1port module Testable.Runner exposing (TestableProgram, program, show)
7import Dict exposing (Dict)
9import Element.Background as Background
10import Element.Border as Border
11import Element.Font as Font
12import Html exposing (Html)
13import Parser exposing ((|.), (|=))
19import Test.Runner.Failure as Failure
24show : Testable.Element msg -> Html msg
29type alias TestableProgram =
30 Program () (Model Msg) Msg
34 { white = Element.rgb 1 1 1
35 , red = Element.rgb 1 0 0
36 , green = Element.rgb 0 1 0
37 , black = Element.rgb 0 0 0
38 , lightGrey = Element.rgb 0.7 0.7 0.7
42program : List ( String, Testable.Element Msg ) -> TestableProgram
45 ( current, upcoming ) =
51 ( Just cur, remaining )
60 , Task.perform (always Analyze)
68 , subscriptions = subscriptions
72subscriptions : Model Msg -> Sub Msg
75 [ styles RefreshBoundingBox
80 { current : Maybe ( String, Testable.Element msg )
81 , upcoming : List ( String, Testable.Element msg )
82 , finished : List (WithResults (Testable.Element msg))
86type alias WithResults thing =
93 { given : Maybe String
94 , description : String
95 , reason : Failure.Reason
102 List (WithResults (Testable.Element msg))
110 { given : Maybe String
111 , description : String
115prepareResults withResults =
117 prepareNode ( x, maybeResult ) =
119 , case maybeResult of
126 , description = res.description
130 prepare { label, results } =
132 , results = List.map prepareNode results
135 List.map prepare withResults
144 , bbox : Testable.BoundingBox
146 , style : List ( String, String )
151runTest : Dict String Testable.Found -> String -> Testable.Element msg -> WithResults (Testable.Element msg)
152runTest boxes label element =
155 Testable.toTest label boxes element
158 Random.initialSeed 227852860
161 Testable.runTests seed tests
169update : Msg -> Model Msg -> ( Model Msg, Cmd Msg )
175 RefreshBoundingBox boxes ->
176 case model.current of
182 Just ( label, current ) ->
186 , { style = Dict.fromList box.style
188 , isVisible = box.isVisible
198 runTest foundData label current
200 case model.upcoming of
204 , finished = model.finished ++ [ currentResults ]
206 , report (prepareResults (currentResults :: model.finished))
209 newCurrent :: remaining ->
211 | finished = model.finished ++ [ currentResults ]
212 , current = Just newCurrent
213 , upcoming = remaining
215 , Task.perform (always Analyze)
223 case model.current of
229 Just ( label, current ) ->
231 , analyze (Testable.getIds current)
235view : Model Msg -> Browser.Document Msg
237 case model.current of
239 if List.isEmpty model.upcoming then
240 { title = "tests finished"
242 [ case model.finished of
248 , Element.width (Element.px 800)
250 -- , Background.color Color.grey
254 finished :: remaining ->
256 viewResultsInline finished
263 , Element.width (Element.px 800)
265 (List.map viewResult (finished :: remaining))
270 { title = "tests finished"
274 Just ( label, current ) ->
277 [ Testable.render current ]
281viewResultsInline : WithResults (Testable.Element Msg) -> Html Msg
282viewResultsInline testable =
285 [ viewResultsAnnotationStylesheet testable.results
286 , Testable.render testable.element
290{-| Our ID is part of our label. This could be fixed farther down the chain, but I think it'd be pretty involved.
292So, now we can just parse the id out of the label.
298 (Parser.succeed identity
299 |. Parser.chompWhile (\c -> c /= '#')
301 { start = \c -> c == '#'
302 , inner = \c -> Char.isAlphaNum c || c == '-'
303 , reserved = Set.empty
309viewResultsAnnotationStylesheet results =
311 toStyleClass ( label, maybeFailure ) =
317 case parseId label of
319 Debug.log "NO ID FOUND" label
322 id ++ " { background-color:red; outline: dashed; };"
326 |> List.map toStyleClass
331 [ Html.text styleSheet
335viewResult : WithResults (Testable.Element Msg) -> Element.Element Msg
339 case Tuple.second result of
346 ( passing, failing ) =
347 List.partition isPassing testable.results
351 ( label, Nothing ) ->
353 [ Background.color palette.green
354 , Font.color palette.black
355 , Element.paddingXY 20 10
360 Element.text ("Success! - " ++ label)
362 ( label, Just ({ given, description } as reason) ) ->
364 [ Background.color palette.red
365 , Font.color palette.black
366 , Element.paddingXY 20 10
368 , Element.width Element.shrink
370 -- , Element.spacing 25
373 [ Element.el [ Element.width Element.fill ] <| Element.text label
374 , Element.el [ Element.width Element.fill ] <| Element.text (viewReason reason)
379 , Border.color palette.lightGrey
381 , Element.height Element.shrink
385 [ Element.el [ Font.bold, Font.size 64 ] (Element.text testable.label)
386 , Element.column [ Element.alignLeft, Element.spacing 20 ]
388 |> List.map viewSingle
393 , Background.color palette.green
394 , Font.color palette.black
395 , Element.paddingXY 20 10
399 (Element.text (String.fromInt (List.length passing) ++ " tests passing!"))
403viewReason { description, reason } =
408 Failure.Equality one two ->
409 description ++ " " ++ one ++ " " ++ two
411 Failure.Comparison one two ->
412 description ++ " " ++ one ++ " " ++ two
414 Failure.ListDiff expected actual ->
416 ++ String.join " \n" expected
418 ++ String.join " \n" actual
420 Failure.CollectionDiff { expected, actual, extra, missing } ->
422 [ formatKeyValue "expected" expected
423 , formatKeyValue "actual" actual
424 , formatKeyValue "extra" (String.join ", " extra)
425 , formatKeyValue "missing" (String.join ", " missing)
435formatKeyValue : String -> String -> String
436formatKeyValue key val =
447 { given : Maybe String
448 , description : String
455port test : String -> Cmd msg
458port analyze : List String -> Cmd msg
464 , bbox : Testable.BoundingBox
465 , style : List ( String, String )
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list