1module Testable exposing
8 , LayoutExpectation(..)
13 , compareFormattedColor
16 , formatColorWithAlpha
28import Dict exposing (Dict)
29import Element exposing (Color)
30import Html exposing (Html)
32import Internal.Model as Internal
33import Test exposing (Test)
37 = El (List (Attr msg)) (Element msg)
38 | Row (List (Attr msg)) (List (Element msg))
39 | Column (List (Attr msg)) (List (Element msg))
40 | TextColumn (List (Attr msg)) (List (Element msg))
41 | Paragraph (List (Attr msg)) (List (Element msg))
46{-| We have an attribute id in order to remove tests when an overriding attribtue is assigned.
48Basically, we want to implictly test for height/width shrink.
50But we want to skip this test if width/height is already set.
52This allows us to do that by comparing identities.
62 = Attr (Element.Attribute msg)
64 { test : Surroundings -> List LayoutExpectation
68 | Batch (List (Attr msg))
72 , element : Element msg
73 , test : Surroundings -> List LayoutExpectation
77 { test : Surroundings -> List LayoutExpectation
79 , attr : Element.Attribute msg
100type alias Surroundings =
101 { siblings : List Found
103 , children : List Found
106 -- These values are needed to perform some types of tests.
107 , location : LayoutContext
108 , parentSpacing : Int
124type alias BoundingBox =
140type LayoutExpectation
142 { description : String
148type alias LayoutTest =
149 { elementDomId : String
151 , expectations : List LayoutExpectation
159equal : a -> a -> LayoutExpectation
162 { description = "Are equal"
163 , result = one == two
167true : String -> Bool -> LayoutExpectation
170 { description = label
175todo : String -> LayoutExpectation
184getIds : Element msg -> List String
186 "se-0" :: getElementId [ 0, 0 ] el
189getElementId : List Int -> Element msg -> List String
190getElementId level el =
195 attrID attrIndex attr =
198 getElementId (attrIndex :: -1 :: level) nearby.element
205 |> List.indexedMap attrID
208 childrenIDs children =
209 List.concat <| List.indexedMap (\i -> getElementId (i :: level)) children
213 id :: getElementId (0 :: level) child ++ attributeIDs attrs
215 Row attrs children ->
216 id :: childrenIDs children ++ attributeIDs attrs
218 Column attrs children ->
219 id :: childrenIDs children ++ attributeIDs attrs
221 TextColumn attrs children ->
222 id :: childrenIDs children ++ attributeIDs attrs
224 Paragraph attrs children ->
225 id :: childrenIDs children ++ attributeIDs attrs
238toElement : Element msg -> Element.Element msg
240 renderElement [ 0, 0 ] el
243toHtml : Element msg -> Html msg
245 Element.layout [ idAttr "0" ] <|
246 renderElement [ 0, 0 ] el
249idAttr : String -> Element.Attribute msg
251 Element.htmlAttribute (Html.Attributes.id ("se-" ++ id))
254renderElement : List Int -> Element msg -> Element.Element msg
255renderElement level el =
259 |> List.map String.fromInt
263 makeAttributes attrs =
265 |> List.indexedMap (renderAttribute level)
271 (id :: makeAttributes attrs)
272 (renderElement (0 :: level) child)
274 Row attrs children ->
276 (id :: makeAttributes attrs)
277 (List.indexedMap (\i -> renderElement (i :: level)) children)
279 Column attrs children ->
281 (id :: makeAttributes attrs)
282 (List.indexedMap (\i -> renderElement (i :: level)) children)
284 TextColumn attrs children ->
286 (id :: makeAttributes attrs)
287 (List.indexedMap (\i -> renderElement (i :: level)) children)
289 Paragraph attrs children ->
291 (id :: makeAttributes attrs)
292 (List.indexedMap (\i -> renderElement (i :: level)) children)
301renderAttribute : List Int -> Int -> Attr msg -> List (Element.Attribute msg)
302renderAttribute level attrIndex attr =
313 Nearby { location, element } ->
316 [ Element.above (renderElement (attrIndex :: -1 :: level) element) ]
319 [ Element.below (renderElement (attrIndex :: -1 :: level) element) ]
322 [ Element.onRight (renderElement (attrIndex :: -1 :: level) element) ]
325 [ Element.onLeft (renderElement (attrIndex :: -1 :: level) element) ]
328 [ Element.inFront (renderElement (attrIndex :: -1 :: level) element) ]
331 [ Element.behindContent (renderElement (attrIndex :: -1 :: level) element) ]
334 List.indexedMap (renderAttribute (attrIndex :: level)) batch
337 LabeledTest tested ->
345runTests : Dict String Found -> Element msg -> List LayoutTest
346runTests harvested el =
349 Dict.get "se-0" harvested
353 [ { elementDomId = "se-0"
354 , label = "Finding root element"
357 { description = "Locating root element for rendering tests"
376levelToString : List Int -> String
379 |> List.map String.fromInt
381 |> (\x -> "se-" ++ x)
385 { siblings : List Found
387 , cache : Dict String Found
389 , element : Element msg
390 , location : LayoutContext
391 , parentSpacing : Int
394createTest { siblings, parent, cache, level, element, location, parentSpacing } =
398 |> Maybe.withDefault 0
403 testChildren : Found -> List (Element msg) -> List LayoutTest
404 testChildren found children =
407 -- Should check that this lookup doesn't fail.
408 -- Thoug if it does, it'll fail when the element itself is tested
411 Dict.get (levelToString (x :: level)) cache
413 (List.range 0 (List.length children))
415 List.foldl (applyChildTest found)
417 , upcoming = childrenFound
430 , previous : List Found
431 , tests : List LayoutTest
432 , upcoming : List Found
436 , previous : List Found
437 , tests : List LayoutTest
438 , upcoming : List Found
440 applyChildTest found child childTest =
441 -- { index, upcoming, previous, tests }
443 surroundingChildren =
444 case childTest.upcoming of
449 remaining ++ childTest.previous
453 { siblings = surroundingChildren
456 , level = childTest.index :: level
458 , parentSpacing = spacing
483 { index = childTest.index + 1
484 , tests = childTest.tests ++ childrenTests
486 case childTest.upcoming of
491 x :: childTest.previous
493 case childTest.upcoming of
501 tests : Found -> List (Attr msg) -> List (Element msg) -> List LayoutTest
502 tests self attributes children =
504 findBBox elem ( i, gathered ) =
517 case Dict.get (levelToString (i :: level)) cache of
521 Debug.log "el failed to find" elem
524 Debug.log "Failed to find child" (levelToString (i :: level))
536 List.foldl findBBox ( 0, [] ) children
542 -- Found -> Dict String Found -> List Int -> Int -> Surroundings -> Attr msg -> List Test
544 createAttributeTest self
548 { siblings = siblings
551 , children = childrenFoundData
552 , location = location
553 , parentSpacing = parentSpacing
560 ++ testChildren self children
562 case Dict.get id cache of
572 [ { elementDomId = id
573 , label = "Finding element in DOM"
576 { description = "Locating element for rendering test"
586 tests self attrs [ child ]
588 Row attrs children ->
589 tests self attrs children
591 Column attrs children ->
592 tests self attrs children
594 TextColumn attrs children ->
595 tests self attrs children
597 Paragraph attrs children ->
598 tests self attrs children
615createAttributeTest parent cache level attrIndex surroundings attr =
618 "#" ++ levelToString level
628 [ { elementDomId = domId
629 , label = details.label
630 , expectations = details.test surroundings
640 , level = attrIndex :: -1 :: level
641 , location = IsNearby nearby.location
645 { label = nearby.label
656 |> List.indexedMap (\i attribute -> createAttributeTest parent cache (attrIndex :: level) i surroundings attribute)
659 LabeledTest { label, test } ->
660 [ { elementDomId = domId
662 , expectations = test surroundings
667addAttribute : Attr msg -> Element msg -> Element msg
668addAttribute attr el =
671 El (attr :: attrs) child
673 Row attrs children ->
674 Row (attr :: attrs) children
676 Column attrs children ->
677 Column (attr :: attrs) children
679 TextColumn attrs children ->
680 TextColumn (attr :: attrs) children
682 Paragraph attrs children ->
683 Paragraph (attr :: attrs) children
700-- { given : Maybe String
701-- , description : String
702-- , reason : Test.Runner.Failure.Reason
705-- runTests seed tests =
710-- List.map Test.Runner.getFailureReason (runner.run ())
712-- List.map2 Tuple.pair runner.labels ran
714-- case Test.Runner.fromTest 100 seed tests of
715-- Test.Runner.Plain rnrs ->
717-- Test.Runner.Only rnrs ->
719-- Test.Runner.Skipping rnrs ->
721-- Test.Runner.Invalid invalid ->
724-- Debug.log "Invalid tests" invalid
728-- List.concat results
731compareFormattedColor : Color -> String -> Bool
732compareFormattedColor color expected =
733 formatColor color == expected || formatColorWithAlpha color == expected
736formatColorWithAlpha : Color -> String
737formatColorWithAlpha (Internal.Rgba red green blue alpha) =
739 ("rgba(" ++ String.fromInt (round (red * 255)))
740 ++ (", " ++ String.fromInt (round (green * 255)))
741 ++ (", " ++ String.fromInt (round (blue * 255)))
746 ("rgba(" ++ String.fromInt (round (red * 255)))
747 ++ (", " ++ String.fromInt (round (green * 255)))
748 ++ (", " ++ String.fromInt (round (blue * 255)))
749 ++ (", " ++ String.fromFloat alpha ++ ")")
752formatColor : Color -> String
753formatColor (Internal.Rgba red green blue alpha) =
755 ("rgb(" ++ String.fromInt (round (red * 255)))
756 ++ (", " ++ String.fromInt (round (green * 255)))
757 ++ (", " ++ String.fromInt (round (blue * 255)))
761 ("rgb(" ++ String.fromInt (round (red * 255)))
762 ++ (", " ++ String.fromInt (round (green * 255)))
763 ++ (", " ++ String.fromInt (round (blue * 255)))
767getSpacing : Element msg -> Maybe Int
770 getSpacingAttr attr found =
771 if found /= Nothing then
780 List.foldr getSpacingAttr Nothing attrs
786 List.foldr getSpacingAttr Nothing attrs
798 TextColumn attrs _ ->
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