diff --git a/elm.json b/elm.json index eae49155..a7147972 100644 --- a/elm.json +++ b/elm.json @@ -17,6 +17,7 @@ ], "elm-version": "0.19.0 <= v < 0.20.0", "dependencies": { + "elm/browser": "1.0.2 <= v < 2.0.0", "elm/bytes": "1.0.8 <= v < 2.0.0", "elm/core": "1.0.0 <= v < 2.0.0", "elm/html": "1.0.0 <= v < 2.0.0", diff --git a/src/Elm/Kernel/Test.js b/src/Elm/Kernel/Test.js index 1ef03633..1d791e17 100644 --- a/src/Elm/Kernel/Test.js +++ b/src/Elm/Kernel/Test.js @@ -16,3 +16,5 @@ function _Test_runThunk(thunk) return __Result_Err(err.toString()); } } + +function _Test_navigationKey() {} diff --git a/src/Test.elm b/src/Test.elm index cf0dd763..b1a358c7 100644 --- a/src/Test.elm +++ b/src/Test.elm @@ -1,13 +1,13 @@ module Test exposing - ( Test, test + ( Test, test, testWithKey , describe, concat, todo, skip, only - , fuzz, fuzz2, fuzz3, fuzzWith, FuzzOptions + , fuzz, fuzz2, fuzz3, fuzzWithKey, fuzzWith, FuzzOptions , Distribution, noDistribution, reportDistribution, expectDistribution ) {-| A module containing functions for creating and managing tests. -@docs Test, test +@docs Test, test, testWithKey ## Organizing Tests @@ -17,11 +17,13 @@ module Test exposing ## Fuzz Testing -@docs fuzz, fuzz2, fuzz3, fuzzWith, FuzzOptions +@docs fuzz, fuzz2, fuzz3, fuzzWithKey, fuzzWith, FuzzOptions @docs Distribution, noDistribution, reportDistribution, expectDistribution -} +import Browser.Navigation +import Elm.Kernel.Test import Expect exposing (Expectation) import Fuzz exposing (Fuzzer) import Set @@ -59,6 +61,7 @@ concat tests = case Internal.duplicatedName tests of Err dups -> let + dupDescription : String -> String dupDescription duped = "A test group contains multiple tests named '" ++ duped ++ "'. Do some renaming so that tests have unique names." in @@ -98,6 +101,7 @@ mistake or are creating a placeholder. describe : String -> List Test -> Test describe untrimmedDesc tests = let + desc : String desc = String.trim untrimmedDesc in @@ -117,6 +121,7 @@ describe untrimmedDesc tests = case Internal.duplicatedName tests of Err dups -> let + dupDescription : String -> String dupDescription duped = "Contains multiple tests named '" ++ duped ++ "'. Let's rename them so we know which is which." in @@ -154,6 +159,7 @@ describe untrimmedDesc tests = test : String -> (() -> Expectation) -> Test test untrimmedDesc thunk = let + desc : String desc = String.trim untrimmedDesc in @@ -164,6 +170,43 @@ test untrimmedDesc thunk = Internal.ElmTestVariant__Labeled desc (Internal.ElmTestVariant__UnitTest (\() -> [ thunk () ])) +{-| Return a [`Test`](#Test) that provides a [`Browser.Navigation.Key`](https://package.elm-lang.org/packages/elm/browser/latest/Browser-Navigation#Key) +that evaluates a single [`Expectation`](../Expect#Expectation). + +You might need such a key if you're testing functions where a key is contained in the arguments. +This might be the case when using [`Browser.application`](https://package.elm-lang.org/packages/elm/browser/latest/Browser#application) +and storing the key in the `Model`. +If you do not need the key, use [`test`](#test) instead. + + import Test exposing (test) + import Expect + + + test "functionToTest returns 0 when given 0" <| + \key -> + functionToTest key 0 + |> Expect.equal 0 + +-} +testWithKey : String -> (Browser.Navigation.Key -> Expectation) -> Test +testWithKey untrimmedDesc thunk = + let + desc : String + desc = + String.trim untrimmedDesc + in + if String.isEmpty desc then + Internal.blankDescriptionFailure + + else + Internal.ElmTestVariant__Labeled desc (Internal.ElmTestVariant__UnitTest (\() -> [ thunk testNavigationKey ])) + + +testNavigationKey : Browser.Navigation.Key +testNavigationKey = + Elm.Kernel.Test.navigationKey + + {-| Returns a [`Test`](#Test) that is "TODO" (not yet implemented). These tests always fail, but test runners will only include them in their output if there are no other failures. @@ -416,6 +459,27 @@ fuzz = Test.Fuzz.fuzzTest Test.Distribution.Internal.NoDistributionNeeded +{-| Run a [fuzz test](#fuzz) using a [`Browser.Navigation.Key`](https://package.elm-lang.org/packages/elm/browser/latest/Browser-Navigation#Key) and a random input. + +You might need such a key if you're testing functions where a key is contained in the arguments. +This might be the case when using [`Browser.application`](https://package.elm-lang.org/packages/elm/browser/latest/Browser#application) +and storing the key in the `Model`. +If you do not need the key, use [`fuzz`](#fuzz) instead. + +-} +fuzzWithKey : + Fuzzer a + -> String + -> (Browser.Navigation.Key -> a -> Expectation) + -> Test +fuzzWithKey fuzzer untrimmedDesc getExpectation = + Test.Fuzz.fuzzTest + Test.Distribution.Internal.NoDistributionNeeded + fuzzer + untrimmedDesc + (getExpectation testNavigationKey) + + {-| Run a [fuzz test](#fuzz) using two random inputs. This is a convenience function that lets you skip calling [`Fuzz.pair`](Fuzz#pair). @@ -440,6 +504,7 @@ fuzz2 : -> Test fuzz2 fuzzA fuzzB desc = let + fuzzer : Fuzzer ( a, b ) fuzzer = Fuzz.pair fuzzA fuzzB in @@ -460,6 +525,7 @@ fuzz3 : -> Test fuzz3 fuzzA fuzzB fuzzC desc = let + fuzzer : Fuzzer ( a, b, c ) fuzzer = Fuzz.triple fuzzA fuzzB fuzzC in diff --git a/tests/src/BrowserTests.elm b/tests/src/BrowserTests.elm new file mode 100644 index 00000000..4d7e1f73 --- /dev/null +++ b/tests/src/BrowserTests.elm @@ -0,0 +1,52 @@ +module BrowserTests exposing (all) + +import Browser.Navigation +import Expect +import Fuzz +import Test exposing (Test, describe) + + +all : Test +all = + Test.concat + [ testWithKey + , fuzzWithKey + ] + + +testWithKey : Test +testWithKey = + Test.testWithKey "Test.testWithKey: storing, using or comparing the key should not have any noticeable effect" <| + \navKey -> + let + init : { navKey : Browser.Navigation.Key } + init = + { navKey = navKey } + in + ( init, cmdsUsingKey navKey ) + |> Tuple.first + |> Expect.equal { navKey = navKey } + + +fuzzWithKey : Test +fuzzWithKey = + Test.fuzzWithKey Fuzz.int "Test.fuzzWithKey: storing, using or comparing the key should not have any noticeable effect" <| + \navKey number -> + let + init : { navKey : Browser.Navigation.Key, number : Int } + init = + { navKey = navKey, number = number } + in + ( init, cmdsUsingKey navKey ) + |> Tuple.first + |> Expect.equal { navKey = navKey, number = number } + + +cmdsUsingKey : Browser.Navigation.Key -> Cmd msg +cmdsUsingKey navKey = + Cmd.batch + [ Browser.Navigation.pushUrl navKey "some-url" + , Browser.Navigation.replaceUrl navKey "some-url" + , Browser.Navigation.back navKey 1 + , Browser.Navigation.forward navKey 1 + ] diff --git a/tests/src/RunnerTests.elm b/tests/src/RunnerTests.elm index 6f66cf58..ce55b659 100644 --- a/tests/src/RunnerTests.elm +++ b/tests/src/RunnerTests.elm @@ -22,7 +22,7 @@ toSeededRunners = fromTest : Test fromTest = - describe "TestRunner.fromTest" + describe "Test.Runner.fromTest" [ describe "test length" [ fuzz2 int int "only positive tests runs are valid" <| \runs intSeed -> diff --git a/tests/src/Tests.elm b/tests/src/Tests.elm index 931565c2..cdac78c8 100644 --- a/tests/src/Tests.elm +++ b/tests/src/Tests.elm @@ -1,5 +1,6 @@ module Tests exposing (all) +import BrowserTests import Expect import FloatWithinTests exposing (floatWithinTests) import Fuzz exposing (..) @@ -28,6 +29,7 @@ all = , fuzzerTests , floatWithinTests , RunnerTests.all + , BrowserTests.all , elmHtmlTests , shrinkingChallenges