packages feed

fluent-icu-1.0.0: test/BuiltinSpec.hs

module BuiltinSpec (spec) where

import Data.Time (UTCTime (..), fromGregorian, secondsToDiffTime)
import Prelude

spec :: Spec
spec = do
    describe "NUMBER" do
        it "formats a number by the given options" $
            written [fluent|foo = { NUMBER($arg, minimumFractionDigits: 2) }|] `shouldBe` Right "3.00"
        it "limits the significant digits it is given" $
            written [fluent|foo = { NUMBER($arg, maximumSignificantDigits: 2) }|] `shouldBe` Right "3"
        it "omits the grouping separators when turned off" $
            translate
                "foo"
                [("arg", number 1234567)]
                [fluent|foo = { NUMBER($arg, useGrouping: "false") }|]
                `shouldBe` Right "1234567"
        it "selects by the plural category of the number" $
            written
                [fluent|
                foo = { NUMBER($arg, minimumFractionDigits: 1) ->
                    [one] one
                   *[other] other
                }
                |]
                `shouldBe` Right "other"
        it "formats an amount of a unit" $
            written [fluent|foo = { NUMBER($arg, unit: "kilometre-per-hour") }|] `shouldBe` Right "3 km/h"
        it "spells the unit's name in full, not its symbol" $
            written
                [fluent|foo = { NUMBER($arg, unit: "litre", unitDisplay: "long") }|]
                `shouldBe` Right "3 litres"
        it "rejects a unit it does not know" $
            written [fluent|foo = { NUMBER($arg, unit: "banana") }|]
                `shouldBe` Left "NUMBER: U_NUMBER_SKELETON_SYNTAX_ERROR"
        it "rejects a style it does not know" $
            written [fluent|foo = { NUMBER($arg, style: "banana") }|]
                `shouldBe` Left "NUMBER: no such style: banana"
    describe "DATETIME" do
        it "formats a time by the given options" $
            when' [fluent|foo = { DATETIME($arg, month: "long", year: "numeric", day: "numeric") }|]
                `shouldBe` Right "10 August 2026"
        it "formats only the field it is given" $
            when' [fluent|foo = { DATETIME($arg, weekday: "long") }|] `shouldBe` Right "Monday"
        it "shifts the time by the zone it is given" $
            when'
                [fluent|foo = { DATETIME($arg, hour: "numeric", minute: "2-digit", timeZone: "Europe/Berlin") }|]
                `shouldBe` Right "14:34"
        it "defaults to a date of numbers when given no options" $
            when' [fluent|foo = { DATETIME($arg) }|] `shouldBe` Right "10/08/2026"
        it "rejects a word for a field of digits" $
            when' [fluent|foo = { DATETIME($arg, year: "long") }|]
                `shouldBe` Left "DATETIME: expected one of numeric, 2-digit for year, but got long"
        it "rejects digits for a field of words" $
            when' [fluent|foo = { DATETIME($arg, weekday: "2-digit") }|]
                `shouldBe` Left "DATETIME: expected one of narrow, short, long for weekday, but got 2-digit"
        it "formats the month in words or in digits" $ do
            when' [fluent|foo = { DATETIME($arg, month: "long") }|] `shouldBe` Right "August"
            when' [fluent|foo = { DATETIME($arg, month: "2-digit") }|] `shouldBe` Right "08"
        it "rejects a month it does not know" $
            when' [fluent|foo = { DATETIME($arg, month: "medium") }|]
                `shouldBe` Left "DATETIME: no such month: medium"
        it "rejects a positional argument that is not a time" $
            written [fluent|foo = { DATETIME($arg) }|]
                `shouldBe` Left "DATETIME: the positional argument is not a time"

written :: Resource -> Either String Text
written = translate "foo" [("arg", number 3)]

when' :: Resource -> Either String Text
when' = translate "foo" [("arg", value afternoon)]

-- | 2026-08-10, a Monday, 12:34:56 UTC.
afternoon :: UTCTime
afternoon = UTCTime (fromGregorian 2026 8 10) . secondsToDiffTime $ 12 * 3600 + 34 * 60 + 56