ordinal 0.4.0.0 → 0.4.0.2
raw patch · 5 files changed
+61/−8 lines, 5 filesdep ~QuickCheckPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
Dependency ranges changed: QuickCheck
API changes (from Hackage documentation)
+ Text.Numerals.Algorithm: instance Test.QuickCheck.Arbitrary.Arbitrary Text.Numerals.Algorithm.HighNumberAlgorithm
+ Text.Numerals.Class: instance Test.QuickCheck.Arbitrary.Arbitrary Text.Numerals.Class.ClockSegment
+ Text.Numerals.Class: instance Test.QuickCheck.Arbitrary.Arbitrary Text.Numerals.Class.DayPart
+ Text.Numerals.Class: instance Test.QuickCheck.Arbitrary.Arbitrary Text.Numerals.Class.DaySegment
+ Text.Numerals.Class: instance Test.QuickCheck.Arbitrary.Arbitrary Text.Numerals.Class.NumberType
+ Text.Numerals.Class: instance Test.QuickCheck.Arbitrary.Arbitrary i => Test.QuickCheck.Arbitrary.Arbitrary (Text.Numerals.Class.NumberSegment i)
+ Text.Numerals.Class: instance Test.QuickCheck.Arbitrary.Arbitrary1 Text.Numerals.Class.NumberSegment
Files
- README.md +4/−2
- ordinal.cabal +3/−2
- src/Text/Numerals/Algorithm.hs +9/−1
- src/Text/Numerals/Class.hs +31/−2
- src/Text/Numerals/Internal.hs +14/−1
README.md view
@@ -1,6 +1,6 @@ # ordinal -[](https://travis-ci.com/hapytex/ordinal)+[](https://github.com/hapytex/ordinal/actions/workflows/build-ci.yml) [](https://matrix.hackage.haskell.org/#/package/ordinal) [](https://hackage.haskell.org/package/ordinal) @@ -88,7 +88,9 @@ include a new language. This includes a list of tasks to do in order to add the language. The `test/` directory contains a `test/Text/Numerals/Languages/LanguageSpec.hs.template` file to test the new language. In these templates, one needs to fill in the-`???` parts.+`???` parts. One can make use of the `new-language.sh` script to automatically+copy the templates and open the editor to add the language. In that case the name+of the language is passed as first parameter. Normally the languages are tested for all numbers in the 0-200 range, and the first hundred Fibonacci numbers greater than 200, so:
ordinal.cabal view
@@ -1,5 +1,5 @@ name: ordinal-version: 0.4.0.0+version: 0.4.0.2 synopsis: Convert numbers to words in different languages. description: A package based on Python's num2words package that converts numbers@@ -40,6 +40,7 @@ base >= 4.7 && < 5 , containers >=0.5 , data-default >=0.2+ , QuickCheck >=2.8 , regex >=1.0 , text >= 0.1 , time >=1.0@@ -61,7 +62,7 @@ base , ordinal , hspec ==2.*- , QuickCheck >=2.13 && <2.14+ , QuickCheck >=2.8 , text >= 0.1 build-tool-depends: hspec-discover:hspec-discover == 2.* default-language: Haskell2010
src/Text/Numerals/Algorithm.hs view
@@ -34,6 +34,9 @@ import Data.Vector(Vector, (!), (!?), fromList) import qualified Data.Vector as V +import Test.QuickCheck(oneof)+import Test.QuickCheck.Arbitrary(Arbitrary(arbitrary, shrink))+ import Text.Numerals.Class( NumToWord(toCardinal, toOrdinal, toShortOrdinal, toTimeText') , FreeMergerFunction, FreeNumberToWords, FreeValueSplitter@@ -43,7 +46,7 @@ , ClockText , toClockSegment, toDaySegment )-import Text.Numerals.Internal(_thousand, _iLogFloor)+import Text.Numerals.Internal(_genText, _shrinkText, _thousand, _iLogFloor) import Text.Numerals.Prefix(latinPrefixes) -- | A data type for algorithmic number to word conversions. Most western@@ -86,6 +89,11 @@ = ShortScale Text | LongScale Text Text deriving (Eq, Ord, Read, Show)++instance Arbitrary HighNumberAlgorithm where+ arbitrary = oneof [ShortScale <$> _genText, LongScale <$> _genText <*> _genText]+ shrink (ShortScale t) = ShortScale <$> _shrinkText t+ shrink (LongScale ta tb) = ((`LongScale` tb) <$> _shrinkText ta) <> (LongScale ta <$> _shrinkText tb) instance Default HighNumberAlgorithm where def = ShortScale "illion"
src/Text/Numerals/Class.hs view
@@ -39,6 +39,11 @@ import Data.Time.Clock(getCurrentTime, utctDayTime) import Data.Time.LocalTime(TimeOfDay(TimeOfDay), TimeZone, timeToTimeOfDay, utcToLocalTimeOfDay) +import Test.QuickCheck(choose)+import Test.QuickCheck.Arbitrary(Arbitrary(arbitrary, shrink), Arbitrary1(liftArbitrary), arbitrary1, arbitraryBoundedEnum)++import Text.Numerals.Internal(_genText, _shrinkText)+ -- | A type alias for a function that maps a number to a 'Text' object. type NumberToWords i = i -> Text @@ -76,6 +81,19 @@ , segmentRemainder :: MNumberSegment i -- ^ The optional remainder part. 'Nothing' if the remainder is equal to zero. } deriving (Foldable, Functor, Eq, Ord, Read, Show) +instance Arbitrary1 NumberSegment where+ liftArbitrary gen = go+ where go = NumberSegment <$> liftArbitrary go <*> gen <*> _genText <*> liftArbitrary go++instance Arbitrary i => Arbitrary (NumberSegment i) where+ arbitrary = arbitrary1+ shrink (NumberSegment dv val txt rm) =+ ((\x -> NumberSegment x val txt rm) <$> shrink dv) <>+ ((\x -> NumberSegment dv x txt rm) <$> shrink val) <>+ ((\x -> NumberSegment dv val x rm) <$> _shrinkText txt) <>+ (NumberSegment dv val txt <$> shrink rm)++ -- | A 'Maybe' variant of the 'NumberSegment' data type. This is used since the -- division part can be one, or the remainder part can be zero. type MNumberSegment i = Maybe (NumberSegment i)@@ -88,6 +106,9 @@ | ShortOrdinal -- ^ /Short ordinal/ numbers like 1st, 2nd, 3rd, etc. deriving (Bounded, Enum, Eq, Ord, Read, Show) +instance Arbitrary NumberType where+ arbitrary = arbitraryBoundedEnum+ -- | The type of a function that converts time to its description. The first -- two parameters are used to make conversion more convenient. type ClockText@@ -109,6 +130,9 @@ | To Int -- ^ The parameter is the number of minutes to the next hour, this is between @1@ and @14@. deriving (Eq, Ord, Read, Show) +instance Arbitrary ClockSegment where+ arbitrary = toClockSegment <$> choose (0, 59)+ -- | A data type that describes the state of the hours within a day. data DayPart = Night -- ^ It is night, this means that it is between @0:00@ and @5:59@.@@ -117,6 +141,9 @@ | Evening -- ^ It is evening, this means it is between @18:00@ and @23:59@. deriving (Bounded, Enum, Eq, Ord, Read, Show) +instance Arbitrary DayPart where+ arbitrary = arbitraryBoundedEnum+ -- | A data type that describes the part of the day, and the number of hours on -- a 12-hour clock. data DaySegment@@ -126,6 +153,8 @@ } deriving (Eq, Ord, Read, Show) +instance Arbitrary DaySegment where+ arbitrary = toDaySegment <$> choose (0, 23) -- | Convert the given number of minutes to the corresponding 'ClockSegment'. toClockSegment@@ -205,14 +234,14 @@ toWords Cardinal = toCardinal toWords Ordinal = toOrdinal toWords ShortOrdinal = toShortOrdinal- + -- | Convert the given time of the day to text describing that time. toTimeText :: a -- ^ The conversion algorithm to transform numbers into words. -> TimeOfDay -- ^ The time of the day to convert to words. -> Text -- ^ The time as /text/. toTimeText gen (TimeOfDay h m _) = toTimeText' gen h m- + -- | Convert the given hours and minutes to text that describes the time. toTimeText' :: a -- ^ The conversion algorithm to transform numbers into words.
src/Text/Numerals/Internal.hs view
@@ -10,12 +10,19 @@ , _stripLastIf , _showIntegral , _showPositive+ , _genText, _shrinkText ) where +import Control.Applicative(liftA2)+ import Data.Char(intToDigit)-import Data.Text(Text, cons, dropEnd, isSuffixOf, singleton, pack)+import Data.Text(Text, cons, dropEnd, inits, isSuffixOf, singleton, tails, pack) import qualified Data.Text as T +import Test.QuickCheck(listOf)+import Test.QuickCheck.Arbitrary(Arbitrary(arbitrary))+import Test.QuickCheck.Gen(Gen)+ _pluralize :: a -> a -> Int -> a _pluralize sing plur = go where go 1 = sing@@ -108,3 +115,9 @@ | otherwise = _showPositive q tl where (q, r) = quotRem n 10 tl = intToDigit (fromIntegral r) : s++_genText :: Gen Text+_genText = pack <$> listOf arbitrary++_shrinkText :: Text -> [Text]+_shrinkText = liftA2 (zipWith (<>)) inits (tails . T.drop 1)