1module Testable exposing
9 , LayoutExpectation(..)
15 , compareFormattedColor
19 , formatColorWithAlpha
22 , getSpacingFromAttributes
33import Dict exposing (Dict)
34import Element exposing (Color)
35import Html exposing (Html)
37import Internal.Model as Internal
38import Test exposing (Test)
42 = El (List (Attr msg)) (Element msg)
43 | Row (List (Attr msg)) (List (Element msg))
44 | Column (List (Attr msg)) (List (Element msg))
45 | TextColumn (List (Attr msg)) (List (Element msg))
46 | Paragraph (List (Attr msg)) (List (Element msg))
61elementTypeToString : ElementType -> String
62elementTypeToString elem =
86toElementType : Element msg -> ElementType
111{-| We have an attribute id in order to remove tests when an overriding attribtue is assigned.
113Basically, we want to implictly test for height/width shrink.
115But we want to skip this test if width/height is already set.
117This allows us to do that by comparing identities.
127 = Attr (Element.Attribute msg)
129 { test : Surroundings msg -> List LayoutExpectation
133 | Batch (List (Attr msg))
136 { location : Location
137 , element : Element msg
138 , test : Surroundings msg -> List LayoutExpectation
142 { test : Surroundings msg -> List LayoutExpectation
144 , attr : Element.Attribute msg
165type alias Surroundings msg =
166 { siblings : List Found
168 , children : List Found
170 , selfElement : Element msg
172 -- These values are needed to perform some types of tests.
173 , parentLayout : LayoutContext
174 , parentSpacing : Int
182 , textMetrics : List TextMetrics
186type alias TextMetrics =
187 { actualBoundingBoxAscent : Float
188 , actualBoundingBoxDescent : Float
189 , actualBoundingBoxLeft : Float
190 , actualBoundingBoxRight : Float
196 metrics.actualBoundingBoxAscent
197 + metrics.actualBoundingBoxDescent
205type alias BoundingBox =
221type LayoutExpectation
223 { description : String
229type alias LayoutTest =
230 { elementDomId : String
231 , elementType : ElementType
233 , expectations : List LayoutExpectation
241equal : a -> a -> LayoutExpectation
244 { description = "Are equal"
245 , result = one == two
249true : String -> Bool -> LayoutExpectation
252 { description = label
257todo : String -> LayoutExpectation
266getIds : Element msg -> List String
268 "se-0" :: getElementId [ 0, 0 ] el
271getElementId : List Int -> Element msg -> List String
272getElementId level el =
277 attrID attrIndex attr =
280 getElementId (attrIndex :: -1 :: level) nearby.element
287 |> List.indexedMap attrID
290 childrenIDs children =
291 List.concat <| List.indexedMap (\i -> getElementId (i :: level)) children
295 id :: getElementId (0 :: level) child ++ attributeIDs attrs
297 Row attrs children ->
298 id :: childrenIDs children ++ attributeIDs attrs
300 Column attrs children ->
301 id :: childrenIDs children ++ attributeIDs attrs
303 TextColumn attrs children ->
304 id :: childrenIDs children ++ attributeIDs attrs
306 Paragraph attrs children ->
307 id :: childrenIDs children ++ attributeIDs attrs
320toElement : Element msg -> Element.Element msg
322 renderElement [ 0, 0 ] el
325toHtml : Element msg -> Html msg
327 Element.layout [ idAttr "0" ] <|
328 renderElement [ 0, 0 ] el
331idAttr : String -> Element.Attribute msg
333 Element.htmlAttribute (Html.Attributes.id ("se-" ++ id))
336renderElement : List Int -> Element msg -> Element.Element msg
337renderElement level el =
341 |> List.map String.fromInt
345 makeAttributes attrs =
347 |> List.indexedMap (renderAttribute level)
353 (id :: makeAttributes attrs)
354 (renderElement (0 :: level) child)
356 Row attrs children ->
358 (id :: makeAttributes attrs)
359 (List.indexedMap (\i -> renderElement (i :: level)) children)
361 Column attrs children ->
363 (id :: makeAttributes attrs)
364 (List.indexedMap (\i -> renderElement (i :: level)) children)
366 TextColumn attrs children ->
368 (id :: makeAttributes attrs)
369 (List.indexedMap (\i -> renderElement (i :: level)) children)
371 Paragraph attrs children ->
373 (id :: makeAttributes attrs)
374 (List.indexedMap (\i -> renderElement (i :: level)) children)
383renderAttribute : List Int -> Int -> Attr msg -> List (Element.Attribute msg)
384renderAttribute level attrIndex attr =
395 Nearby { location, element } ->
398 [ Element.above (renderElement (attrIndex :: -1 :: level) element) ]
401 [ Element.below (renderElement (attrIndex :: -1 :: level) element) ]
404 [ Element.onRight (renderElement (attrIndex :: -1 :: level) element) ]
407 [ Element.onLeft (renderElement (attrIndex :: -1 :: level) element) ]
410 [ Element.inFront (renderElement (attrIndex :: -1 :: level) element) ]
413 [ Element.behindContent (renderElement (attrIndex :: -1 :: level) element) ]
416 List.indexedMap (renderAttribute (attrIndex :: level)) batch
419 LabeledTest tested ->
427runTests : Dict String Found -> Element msg -> List LayoutTest
428runTests harvested el =
431 Dict.get "se-0" harvested
435 [ { elementDomId = "se-0"
436 , elementType = EmptyType
437 , label = "Finding root element"
440 { description = "Locating root element for rendering tests"
459levelToString : List Int -> String
462 |> List.map String.fromInt
464 |> (\x -> "se-" ++ x)
468 { siblings : List Found
470 , cache : Dict String Found
472 , element : Element msg
473 , location : LayoutContext
474 , parentSpacing : Int
477createTest { siblings, parent, cache, level, element, location, parentSpacing } =
481 |> Maybe.withDefault 0
488 Debug.log "element" element
490 testChildren : Found -> List (Element msg) -> List LayoutTest
491 testChildren found children =
494 -- Should check that this lookup doesn't fail.
495 -- Thoug if it does, it'll fail when the element itself is tested
498 Dict.get (levelToString (x :: level)) cache
500 (List.range 0 (List.length children))
502 List.foldl (applyChildTest found)
504 , upcoming = childrenFound
517 , previous : List Found
518 , tests : List LayoutTest
519 , upcoming : List Found
523 , previous : List Found
524 , tests : List LayoutTest
525 , upcoming : List Found
527 applyChildTest found child childTest =
528 -- { index, upcoming, previous, tests }
530 surroundingChildren =
531 case childTest.upcoming of
536 remaining ++ childTest.previous
540 { siblings = surroundingChildren
543 , level = childTest.index :: level
545 , parentSpacing = spacing
570 { index = childTest.index + 1
571 , tests = childTest.tests ++ childrenTests
573 case childTest.upcoming of
578 x :: childTest.previous
580 case childTest.upcoming of
588 tests : Found -> List (Attr msg) -> List (Element msg) -> List LayoutTest
589 tests self attributes children =
591 findBBox elem ( i, gathered ) =
604 case Dict.get (levelToString (i :: level)) cache of
608 Debug.log "el failed to find" elem
611 Debug.log "Failed to find child" (levelToString (i :: level))
623 List.foldl findBBox ( 0, [] ) children
628 |> Debug.log "attributes"
630 -- Found -> Dict String Found -> List Int -> Int -> Surroundings -> Attr msg -> List Test
632 createAttributeTest self
636 { siblings = siblings
639 , selfElement = element
640 , children = childrenFoundData
641 , parentLayout = location
642 , parentSpacing = parentSpacing
649 ++ testChildren self children
651 case Dict.get id cache of
661 [ { elementDomId = id
662 , elementType = EmptyType
663 , label = "Finding element in DOM"
666 { description = "Locating element for rendering test"
676 tests self attrs [ child ]
678 Row attrs children ->
679 tests self attrs children
681 Column attrs children ->
682 tests self attrs children
684 TextColumn attrs children ->
685 tests self attrs children
687 Paragraph attrs children ->
688 tests self attrs children
705createAttributeTest parent cache level attrIndex surroundings attr =
708 Debug.log "attribute test" attr
712 ++ levelToString level
723 [ { elementDomId = domId
725 toElementType surroundings.selfElement
726 , label = details.label
727 , expectations = details.test surroundings
737 , level = attrIndex :: -1 :: level
738 , location = IsNearby nearby.location
742 { label = nearby.label
753 |> List.indexedMap (\i attribute -> createAttributeTest parent cache level i surroundings attribute)
756 LabeledTest { label, test } ->
757 [ { elementDomId = domId
758 , elementType = toElementType surroundings.selfElement
760 , expectations = test surroundings
765addAttribute : Attr msg -> Element msg -> Element msg
766addAttribute attr el =
769 El (attr :: attrs) child
771 Row attrs children ->
772 Row (attr :: attrs) children
774 Column attrs children ->
775 Column (attr :: attrs) children
777 TextColumn attrs children ->
778 TextColumn (attr :: attrs) children
780 Paragraph attrs children ->
781 Paragraph (attr :: attrs) children
790compareFormattedColor : Color -> String -> Bool
791compareFormattedColor color expected =
792 formatColor color == expected || formatColorWithAlpha color == expected
795formatColorWithAlpha : Color -> String
796formatColorWithAlpha (Internal.Rgba red green blue alpha) =
798 ("rgba(" ++ String.fromInt (round (red * 255)))
799 ++ (", " ++ String.fromInt (round (green * 255)))
800 ++ (", " ++ String.fromInt (round (blue * 255)))
805 ("rgba(" ++ String.fromInt (round (red * 255)))
806 ++ (", " ++ String.fromInt (round (green * 255)))
807 ++ (", " ++ String.fromInt (round (blue * 255)))
808 ++ (", " ++ String.fromFloat alpha ++ ")")
811formatColor : Color -> String
812formatColor (Internal.Rgba red green blue alpha) =
814 ("rgb(" ++ String.fromInt (round (red * 255)))
815 ++ (", " ++ String.fromInt (round (green * 255)))
816 ++ (", " ++ String.fromInt (round (blue * 255)))
820 ("rgb(" ++ String.fromInt (round (red * 255)))
821 ++ (", " ++ String.fromInt (round (green * 255)))
822 ++ (", " ++ String.fromInt (round (blue * 255)))
826getSpacingFromAttributes attrs =
831 (Spacing i) :: remain ->
834 (Batch batched) :: remain ->
835 getSpacingFromAttributes (batched ++ remain)
838 getSpacingFromAttributes remain
841getSpacing : Element msg -> Maybe Int
844 getSpacingAttr attr found =
845 if found /= Nothing then
854 List.foldr getSpacingAttr Nothing attrs
860 List.foldr getSpacingAttr Nothing attrs
872 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