1port module Testable.Runner exposing (Msg, TestableProgram, program, show)
6import Dict exposing (Dict)
8import Element.Background as Background
9import Element.Border as Border
10import Element.Events as Events
11import Element.Font as Font
12import Html exposing (Html)
20show : Testable.Element msg -> Html msg
25type alias TestableProgram =
26 Program () (Model Msg) Msg
30 { white = Element.rgb 1 1 1
31 , red = Element.rgb 1 0 0
32 , green = Element.rgb 0 1 0
33 , black = Element.rgb 0 0 0
34 , lightGrey = Element.rgb 0.7 0.7 0.7
38program : List ( String, Testable.Element Msg ) -> TestableProgram
41 ( current, upcoming ) =
47 ( Just cur, remaining )
56 , highlightDomId = Nothing
58 , Task.perform (always Analyze)
66 , subscriptions = subscriptions
70subscriptions : Model Msg -> Sub Msg
73 [ styles RefreshBoundingBox
78 { current : Maybe ( String, Testable.Element msg )
79 , upcoming : List ( String, Testable.Element msg )
80 , finished : List (WithResults (Testable.Element msg))
82 , highlightDomId : Maybe String
86type alias WithResults thing =
90 List Testable.LayoutTest
95 List (WithResults (Testable.Element msg))
101 { description : String
106encodeForReport withResults =
108 prepareExpectation layoutTest exp =
110 Testable.Todo description ->
111 { description = description
116 Testable.Expect details ->
117 { description = details.description
118 , passing = details.result
122 prepareNode layoutTest =
123 List.map (prepareExpectation layoutTest) layoutTest.expectations
125 prepare { label, results } =
127 , results = List.concatMap prepareNode results
130 List.map prepare withResults
137 | HighlightDomID (Maybe String)
141 , bbox : Testable.BoundingBox
142 , style : List ( String, String )
144 , textMetrics : List Testable.TextMetrics
149runTest : Dict String Testable.Found -> String -> Testable.Element msg -> WithResults (Testable.Element msg)
150runTest boxes label element =
153 Testable.runTests boxes element
161update : Msg -> Model Msg -> ( Model Msg, Cmd Msg )
167 HighlightDomID newId ->
168 ( { model | highlightDomId = newId }
173 ( { model | selected = index }
177 RefreshBoundingBox boxes ->
178 case model.current of
184 Just ( label, current ) ->
188 , { style = Dict.fromList box.style
190 , isVisible = box.isVisible
191 , textMetrics = box.textMetrics
201 runTest foundData label current
203 case model.upcoming of
207 , finished = model.finished ++ [ currentResults ]
209 , report (encodeForReport (currentResults :: model.finished))
212 newCurrent :: remaining ->
214 | finished = model.finished ++ [ currentResults ]
215 , current = Just newCurrent
216 , upcoming = remaining
218 , Task.perform (always Analyze)
226 case model.current of
232 Just ( label, current ) ->
234 , analyze (Testable.getIds current)
238view : Model Msg -> Html.Html Msg
240 case model.current of
242 if List.isEmpty model.upcoming then
245 getByIndex model.selected model.finished
247 -- |> Debug.log "selected"
251 , Element.inFront (Element.html (viewElementHighlight model))
252 , Element.height Element.fill
255 Element.row [ Element.width Element.fill, Element.height Element.fill ]
259 |> Element.maximum 900
262 , Element.height Element.fill
267 , Element.padding 100
270 , Border.color palette.lightGrey
275 , Font.color palette.lightGrey
277 (Element.text "test case")
282 Element.text "nothing selected"
285 Testable.toElement sel.element
291 , Element.width Element.fill
292 , Element.height Element.fill
295 (List.indexedMap (viewResult model.selected) model.finished)
301 Just ( label, current ) ->
302 Testable.toHtml current
307 (\elem ( index, found ) ->
309 ( index + 1, Just elem )
319viewElementHighlight model =
320 case model.highlightDomId of
324 Just highlightDomId ->
327 highlightDomId ++ " { outline: solid black; }"
332 |> String.append "#tests-"
335 testId ++ " { outline: dashed black; }"
345 [ Html.text styleSheet
349viewResult : Int -> Int -> WithResults (Testable.Element Msg) -> Element.Element Msg
350viewResult selectedIndex index testable =
351 if index == selectedIndex then
356 [ Element.el [ Font.size 24 ] (Element.text testable.label)
358 [ Element.alignLeft, Element.spacing 16 ]
360 |> groupBy .elementDomId
361 |> List.map (expandDetails >> viewLayoutTestGroup)
367 isExpectationPassing result =
369 Testable.Todo label ->
372 Testable.Expect details ->
375 isPassing layoutTest =
376 List.all isExpectationPassing layoutTest.expectations
378 ( passing, failing ) =
379 List.partition isPassing testable.results
385 , Events.onClick (Select index)
387 [ Element.row [ Element.spacing 16 ]
388 [ Element.el [ Font.size 24 ] (Element.text testable.label)
389 , Element.text (String.fromInt (List.length passing) ++ " passing")
394 if failingCount == 0 then
398 Element.text (String.fromInt (List.length failing) ++ " failing")
404 case group.members of
407 , elementType = Testable.EmptyType
408 , members = group.members
413 , elementType = top.elementType
414 , members = group.members
419 groupWhile (\one two -> fn one == fn two) list
421 (\( fst, remaining ) ->
423 , members = fst :: remaining
428groupWhile : (a -> a -> Bool) -> List a -> List ( a, List a )
429groupWhile isSameGroup items =
436 ( y, restOfGroup ) :: groups ->
437 if isSameGroup x y then
438 ( x, y :: restOfGroup ) :: groups
447viewLayoutTestGroup group =
452 |> String.append "tests-"
456 , Element.htmlAttribute (Html.Attributes.id testId)
457 , Events.onMouseEnter (HighlightDomID (Just group.id))
458 , Events.onMouseLeave (HighlightDomID Nothing)
459 , Element.htmlAttribute (Html.Attributes.style "user-select" "none")
461 [ Element.row [ Element.spacing 16 ]
462 [ Element.el [] (Element.text (Testable.elementTypeToString group.elementType))
463 , Element.el [ Font.color palette.lightGrey ] (Element.text group.id)
467 , Element.paddingXY 32 0
469 (List.map viewLayoutTest group.members)
473type alias Grouped thing =
475 , members : List thing
479viewLayoutTest layoutTest =
483 [ Element.row [ Element.spacing 8 ]
484 [ Element.el [ Font.bold ] (Element.text layoutTest.label)
486 -- , Element.el [ Font.color palette.lightGrey ] (Element.text layoutTest.elementDomId)
488 , Element.column [ Element.spacing 8 ]
489 (List.map viewLayoutExpectation layoutTest.expectations)
493viewLayoutExpectation expectation =
495 Testable.Todo label ->
496 Element.row [ Element.spacing 4 ]
497 [ todo, Element.text label ]
499 Testable.Expect details ->
500 if details.result then
501 Element.row [ Element.spacing 4 ]
502 [ pass, Element.text details.description ]
505 Element.row [ Element.spacing 4 ]
506 [ fail, Element.text details.description ]
511 [ Background.color color
512 , Font.color palette.black
513 , Element.paddingXY 4 8
520 badge palette.lightGrey "todo"
524 badge palette.green "pass"
528 badge palette.red "fail"
531formatKeyValue : String -> String -> String
532formatKeyValue key val =
541 { description : String
549port test : String -> Cmd msg
552port analyze : List String -> Cmd msg
558 , bbox : Testable.BoundingBox
559 , style : List ( String, String )
561 , textMetrics : List Testable.TextMetrics
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