@@ -11,7 +11,7 @@ module Tests.Properties
11import Control.Applicative ((<$>), (<*>))
11import Control.Applicative ((<$>), (<*>))
12import Control.Arrow ((***), second)
12import Control.Arrow ((***), second)
13import Data.Bits ((.&.))
13import Data.Bits ((.&.))
14−import Data.Char (chr, isDigit, isHexDigit, isLower, isSpace, isUpper, ord)
14+import Data.Char (chr, isDigit, isHexDigit, isLower, isSpace, isLetter, isUpper, ord)
15import Data.Int (Int8, Int16, Int32, Int64)
15import Data.Int (Int8, Int16, Int32, Int64)
16import Data.Monoid (Monoid(..))
16import Data.Monoid (Monoid(..))
17import Data.String (IsString(fromString))
17import Data.String (IsString(fromString))
@@ -23,6 +23,7 @@ import Data.Text.Internal.Search (indices)
23import Data.Text.Lazy.Read as TL
23import Data.Text.Lazy.Read as TL
24import Data.Text.Read as T
24import Data.Text.Read as T
25import Data.Word (Word, Word8, Word16, Word32, Word64)
25import Data.Word (Word, Word8, Word16, Word32, Word64)
26+import Data.Maybe (mapMaybe)
26import Numeric (showEFloat, showFFloat, showGFloat, showHex)
27import Numeric (showEFloat, showFFloat, showGFloat, showHex)
27import Prelude hiding (replicate)
28import Prelude hiding (replicate)
28import Test.Framework (Test, testGroup)
29import Test.Framework (Test, testGroup)
@@ -326,6 +327,14 @@ t_toUpper_upper t = p (T.toUpper t) >= p t
326 where p = T.length . T.filter isUpper
327 where p = T.length . T.filter isUpper
327tl_toUpper_upper t = p (TL.toUpper t) >= p t
328tl_toUpper_upper t = p (TL.toUpper t) >= p t
328 where p = TL.length . TL.filter isUpper
329 where p = TL.length . TL.filter isUpper
330+t_toTitle_title t = all (<= 1) (caps t)
331+ where caps = fmap (T.length . T.filter isUpper) . T.words . T.toTitle
332+t_toTitle_1stNotLower = and . notLow . T.toTitle . T.filter stable
333+ where notLow = mapMaybe (fmap (not . isLower) . (T.find isLetter)) . T.words
334+ -- Surprise! The Spanish/Portuguese ordinal indicators changed
335+ -- from category Ll (letter, lowercase) to Lo (letter, other)
337+ stable c = c /= '\170' && c /= '\186'
330justifyLeft k c xs = xs ++ L.replicate (k - length xs) c
339justifyLeft k c xs = xs ++ L.replicate (k - length xs) c
331justifyRight m n xs = L.replicate (m - length xs) n ++ xs
340justifyRight m n xs = L.replicate (m - length xs) n ++ xs
@@ -1030,7 +1039,9 @@ tests =
1030 testProperty "tl_toLower_lower" tl_toLower_lower,
1039 testProperty "tl_toLower_lower" tl_toLower_lower,
1031 testProperty "t_toUpper_length" t_toUpper_length,
1040 testProperty "t_toUpper_length" t_toUpper_length,
1032 testProperty "t_toUpper_upper" t_toUpper_upper,
1041 testProperty "t_toUpper_upper" t_toUpper_upper,
1033− testProperty "tl_toUpper_upper" tl_toUpper_upper
1042+ testProperty "tl_toUpper_upper" tl_toUpper_upper,
1043+ testProperty "t_toTitle_title" t_toTitle_title,
1044+ testProperty "t_toTitle_1stNotLower" t_toTitle_1stNotLower
1036 testGroup "justification" [
1047 testGroup "justification" [