@@ -5,6 +5,8 @@ module ICU.CharSpec
55 ) where
66
77import Control.Applicative (Alternative (.. ))
8+ import Data.Bits (Bits (.. ))
9+ import qualified Data.Char as Char
810import Data.Foldable (traverse_ )
911import Data.Version (showVersion , versionBranch )
1012import Numeric (showHex )
@@ -35,6 +37,12 @@ spec = do
3537 ourUnicodeVersion = versionBranch U. unicodeVersion
3638 theirUnicodeVersion = versionBranch ICU. unicodeVersion
3739 showCodePoint c = (" U+" ++ ) . fmap U. toUpper . showHex (U. ord c)
40+ -- Check if the character is not assigned in exactly one Unicode version.
41+ isUnassigned c = (U. generalCategory c == U. NotAssigned )
42+ `xor` (ICU. toGeneralCategory (ICU. charType c) == Char. NotAssigned )
43+ -- Check if the character has changed its general category
44+ hasDifferentCategory c = fromEnum (U. generalCategory c)
45+ /= fromEnum (ICU. toGeneralCategory (ICU. charType c))
3846
3947 -- There is no feature to display warnings other than `trace`, so
4048 -- hack our own:
@@ -61,8 +69,11 @@ spec = do
6169 | n == nRef = acc
6270 -- Unicode version mismatch: char is not mapped in one of the libs:
6371 -- add warning.
64- | age' > ourUnicodeVersion || age' > theirUnicodeVersion
65- = acc{warnings= c : warnings acc}
72+ | age' > ourUnicodeVersion || age' > theirUnicodeVersion ||
73+ isUnassigned c
74+ = acc{warnings= (c, Unassigned ) : warnings acc}
75+ | hasDifferentCategory c
76+ = acc{warnings= (c, CategoryChange ) : warnings acc}
6677 -- Error
6778 | otherwise =
6879 let ! msg = mconcat
@@ -75,14 +86,18 @@ spec = do
7586 ! nRef = fRef c
7687 age = ICU. charAge c
7788 age' = take 3 (versionBranch age)
78- mkWarning c = it (showCodePoint c " " ) . pendingWith $ mconcat
89+ mkWarning (c, reason) = it (showCodePoint c " " ) . pendingWith $ mconcat
7990 [ " Incompatible ICU Unicode version: expected "
8091 , showVersion U. unicodeVersion
8192 , " , got: "
8293 , showVersion ICU. unicodeVersion
83- , " (ICU character age is: "
84- , showVersion (ICU. charAge c)
85- , " )" ]
94+ , case reason of
95+ Unassigned -> mconcat
96+ [ " (ICU character age is: "
97+ , showVersion (ICU. charAge c)
98+ , " )" ]
99+ CategoryChange -> " (different general category)"
100+ ]
86101
87102-- | Helper to compare our GeneralCategory to 'Data.Char.GeneralCategory'.
88103data GeneralCategory = forall c . (Show c , Enum c ) => GeneralCategory c
@@ -93,6 +108,12 @@ instance Show GeneralCategory where
93108instance Eq GeneralCategory where
94109 GeneralCategory a == GeneralCategory b = fromEnum a == fromEnum b
95110
111+ data MismatchReason
112+ = Unassigned
113+ | CategoryChange
114+
96115-- | Warning accumulator
97- data Acc = Acc { warnings :: ! [Char ], firstError :: ! (Maybe String ) }
116+ data Acc = Acc
117+ { warnings :: ! [(Char , MismatchReason )]
118+ , firstError :: ! (Maybe String ) }
98119
0 commit comments