elmelm-test

Executing elm-test throws runtime exception: Cannot read property 'href' of undefined


The following test results in a runtime exception:

test "search yields profile" <|
\_ ->
    let
        -- Setup
        location =
            Navigation.Location "" "" "" "" "" "" "" "" "" "" ""

        ( model, _ ) =
            Home.init location

        -- Test
        ( newState, _ ) =
            model |> Home.update (Search "Scott")

        -- Verify
        ( onlyOne, isContentProvider1 ) =
            ( (newState.contentProviders |> List.length) == 1
            , newState.contentProviders |> List.member contentProvider1
            )
    in
        Expect.equal (onlyOne && isContentProvider1) True
TypeError: Cannot read property 'href' of undefined
    at Object.getLocation (eval at <anonymous> (my_path\AppData\Roaming\npm\node_modules\elm-test\lib\runner.js:84:37),
<anonymous>:1392 6:17)
    at Function.eval (eval at <anonymous> (my_path\AppData\Roaming\npm\node_modules\elm-test\lib\runner.js:84:37),
<anonymous>:14127:43)
    at A2 (eval at <anonymous> (my_path\AppData\Roaming\npm\node_modules\elm-test\lib\runner.js:84:37),
<anonymous>:92:11)
    at eval (eval at <anonymous> (my_path\AppData\Roaming\npm\node_modules\elm-test\lib\runner.js:84:37),
<anonymous>:21270:31)
    at eval (eval at <anonymous> (my_path\AppData\Roaming\npm\node_modules\elm-test\lib\runner.js:84:37),
<anonymous>:22757:4)
    at my_path\AppData\Roaming\npm\node_modules\elm-test\lib\runner.js:84:32
    at Object.evalElmCode (my_path\AppData\Roaming\npm\node_modules\elm-test\lib\runner.js:84:76)
    at my_path\AppData\Roaming\npm\node_modules\elm-test\bin\elm-test:196:14
    at my_path\AppData\Roaming\npm\node_modules\elm-test\node_modules\graceful-fs\graceful-fs.js:78:16
    at tryToString (fs.js:456:3)

My hunch is that the Navigaton.Location is behind the exception. However, I have no clue how to resolve the issue.

The source code can be found on GitHub.


Solution

  • I don't know if you've found an answer to this on Elm Slack, but I've spent some time looking into this and have found the cause of the problem.

    In short, the problem is including your call to Navigation.program in an Elm file that gets run using elm-test. In your case, Navigation.program is in Home.elm. Move it to a different module (or temporarily comment it out) and your tests should run.

    In more detail, the native code behind Navigation.program gets document.location and passes that into your init function. However, when running elm-test, you don't have a document object as there isn't a browser. elm-test will make up a skeletal document object instead, but this object has no location property and hence an exception is thrown attempting to get location.href.

    There is some guidance to this effect in the elm-test package documentation (point 1 under 'Application-specific techniques'):

    Avoid importing your Main module. Most of your code belongs in other modules, so import those instead.


    Alternatively, document.location has now been polyfilled in elm-test version 0.18.9, so upgrading to that version will also fix this problem.