Skip to content
37 changes: 36 additions & 1 deletion src/ElmTestRunner/Failure.elm
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Json.Encode as Encode
import Test.Runner.Failure exposing (InvalidReason(..), Reason(..))


{-| Type resulting of calling `Test.Runner.getFailureReason` on a test `Expectation`.
{-| Type resulting of calling the old `Test.Runner.getFailureReason` on a test `Expectation`.
-}
type alias Failure =
{ given : Maybe String
Expand Down Expand Up @@ -50,6 +50,12 @@ encode =
-- }
-- | TODO
-- | Invalid InvalidReason
-- | Multiple
-- (List
-- { description : String
-- , reason : Reason
-- }
-- )
--
-- type InvalidReason
-- = EmptyList
Expand All @@ -61,6 +67,10 @@ encode =
-- | DistributionBug


type alias Record_description_String_reason_Reason_ =
{ description : String, reason : Reason }


type alias Record_expected_String_actual_String_extra_ListString_missing_ListString_ =
{ expected : String, actual : String, extra : List String, missing : List String }

Expand Down Expand Up @@ -147,10 +157,22 @@ decodeReasonHelp constructor =
Invalid
(Decode.field "A1" decodeInvalidReason)

"Multiple" ->
Decode.map
Multiple
(Decode.field "A1" (Decode.list decodeRecord_description_String_reason_Reason_))

other ->
Decode.fail <| "Unknown constructor for type Reason: " ++ other


decodeRecord_description_String_reason_Reason_ =
Decode.map2
Record_description_String_reason_Reason_
(Decode.field "description" Decode.string)
(Decode.field "reason" decodeReason)


decodeRecord_expected_String_actual_String_extra_ListString_missing_ListString_ =
Decode.map4
Record_expected_String_actual_String_extra_ListString_missing_ListString_
Expand Down Expand Up @@ -250,6 +272,19 @@ encodeReason a =
, ( "A1", encodeInvalidReason a1 )
]

Multiple a1 ->
Encode.object
[ ( "Constructor", Encode.string "Multiple" )
, ( "A1", Encode.list encodeRecord_description_String_reason_Reason_ a1 )
]


encodeRecord_description_String_reason_Reason_ a =
Encode.object
[ ( "description", Encode.string a.description )
, ( "reason", encodeReason a.reason )
]


encodeRecord_expected_String_actual_String_extra_ListString_missing_ListString_ a =
Encode.object
Expand Down
20 changes: 18 additions & 2 deletions src/ElmTestRunner/Reporter/ConsoleColor.elm
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import ElmTestRunner.Vendor.ConsoleText as Text exposing (Text, UseColor, dark,
import ElmTestRunner.Vendor.FormatColor as FormatColor
import ElmTestRunner.Vendor.FormatMonochrome as FormatMonochrome
import Test.Distribution exposing (DistributionReport)
import Test.Runner exposing (formatLabels)


{-| Provide a console implementation of a reporter, mostly for human consumption.
Expand Down Expand Up @@ -116,10 +115,27 @@ successLabelsToText =
formatLabels (dark << plain << withChar '↓') (green << withChar '✓') >> Text.concat


formatLabels :
(String -> Text)
-> (String -> Text)
-> List String
-> List Text
formatLabels formatDescription formatTest labels =
case labels of
[] ->
[]

test :: descriptions ->
List.foldl
(\x acc -> formatDescription x :: acc)
[ formatTest test ]
descriptions


distributionReportToString : DistributionReport -> Maybe String
distributionReportToString distributionReport =
case distributionReport of
Test.Distribution.NoDistribution ->
Test.Distribution.NoDistribution () ->
Nothing

Test.Distribution.DistributionToReport r ->
Expand Down
9 changes: 8 additions & 1 deletion src/ElmTestRunner/Reporter/Json.elm
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,18 @@ encodeReason description reason =
|> Encode.object
|> encodeReasonType "CollectionDiff"

Multiple _ ->
-- elm-test-runner does not support showing the `reason` for `Expect.oneOf`.
-- Also, when this was added, this avoided downstream consumers of this JSON
-- choking on a new variant.
Encode.string description
|> encodeSumType "Custom"


encodeDistributionReport : DistributionReport -> Encode.Value
encodeDistributionReport distributionReport =
case distributionReport of
NoDistribution ->
NoDistribution () ->
Encode.null
|> encodeSumType "NoDistribution"

Expand Down
6 changes: 5 additions & 1 deletion src/ElmTestRunner/Reporter/Junit.elm
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ classAndName labels =
distributionReportToString : DistributionReport -> Maybe String
distributionReportToString distributionReport =
case distributionReport of
Test.Distribution.NoDistribution ->
Test.Distribution.NoDistribution () ->
Nothing

Test.Distribution.DistributionToReport r ->
Expand Down Expand Up @@ -271,3 +271,7 @@ reasonToString description reason =
++ String.join "\n" extra
++ "\n\nthese were missing:\n\n"
++ String.join "\n" missing

Multiple _ ->
-- elm-test-runner does not support showing the `reason` for `Expect.oneOf`.
description
81 changes: 4 additions & 77 deletions src/ElmTestRunner/Result.elm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module ElmTestRunner.Result exposing
( TestResult(..), fromExpectations, setDuration, setLogs, encode, decoder
( TestResult(..), setDuration, setLogs, encode, decoder
, Summary, summary
)

Expand All @@ -8,7 +8,7 @@ module ElmTestRunner.Result exposing

# Manipulation of the result of a test run

@docs TestResult, fromExpectations, setDuration, setLogs, encode, decoder
@docs TestResult, setDuration, setLogs, encode, decoder


# Helper functions
Expand All @@ -20,11 +20,9 @@ module ElmTestRunner.Result exposing
import Array exposing (Array)
import Dict exposing (Dict)
import ElmTestRunner.Failure as Failure exposing (Failure)
import Expect exposing (Expectation)
import Json.Decode as Decode exposing (Decoder, Value)
import Json.Encode as Encode
import Test.Distribution exposing (DistributionReport(..))
import Test.Runner


{-| Type summarizing the results of a test run.
Expand Down Expand Up @@ -95,77 +93,6 @@ setLogs logs testResult =
}


{-| Convert a list of expectations (results of a run) into a `TestResult`.
Return the `Failed` variant if there is any todo or failure in the expectations.
-}
fromExpectations : List String -> List Expectation -> TestResult
fromExpectations labels expectations =
let
outcomes : Outcomes
outcomes =
getOutcomes expectations
in
if List.isEmpty outcomes.todos && List.isEmpty outcomes.failures then
Passed
{ labels = labels
, duration = 0
, logs = []
, distributionReports = outcomes.distributionReports
}

else
Failed
{ labels = labels
, duration = 0
, logs = []
, todos = outcomes.todos
, failures = outcomes.failures
, distributionReports = outcomes.distributionReports
}


type alias Outcomes =
{ todos : List String
, failures : List Failure
, distributionReports : List DistributionReport
}


initOutcomes : Outcomes
initOutcomes =
{ todos = []
, failures = []
, distributionReports = []
}


getOutcomes : List Expectation -> Outcomes
getOutcomes expectations =
List.foldl accumOutcomes initOutcomes expectations


accumOutcomes : Expectation -> Outcomes -> Outcomes
accumOutcomes expectation outcomes =
let
distributionReport : DistributionReport
distributionReport =
Test.Runner.getDistributionReport expectation
in
case Test.Runner.getFailureReason expectation of
Nothing ->
{ outcomes | distributionReports = distributionReport :: outcomes.distributionReports }

Just failure ->
if Test.Runner.isTodo expectation then
{ outcomes | todos = failure.description :: outcomes.todos }

else
{ outcomes
| failures = failure :: outcomes.failures
, distributionReports = distributionReport :: outcomes.distributionReports
}


{-| Encode a `TestResult`.
-}
encode : TestResult -> Value
Expand Down Expand Up @@ -270,7 +197,7 @@ decodeDistributionReport =
decodeDistributionReportHelp constructor =
case constructor of
"NoDistribution" ->
Decode.succeed NoDistribution
Decode.succeed (NoDistribution ())

"DistributionToReport" ->
Decode.map
Expand Down Expand Up @@ -373,7 +300,7 @@ decodeTestResultHelp constructor =
encodeDistributionReport : DistributionReport -> Value
encodeDistributionReport a =
case a of
NoDistribution ->
NoDistribution () ->
Encode.object
[ ( "Constructor", Encode.string "NoDistribution" )
]
Expand Down
47 changes: 25 additions & 22 deletions src/ElmTestRunner/Runner.elm
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ module ElmTestRunner.Runner exposing

-}

import Array
import ElmTestRunner.Result as TestResult exposing (TestResult)
import ElmTestRunner.SeededRunners as SeededRunners exposing (SeededRunners, kindToString)
import Json.Encode exposing (Value)
import Platform
import Task
import Test exposing (Test)


Expand Down Expand Up @@ -65,6 +65,7 @@ type alias Model =
type Msg
= AskTestsCount
| ReceiveRunTest Int
| RanTest Int TestResult



Expand Down Expand Up @@ -139,24 +140,26 @@ init maybeConcatenatedTest ports flags =

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case ( msg, model.testRunners ) of
-- AskTestsCount
( AskTestsCount, Ok { kind, runners } ) ->
( model, model.ports.sendTestsCount { kind = kindToString kind, testsCount = Array.length runners } )

( AskTestsCount, Err err ) ->
( model, model.ports.sendTestsCount { kind = "Invalid" ++ err, testsCount = 0 } )

-- ReceiveRunTest
( ReceiveRunTest id, Ok { runners } ) ->
( model, sendTestResult model.ports id (SeededRunners.run id runners) )

( ReceiveRunTest _, Err _ ) ->
( model, Debug.todo "There is no test to run, how did we get here?" )


sendTestResult : Ports msg -> Int -> Maybe TestResult -> Cmd msg
sendTestResult ports id maybeResult =
Maybe.map TestResult.encode maybeResult
|> Maybe.map (\res -> ports.sendResult { id = id, result = res })
|> Maybe.withDefault Cmd.none
case msg of
AskTestsCount ->
( model
, model.ports.sendTestsCount
{ kind = kindToString (SeededRunners.getKind model.testRunners)
, testsCount = SeededRunners.getTestsCount model.testRunners
}
)

ReceiveRunTest id ->
( model
, case SeededRunners.run id model.testRunners of
Just task ->
Task.perform (RanTest id) task

Nothing ->
Cmd.none
)

RanTest id testResult ->
( model
, model.ports.sendResult { id = id, result = TestResult.encode testResult }
)
Loading