diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0b3ca67..c842755 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,8 @@ jobs: - name: Set up PureScript toolchain uses: purescript-contrib/setup-purescript@main + with: + purescript: "0.14.0-rc3" - name: Cache PureScript dependencies uses: actions/cache@v2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 3db9d6b..f64c3b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ New features: Bugfixes: Other improvements: +- Changed test library from `spec` to `assert` ## [v4.0.1](https://github.com/purescript-contrib/purescript-formatters/releases/tag/v4.0.1) - 2019-02-09 diff --git a/packages.dhall b/packages.dhall index b5baf39..9c3ee6f 100644 --- a/packages.dhall +++ b/packages.dhall @@ -1,4 +1,4 @@ let upstream = - https://github.com/purescript/package-sets/releases/download/psc-0.13.8-20200922/packages.dhall sha256:5edc9af74593eab8834d7e324e5868a3d258bbab75c5531d2eb770d4324a2900 + https://raw.githubusercontent.com/purescript/package-sets/prepare-0.14/src/packages.dhall in upstream diff --git a/spago.dhall b/spago.dhall index 96f0667..00dcc81 100644 --- a/spago.dhall +++ b/spago.dhall @@ -1,16 +1,17 @@ { name = "formatters" , dependencies = [ "aff" + , "assert" , "console" , "datetime" , "effect" , "fixed-points" , "generics-rep" , "lists" + , "numbers" , "parsing" , "prelude" , "psci-support" - , "spec" , "transformers" ] , packages = ./packages.dhall diff --git a/src/Data/Formatter/Parser/Interval.purs b/src/Data/Formatter/Parser/Interval.purs index ccede26..330c9cd 100644 --- a/src/Data/Formatter/Parser/Interval.purs +++ b/src/Data/Formatter/Parser/Interval.purs @@ -10,7 +10,7 @@ import Prelude import Control.Alt ((<|>)) import Data.DateTime (DateTime) -import Data.Either (Either(..), fromRight) +import Data.Either (Either(..), either) import Data.Foldable (class Foldable, fold, foldMap, intercalate) import Data.Formatter.DateTime (unformatParser, Formatter, parseFormatString) import Data.Formatter.Parser.Number (parseNumber, parseMaybeInteger) @@ -19,7 +19,7 @@ import Data.Interval.Duration.Iso (IsoDuration, mkIsoDuration, prettyError) import Data.Maybe (Maybe) import Data.Traversable (sequence) import Data.Tuple (Tuple(..), snd) -import Partial.Unsafe (unsafePartial) +import Partial.Unsafe (unsafeCrashWith) import Text.Parsing.Parser as P import Text.Parsing.Parser.Combinators as PC import Text.Parsing.Parser.String as PS @@ -77,4 +77,4 @@ parseDateTime = unformatParser extendedDateTimeFormatInUTC extendedDateTimeFormatInUTC ∷ Formatter extendedDateTimeFormatInUTC = parseFormatString "YYYY-MM-DDTHH:mm:ssZ" - # unsafePartial fromRight -- the format must be valid ISO date format + # either unsafeCrashWith identity -- the format must be valid ISO date format diff --git a/src/Data/Formatter/Parser/Number.purs b/src/Data/Formatter/Parser/Number.purs index bbd8867..078a246 100644 --- a/src/Data/Formatter/Parser/Number.purs +++ b/src/Data/Formatter/Parser/Number.purs @@ -15,9 +15,9 @@ import Text.Parsing.Parser as P import Text.Parsing.Parser.Combinators as PC import Data.Formatter.Parser.Utils (oneOfAs) import Text.Parsing.Parser.String as PS -import Data.Maybe (Maybe) +import Data.Maybe (Maybe(..)) +import Data.Number (fromString) import Data.Foldable (foldMap) -import Global (readFloat) parseInteger ∷ ∀ s m. Monad m ⇒ PS.StringLike s ⇒ P.ParserT s m Int parseInteger = some parseDigit <#> foldDigits @@ -26,7 +26,11 @@ parseMaybeInteger ∷ ∀ s m. Monad m ⇒ PS.StringLike s ⇒ P.ParserT s m (Ma parseMaybeInteger = PC.optionMaybe parseInteger parseFractional ∷ ∀ s m. Monad m ⇒ PS.StringLike s ⇒ P.ParserT s m Number -parseFractional = (some parseDigit) <#> (foldMap show >>> ("0." <> _) >>> readFloat) +parseFractional = do + digitStr <- (some parseDigit) <#> (foldMap show >>> ("0." <> _)) + case fromString digitStr of + Just n -> pure n + Nothing -> P.fail ("Not a number: " <> digitStr) parseNumber ∷ ∀ s m. Monad m ⇒ PS.StringLike s ⇒ P.ParserT s m Number parseNumber = (+) diff --git a/test/src/DateTime.purs b/test/src/DateTime.purs index 7bf81c9..643519a 100644 --- a/test/src/DateTime.purs +++ b/test/src/DateTime.purs @@ -2,17 +2,16 @@ module Test.DateTime (datetimeTest) where import Prelude -import Control.Alternative (class Alternative, empty) -import Control.MonadZero (guard) +import Control.Monad.Reader.Class (class MonadReader) +import Control.Alternative (class Alternative, empty, guard) import Data.DateTime (DateTime) import Data.Either (Either(..)) import Data.Formatter.DateTime as FDT import Data.List (fromFoldable) -import Test.Spec (describe, Spec, it) -import Test.Spec.Assertions (shouldEqual) -import Test.Utils (forAll, makeDateTime) +import Effect.Aff.Class (class MonadAff) +import Test.Utils (forAll, makeDateTime, describe, it, shouldEqual) -datetimeTest ∷ Spec Unit +datetimeTest ∷ forall m. MonadReader Int m ⇒ MonadAff m ⇒ m Unit datetimeTest = describe "Data.Formatter.DateTime" do forAll (\a → a.format <> " | " <> a.dateStr) "formatDateTime/unformatDateTime should format/unformat dateTime" diff --git a/test/src/Interval.purs b/test/src/Interval.purs index efe3c9d..bb2f8f8 100644 --- a/test/src/Interval.purs +++ b/test/src/Interval.purs @@ -2,9 +2,11 @@ module Test.Interval (intervalTest) where import Prelude +import Control.Monad.Reader.Class (class MonadReader) import Effect.Aff (Aff) +import Effect.Aff.Class (class MonadAff) import Data.DateTime (DateTime) -import Data.Either (Either(..), fromRight) +import Data.Either (Either(..), either) import Data.Foldable (class Foldable, fold) import Data.Formatter.Interval (unformatInterval, unformatRecurringInterval, formatRecurringInterval) import Data.Formatter.Parser.Interval (parseIsoDuration) @@ -12,15 +14,13 @@ import Data.Formatter.Parser.Utils (runP) import Data.Interval as I import Data.Interval.Duration.Iso (IsoDuration, mkIsoDuration) import Data.Maybe (Maybe(..)) -import Partial.Unsafe (unsafePartial) -import Test.Spec (describe, Spec) -import Test.Spec.Assertions (shouldEqual) -import Test.Utils (forAll, makeDateTime) +import Partial.Unsafe (unsafeCrashWith) +import Test.Utils (forAll, makeDateTime, describe, shouldEqual) -prop ∷ ∀ e f. Foldable f ⇒ String → f {str ∷ String | e} → ({str ∷ String | e} → Aff Unit) → Spec Unit +prop ∷ ∀ m e f. MonadReader Int m ⇒ MonadAff m ⇒ Foldable f ⇒ String → f {str ∷ String | e} → ({str ∷ String | e} → Aff Unit) → m Unit prop = forAll (show <<< _.str) -intervalTest ∷ Spec Unit +intervalTest ∷ forall m. MonadReader Int m ⇒ MonadAff m ⇒ m Unit intervalTest = describe "Data.Formatter.Interval" do prop "shouldn't unformat invalid Interval" invalidIntervals \({str, err}) → do (unformatInterval str) `shouldEqual` (Left $ err) @@ -40,7 +40,8 @@ intervalTest = describe "Data.Formatter.Interval" do unsafeMkToIsoDuration ∷ I.Duration → IsoDuration unsafeMkToIsoDuration d = mkIsoDuration d - # unsafePartial fromRight -- the duration must be valid ISO duration + -- the duration must be valid ISO duration + # either (\_ -> unsafeCrashWith "unsafeMkToIsoDuration failed") identity durations ∷ Array { str∷ String, formatedStr∷ String, dur ∷ IsoDuration } durations = diff --git a/test/src/Main.purs b/test/src/Main.purs index ef5affb..c21fea9 100644 --- a/test/src/Main.purs +++ b/test/src/Main.purs @@ -2,16 +2,15 @@ module Test.Main where import Prelude +import Control.Monad.Reader.Trans (runReaderT) import Effect (Effect) import Effect.Aff (launchAff_) import Test.DateTime (datetimeTest) import Test.Interval (intervalTest) import Test.Number (numberTest) -import Test.Spec.Reporter.Console (consoleReporter) -import Test.Spec.Runner (runSpec) main ∷ Effect Unit -main = launchAff_ $ runSpec [consoleReporter] do +main = launchAff_ $ flip runReaderT 0 do intervalTest datetimeTest numberTest diff --git a/test/src/Number.purs b/test/src/Number.purs index 1a0bac9..00f4b0a 100644 --- a/test/src/Number.purs +++ b/test/src/Number.purs @@ -2,14 +2,14 @@ module Test.Number (numberTest) where import Prelude +import Control.Monad.Reader.Class (class MonadReader) import Data.Formatter.Number (Formatter(..), printFormatter, parseFormatString, format, unformat) import Data.Either (Either(..)) +import Effect.Aff.Class (class MonadAff) -import Test.Spec (describe, Spec) -import Test.Spec.Assertions (shouldEqual) -import Test.Utils (forAll) +import Test.Utils (forAll, describe, shouldEqual) -numberTest ∷ Spec Unit +numberTest ∷ forall m. MonadReader Int m ⇒ MonadAff m ⇒ m Unit numberTest = describe "Data.Formatter.Number" do forAll _.str "should print formatter" diff --git a/test/src/Utils.purs b/test/src/Utils.purs index e25a7c0..6331d9b 100644 --- a/test/src/Utils.purs +++ b/test/src/Utils.purs @@ -2,21 +2,44 @@ module Test.Utils where import Prelude - -import Test.Spec (describe, it, Spec) import Effect.Aff (Aff) +import Control.Monad.Reader.Class (class MonadReader, ask, local) import Data.Foldable (class Foldable, for_) import Data.Enum (toEnum) import Data.Maybe (fromMaybe) +import Data.Monoid (power, guard) import Data.DateTime (DateTime(..)) import Data.Date (canonicalDate) import Data.Time (Time(..)) +import Effect.Console (log) +import Effect.Class (liftEffect) +import Effect.Aff.Class (class MonadAff, liftAff) +import Test.Assert (assertEqual) + +----------------------------------------------------------------- + +-- Provide similar API to purescript-spec to reduce code changes + +describe :: forall m. MonadReader Int m ⇒ MonadAff m ⇒ String -> m Unit -> m Unit +describe msg runTest = do + indentation <- ask + let spacing = guard (indentation > 0) " " + liftEffect $ log $ (power ">>" indentation) <> spacing <> msg + local (_ + 1) runTest + +it :: forall m. MonadReader Int m ⇒ MonadAff m ⇒ String -> m Unit -> m Unit +it = describe + +shouldEqual :: forall m a. MonadAff m ⇒ Eq a ⇒ Show a ⇒ a -> a -> m Unit +shouldEqual actual expected = + liftEffect $ assertEqual { actual, expected } +----------------------------------------------------------------- -forAll ∷ ∀ a f. Foldable f ⇒ (a → String) → String → f a → (a → Aff Unit) → Spec Unit +forAll ∷ ∀ m a f. MonadReader Int m ⇒ MonadAff m ⇒ Foldable f ⇒ (a → String) → String → f a → (a → Aff Unit) → m Unit forAll itTitle title arb f = describe title do - for_ arb \a → it (itTitle a) (f a) + for_ arb \a → it (itTitle a) (liftAff $ f a) makeDateTime ∷ Int → Int → Int → Int → Int → Int → Int → DateTime makeDateTime year month day hour minute second millisecond =