1module Testable.Element exposing
15 , expectRoundedEquality
40{-| This module should mirror the top level `Element` api, with one important distinction.
42The resulting `Element msg` structure can either be rendered to Html or transformed into a test suite that can be run.
44In order to run the test:
47 - gather information from the browser
59text : String -> Testable.Element msg
64el : List (Testable.Attr msg) -> Testable.Element msg -> Testable.Element msg
69row : List (Testable.Attr msg) -> List (Testable.Element msg) -> Testable.Element msg
74column : List (Testable.Attr msg) -> List (Testable.Element msg) -> Testable.Element msg
79none : Testable.Element msg
84paragraph : List (Testable.Attr msg) -> List (Testable.Element msg) -> Testable.Element msg
89textColumn : List (Testable.Attr msg) -> List (Testable.Element msg) -> Testable.Element msg
125fillPortion : Int -> Length
130label : String -> Testable.Attr msg
135transparent : Bool -> Testable.Attr msg
144 , attr = Element.transparent on
150 |> Dict.get "opacity"
151 |> Maybe.withDefault "notfound"
160 Expect.equal value selfTransparency
165isVisible : Testable.Attr msg
168 { label = "is-visible"
169 , attr = Element.htmlAttribute (Html.Attributes.style "not" "applicable")
172 Expect.equal context.self.isVisible True
177alpha : Float -> Testable.Attr msg
180 { label = "alpha-" ++ String.fromFloat a
181 , attr = Element.alpha a
187 |> Dict.get "opacity"
188 |> Maybe.withDefault "notfound"
190 Expect.equal (String.fromFloat a) selfTransparency
195padding : Int -> Testable.Attr msg
198 { label = "padding " ++ String.fromInt pad
199 , attr = Element.padding pad
202 Expect.true ("Padding " ++ String.fromInt pad ++ " is present")
204 [ floor found.self.bbox.padding.left
205 , floor found.self.bbox.padding.right
206 , floor found.self.bbox.padding.top
207 , floor found.self.bbox.padding.bottom
214paddingXY : Int -> Int -> Testable.Attr msg
217 { label = "paddingXY " ++ String.fromInt x ++ ", " ++ String.fromInt y
218 , attr = Element.paddingXY x y
221 Expect.true ("PaddingXY (" ++ String.fromInt x ++ ", " ++ String.fromInt y ++ ") is present")
223 [ floor found.self.bbox.padding.left
224 , floor found.self.bbox.padding.right
227 [ floor found.self.bbox.padding.top
228 , floor found.self.bbox.padding.bottom
234widthHelper maybeMin maybeMax len =
242 l |> Element.minimum minPx
250 l |> Element.maximum maxPx
258 " min:" ++ String.fromInt i
266 " max:" ++ String.fromInt i
268 minMaxTest actualWidth =
269 case ( maybeMin, maybeMax ) of
270 ( Nothing, Nothing ) ->
273 ( Just lower, Nothing ) ->
276 ( Just lower, Just higher ) ->
277 lower <= actualWidth && actualWidth <= higher
279 ( Nothing, Just higher ) ->
280 actualWidth <= higher
284 widthHelper (Just m) maybeMax newLen
287 widthHelper maybeMin (Just m) newLen
290 -- Pixel values should ignore min and max?
292 { label = "width " ++ String.fromInt val ++ "px" ++ minLabel ++ maxLabel
303 Expect.true "exact width is exact" (floor found.self.bbox.width == val)
304 , \_ -> Expect.true "min/max is upheld" (minMaxTest (floor found.self.bbox.width))
311 { label = "width fill-" ++ String.fromInt portion ++ minLabel ++ maxLabel
314 (Element.fillPortion portion
320 if List.member context.location [ Testable.IsNearby Testable.OnRight, Testable.IsNearby Testable.OnLeft ] then
321 Expect.true "width fill doesn't apply to onright/onleft elements" True
325 parentAvailableWidth =
326 context.parent.bbox.width - (context.self.bbox.padding.left + context.self.bbox.padding.right)
328 case context.location of
329 Testable.IsNearby _ ->
330 Expect.true "Nearby Element has fill width"
331 ((floor context.parent.bbox.width == floor context.self.bbox.width)
332 || minMaxTest (floor context.self.bbox.width)
336 Expect.true "Element within column has fill width"
337 ((floor parentAvailableWidth == floor context.self.bbox.width)
338 || minMaxTest (floor context.self.bbox.width)
342 Expect.true "Element within element has fill width" <|
343 (floor parentAvailableWidth == floor context.self.bbox.width)
344 || minMaxTest (floor context.self.bbox.width)
349 parentAvailableWidth / toFloat (List.length context.siblings + 1)
351 Expect.true "element has fill width" <|
352 (floor spacePerPortion == floor context.self.bbox.width)
353 || minMaxTest (floor context.self.bbox.width)
358 { label = "width shrink" ++ minLabel ++ maxLabel
369 -- TODO: add margin values to widths
374 |> List.map childWidth
378 context.self.bbox.padding.left + context.self.bbox.padding.right
381 toFloat context.parentSpacing * (toFloat (List.length context.children) - 1)
383 if totalChildren == 0 then
384 -- TODO: The issue is that we have a hard time measuring `text` elements
385 -- So if a element has a text child, then it's width isn't going to show up in the system.
386 expectRoundedEquality context.self.bbox.width context.self.bbox.width
389 -- This fails if this element is actually a column
390 -- So we need to capture what this element is in order to do this calculation.
391 expectRoundedEquality (totalChildren + horizontalPadding + spacingValue) context.self.bbox.width
395heightHelper maybeMin maybeMax len =
403 l |> Element.minimum minPx
411 l |> Element.maximum maxPx
419 " min:" ++ String.fromInt i
427 " max:" ++ String.fromInt i
429 minMaxTest actualheight =
430 case ( maybeMin, maybeMax ) of
431 ( Nothing, Nothing ) ->
434 ( Just lower, Nothing ) ->
435 lower <= actualheight
437 ( Just lower, Just higher ) ->
438 lower <= actualheight && actualheight <= higher
440 ( Nothing, Just higher ) ->
441 actualheight <= higher
445 heightHelper (Just m) maybeMax newLen
448 heightHelper maybeMin (Just m) newLen
451 -- Pixel values should ignore min and max?
453 { label = "height " ++ String.fromInt val ++ "px" ++ minLabel ++ maxLabel
464 Expect.true ("exact height is exact: " ++ String.fromInt (floor found.self.bbox.height) ++ "," ++ String.fromInt val)
465 (floor found.self.bbox.height == val)
467 Expect.true "min/max holds true"
468 (minMaxTest (floor found.self.bbox.height))
475 { label = "height fill-" ++ String.fromInt portion ++ minLabel ++ maxLabel
478 (Element.fillPortion portion
484 if List.member context.location [ Testable.IsNearby Testable.Above, Testable.IsNearby Testable.Below ] then
485 Expect.true "height fill doesn't apply to above/below elements" True
489 parentAvailableHeight =
490 context.parent.bbox.height - (context.self.bbox.padding.top + context.self.bbox.padding.bottom)
492 case context.location of
493 Testable.IsNearby _ ->
494 Expect.true "Nearby Element has fill height"
495 ((floor context.parent.bbox.height == floor context.self.bbox.height)
496 || minMaxTest (floor context.self.bbox.height)
500 Expect.true "Element within column has fill height"
501 ((floor parentAvailableHeight == floor context.self.bbox.height)
502 || minMaxTest (floor context.self.bbox.height)
506 Expect.true "Element within el has fill height" <|
507 (floor parentAvailableHeight == floor context.self.bbox.height)
508 || minMaxTest (floor context.self.bbox.height)
513 parentAvailableHeight / toFloat (List.length context.siblings + 1)
515 Expect.true "el has fill height" <|
516 (floor spacePerPortion == floor context.self.bbox.height)
517 || minMaxTest (floor context.self.bbox.height)
522 { label = "height shrink" ++ minLabel ++ maxLabel
533 -- TODO: add margin values to heights
538 |> List.map childWidth
542 context.self.bbox.padding.top + context.self.bbox.padding.bottom
545 toFloat context.parentSpacing * (toFloat (List.length context.children) - 1)
547 if totalChildren == 0 then
548 -- TODO: The issue is that we have a hard time measuring `text` elements
549 -- So if a element has a text child, then it's height isn't going to show up in the system.
550 expectRoundedEquality context.self.bbox.height context.self.bbox.height
553 -- This fails if this element is actually a column
554 -- So we need to capture what this element is in order to do this calculation.
555 expectRoundedEquality (totalChildren + verticalPadding + spacingValue) context.self.bbox.height
559width : Length -> Testable.Attr msg
561 widthHelper Nothing Nothing len
564height : Length -> Testable.Attr msg
566 heightHelper Nothing Nothing len
569spacing : Int -> Testable.Attr msg
572 [ Testable.Spacing space
573 , Testable.LabeledTest
574 { label = "spacing: " ++ String.fromInt space
575 , attr = Element.spacing space
579 findDistance child total =
586 - otherChild.bbox.right
591 - otherChild.bbox.bottom
593 [ if horizontal > 0 then
598 , if vertical > 0 then
609 List.foldl findDistance [] found.children
614 if not (x >= space) then
624 ("All children are at least "
625 ++ String.fromInt space
627 ++ Debug.toString allAreSpaced
635{-| alignLeft needs to account for
638 - elements to the left
641in order to calculate the expected result.
643Also need parent rendering context if this is to work with wrapped rows in the future.
648alignLeft : Testable.Attr msg
651 { label = "alignLeft"
652 , attr = Element.alignLeft
655 if List.member found.location [ Testable.IsNearby Testable.OnLeft, Testable.IsNearby Testable.OnRight ] then
656 Expect.true "alignLeft doesn't apply to elements that are onLeft or onRight" True
659 List.member found.location
660 [ Testable.IsNearby Testable.InFront
661 , Testable.IsNearby Testable.Behind
662 , Testable.IsNearby Testable.Above
663 , Testable.IsNearby Testable.Below
666 expectRoundedEquality
668 found.parent.bbox.left
670 else if List.length found.siblings == 0 then
671 expectRoundedEquality
673 (found.parent.bbox.left + found.parent.bbox.padding.left)
676 case found.location of
680 List.filter (\x -> x.bbox.right < found.self.bbox.left) found.siblings
683 toFloat (List.length siblingsOnLeft * found.parentSpacing)
687 |> List.map (.width << .bbox)
690 expectRoundedEquality
692 (found.parent.bbox.left + (found.parent.bbox.padding.left + widthsOnLeft + spacings))
695 expectRoundedEquality
697 (found.parent.bbox.left + found.parent.bbox.padding.left)
702centerX : Testable.Attr msg
706 , attr = Element.centerX
712 found.self.bbox.left + (found.self.bbox.width / 2)
716 found.parent.bbox.left + (found.parent.bbox.width / 2)
718 if List.member found.location [ Testable.IsNearby Testable.OnRight, Testable.IsNearby Testable.OnLeft ] then
719 Expect.true "centerX doesn't apply to elements that are onLeft or onRight" True
721 else if List.length found.siblings == 0 then
722 expectRoundedEquality
727 case found.location of
731 List.filter (\x -> x.bbox.right < found.self.bbox.left) found.siblings
734 List.filter (\x -> x.bbox.left > found.self.bbox.right) found.siblings
739 |> List.map (.width << .bbox)
741 |> (\x -> x + (toFloat (List.length siblingsOnLeft) * toFloat found.parentSpacing))
745 |> List.map (.width << .bbox)
747 |> (\x -> x + (toFloat (List.length siblingsOnRight) * toFloat found.parentSpacing))
749 expectedCenter : Float
751 found.parent.bbox.left
753 + ((found.parent.bbox.width - (widthsOnRight + widthsOnLeft))
757 expectRoundedEquality
762 expectRoundedEquality selfCenter parentCenter
767alignRight : Testable.Attr msg
770 { label = "alignRight"
771 , attr = Element.alignRight
774 if List.member found.location [ Testable.IsNearby Testable.OnLeft, Testable.IsNearby Testable.OnRight ] then
775 Expect.true "alignRight doesn't apply to elements that are onLeft or onRight" True
778 List.member found.location
779 [ Testable.IsNearby Testable.InFront
780 , Testable.IsNearby Testable.Behind
781 , Testable.IsNearby Testable.Above
782 , Testable.IsNearby Testable.Below
785 expectRoundedEquality
786 found.self.bbox.right
787 found.parent.bbox.right
789 else if List.length found.siblings == 0 then
790 expectRoundedEquality
791 found.self.bbox.right
792 (found.parent.bbox.right + found.parent.bbox.padding.right)
795 case found.location of
799 List.filter (\x -> x.bbox.left > found.self.bbox.right) found.siblings
802 toFloat (List.length siblingsOnRight * found.parentSpacing)
806 |> List.map (.width << .bbox)
809 expectRoundedEquality
810 found.self.bbox.right
811 (found.parent.bbox.right - (found.parent.bbox.padding.right + widthsOnRight + spacings))
814 expectRoundedEquality
815 found.self.bbox.right
816 (found.parent.bbox.right + found.parent.bbox.padding.right)
821alignTop : Testable.Attr msg
825 , attr = Element.alignTop
828 if List.member found.location [ Testable.IsNearby Testable.Above, Testable.IsNearby Testable.Below ] then
829 Expect.true "alignTop doesn't apply to elements that are above or below" True
832 List.member found.location
833 [ Testable.IsNearby Testable.InFront
834 , Testable.IsNearby Testable.Behind
835 , Testable.IsNearby Testable.OnRight
836 , Testable.IsNearby Testable.OnLeft
839 expectRoundedEquality
841 found.parent.bbox.top
843 else if List.length found.siblings == 0 then
844 expectRoundedEquality
846 (found.parent.bbox.top + found.parent.bbox.padding.top)
849 case found.location of
853 List.filter (\x -> x.bbox.bottom < found.self.bbox.top) found.siblings
856 toFloat (List.length siblingsAbove * found.parentSpacing)
860 |> List.map (.height << .bbox)
863 expectRoundedEquality
865 (found.parent.bbox.top + (found.parent.bbox.padding.top + heightsAbove + spacings))
868 expectRoundedEquality
870 found.parent.bbox.top
875alignBottom : Testable.Attr msg
878 { label = "alignBottom"
879 , attr = Element.alignBottom
882 if List.member found.location [ Testable.IsNearby Testable.Above, Testable.IsNearby Testable.Below ] then
883 Expect.true "alignBottom doesn't apply to elements that are above or below" True
886 List.member found.location
887 [ Testable.IsNearby Testable.InFront
888 , Testable.IsNearby Testable.Behind
889 , Testable.IsNearby Testable.OnRight
890 , Testable.IsNearby Testable.OnLeft
893 expectRoundedEquality
894 found.self.bbox.bottom
895 found.parent.bbox.bottom
897 else if List.length found.siblings == 0 then
898 expectRoundedEquality
899 found.self.bbox.bottom
900 (found.parent.bbox.bottom + found.parent.bbox.padding.bottom)
903 case found.location of
907 List.filter (\x -> x.bbox.top > found.self.bbox.bottom) found.siblings
910 toFloat (List.length siblingsBelow * found.parentSpacing)
914 |> List.map (.height << .bbox)
917 expectRoundedEquality
918 found.self.bbox.bottom
919 (found.parent.bbox.bottom - (found.parent.bbox.padding.bottom + heightsBelow + spacings))
922 expectRoundedEquality
923 found.self.bbox.bottom
924 (found.parent.bbox.bottom + found.parent.bbox.padding.bottom)
928expectRoundedEquality x y =
929 Expect.true ("within 1 of each other " ++ String.fromFloat x ++ ":" ++ String.fromFloat y)
934centerY : Testable.Attr msg
938 , attr = Element.centerY
943 found.self.bbox.top + (found.self.bbox.height / 2)
946 found.parent.bbox.top + (found.parent.bbox.height / 2)
948 if List.member found.location [ Testable.IsNearby Testable.Above, Testable.IsNearby Testable.Below ] then
949 Expect.true "centerY doesn't apply to elements that are above or below" True
951 else if List.length found.siblings == 0 then
952 expectRoundedEquality
957 case found.location of
961 List.filter (\x -> x.bbox.bottom < found.self.bbox.top) found.siblings
964 List.filter (\x -> x.bbox.top > found.self.bbox.bottom) found.siblings
969 |> List.map (.height << .bbox)
971 |> (\x -> x + (toFloat (List.length siblingsOnTop) * toFloat found.parentSpacing))
975 |> List.map (.height << .bbox)
977 |> (\x -> x + (toFloat (List.length siblingsBelow) * toFloat found.parentSpacing))
979 expectedCenter : Float
981 found.parent.bbox.top
983 + ((found.parent.bbox.height - (heightsBelow + heightsAbove))
987 expectRoundedEquality
992 expectRoundedEquality selfCenter parentCenter
997above : Testable.Element msg -> Testable.Attr msg
1000 { location = Testable.Above
1005 expectRoundedEquality found.self.bbox.bottom found.parent.bbox.top
1010below : Testable.Element msg -> Testable.Attr msg
1013 { location = Testable.Below
1018 expectRoundedEquality found.self.bbox.top found.parent.bbox.bottom
1023onRight : Testable.Element msg -> Testable.Attr msg
1026 { location = Testable.OnRight
1031 expectRoundedEquality found.self.bbox.left found.parent.bbox.right
1036onLeft : Testable.Element msg -> Testable.Attr msg
1039 { location = Testable.OnLeft
1044 expectRoundedEquality found.self.bbox.right found.parent.bbox.left
1049 vs (round x) (round y) || vs (floor x) (floor y)
1053inFront : Testable.Element msg -> Testable.Attr msg
1056 { location = Testable.InFront
1064withinHelper found _ =
1067 if found.self.bbox.width > found.parent.bbox.width then
1068 [ compare found.self.bbox.right (<=) found.parent.bbox.right
1069 || compare found.self.bbox.left (>=) found.parent.bbox.left
1073 [ compare found.self.bbox.right (<=) found.parent.bbox.right
1074 , compare found.self.bbox.left (>=) found.parent.bbox.left
1078 if found.self.bbox.width > found.parent.bbox.width then
1079 [ compare found.self.bbox.top (>=) found.parent.bbox.top
1080 || compare found.self.bbox.bottom (<=) found.parent.bbox.bottom
1084 [ compare found.self.bbox.top (>=) found.parent.bbox.top
1085 , compare found.self.bbox.bottom (<=) found.parent.bbox.bottom
1088 Expect.true "within the confines of the parent"
1089 (List.all ((==) True)
1099behindContent : Testable.Element msg -> Testable.Attr msg
1100behindContent element =
1102 { location = Testable.Behind
1104 , label = "behindContent"
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