1module Testable.Element exposing
15 , expectRoundedEquality
45{-| This module should mirror the top level `Element` api, with one important distinction.
47The resulting `Element msg` structure can either be rendered to Html or transformed into a test suite that can be run.
49In order to run the test:
52 - gather information from the browser
65layout : List (Testable.Attr msg) -> Testable.Element Testable.Runner.Msg -> Testable.Runner.TestableProgram
67 Testable.Runner.program
68 [ ( "Open Case", elem )
72text : String -> Testable.Element msg
77el : List (Testable.Attr msg) -> Testable.Element msg -> Testable.Element msg
82row : List (Testable.Attr msg) -> List (Testable.Element msg) -> Testable.Element msg
87column : List (Testable.Attr msg) -> List (Testable.Element msg) -> Testable.Element msg
92none : Testable.Element msg
97paragraph : List (Testable.Attr msg) -> List (Testable.Element msg) -> Testable.Element msg
102textColumn : List (Testable.Attr msg) -> List (Testable.Element msg) -> Testable.Element msg
108 Testable.Attr (Element.moveUp x)
112 Testable.Attr (Element.moveDown x)
154fillPortion : Int -> Length
159label : String -> Testable.Attr msg
164transparent : Bool -> Testable.Attr msg
173 , attr = Element.transparent on
179 |> Dict.get "opacity"
180 |> Maybe.withDefault "notfound"
189 Expect.equal value selfTransparency
194isVisible : Testable.Attr msg
197 { label = "is-visible"
198 , attr = Element.htmlAttribute (Html.Attributes.style "not" "applicable")
201 Expect.equal context.self.isVisible True
206alpha : Float -> Testable.Attr msg
209 { label = "alpha-" ++ String.fromFloat a
210 , attr = Element.alpha a
216 |> Dict.get "opacity"
217 |> Maybe.withDefault "notfound"
219 Expect.equal (String.fromFloat a) selfTransparency
224padding : Int -> Testable.Attr msg
227 { label = "padding " ++ String.fromInt pad
228 , attr = Element.padding pad
231 Expect.true ("Padding " ++ String.fromInt pad ++ " is present")
233 [ floor found.self.bbox.padding.left
234 , floor found.self.bbox.padding.right
235 , floor found.self.bbox.padding.top
236 , floor found.self.bbox.padding.bottom
243paddingXY : Int -> Int -> Testable.Attr msg
246 { label = "paddingXY " ++ String.fromInt x ++ ", " ++ String.fromInt y
247 , attr = Element.paddingXY x y
250 Expect.true ("PaddingXY (" ++ String.fromInt x ++ ", " ++ String.fromInt y ++ ") is present")
252 [ floor found.self.bbox.padding.left
253 , floor found.self.bbox.padding.right
256 [ floor found.self.bbox.padding.top
257 , floor found.self.bbox.padding.bottom
263widthHelper maybeMin maybeMax len =
271 l |> Element.minimum minPx
279 l |> Element.maximum maxPx
287 " min:" ++ String.fromInt i
295 " max:" ++ String.fromInt i
297 minMaxTest actualWidth =
298 case ( maybeMin, maybeMax ) of
299 ( Nothing, Nothing ) ->
302 ( Just lower, Nothing ) ->
305 ( Just lower, Just higher ) ->
306 lower <= actualWidth && actualWidth <= higher
308 ( Nothing, Just higher ) ->
309 actualWidth <= higher
313 widthHelper (Just m) maybeMax newLen
316 widthHelper maybeMin (Just m) newLen
319 -- Pixel values should ignore min and max?
321 { label = "width " ++ String.fromInt val ++ "px" ++ minLabel ++ maxLabel
332 Expect.true "exact width is exact" (floor found.self.bbox.width == val)
333 , \_ -> Expect.true "min/max is upheld" (minMaxTest (floor found.self.bbox.width))
340 { label = "width fill-" ++ String.fromInt portion ++ minLabel ++ maxLabel
343 (Element.fillPortion portion
349 if List.member context.location [ Testable.IsNearby Testable.OnRight, Testable.IsNearby Testable.OnLeft ] then
350 Expect.true "width fill doesn't apply to onright/onleft elements" True
354 parentAvailableWidth =
355 context.parent.bbox.width - (context.self.bbox.padding.left + context.self.bbox.padding.right)
357 case context.location of
358 Testable.IsNearby _ ->
359 Expect.true "Nearby Element has fill width"
360 ((floor context.parent.bbox.width == floor context.self.bbox.width)
361 || minMaxTest (floor context.self.bbox.width)
365 Expect.true "Element within column has fill width"
366 ((floor parentAvailableWidth == floor context.self.bbox.width)
367 || minMaxTest (floor context.self.bbox.width)
371 Expect.true "Element within element has fill width" <|
372 (floor parentAvailableWidth == floor context.self.bbox.width)
373 || minMaxTest (floor context.self.bbox.width)
378 parentAvailableWidth / toFloat (List.length context.siblings + 1)
380 Expect.true "element has fill width" <|
381 (floor spacePerPortion == floor context.self.bbox.width)
382 || minMaxTest (floor context.self.bbox.width)
387 { label = "width shrink" ++ minLabel ++ maxLabel
398 -- TODO: add margin values to widths
403 |> List.map childWidth
407 context.self.bbox.padding.left + context.self.bbox.padding.right
410 toFloat context.parentSpacing * (toFloat (List.length context.children) - 1)
412 if totalChildren == 0 then
413 -- TODO: The issue is that we have a hard time measuring `text` elements
414 -- So if a element has a text child, then it's width isn't going to show up in the system.
415 expectRoundedEquality context.self.bbox.width context.self.bbox.width
418 -- This fails if this element is actually a column
419 -- So we need to capture what this element is in order to do this calculation.
420 expectRoundedEquality (totalChildren + horizontalPadding + spacingValue) context.self.bbox.width
424heightHelper maybeMin maybeMax len =
432 l |> Element.minimum minPx
440 l |> Element.maximum maxPx
448 " min:" ++ String.fromInt i
456 " max:" ++ String.fromInt i
458 minMaxTest actualheight =
459 case ( maybeMin, maybeMax ) of
460 ( Nothing, Nothing ) ->
463 ( Just lower, Nothing ) ->
464 lower <= actualheight
466 ( Just lower, Just higher ) ->
467 lower <= actualheight && actualheight <= higher
469 ( Nothing, Just higher ) ->
470 actualheight <= higher
474 heightHelper (Just m) maybeMax newLen
477 heightHelper maybeMin (Just m) newLen
480 -- Pixel values should ignore min and max?
482 { label = "height " ++ String.fromInt val ++ "px" ++ minLabel ++ maxLabel
493 Expect.true ("exact height is exact: " ++ String.fromInt (floor found.self.bbox.height) ++ "," ++ String.fromInt val)
494 (floor found.self.bbox.height == val)
496 Expect.true "min/max holds true"
497 (minMaxTest (floor found.self.bbox.height))
504 { label = "height fill-" ++ String.fromInt portion ++ minLabel ++ maxLabel
507 (Element.fillPortion portion
513 if List.member context.location [ Testable.IsNearby Testable.Above, Testable.IsNearby Testable.Below ] then
514 Expect.true "height fill doesn't apply to above/below elements" True
518 parentAvailableHeight =
519 context.parent.bbox.height - (context.self.bbox.padding.top + context.self.bbox.padding.bottom)
521 case context.location of
522 Testable.IsNearby _ ->
523 Expect.true "Nearby Element has fill height"
524 ((floor context.parent.bbox.height == floor context.self.bbox.height)
525 || minMaxTest (floor context.self.bbox.height)
529 Expect.true "Element within column has fill height"
530 ((floor parentAvailableHeight == floor context.self.bbox.height)
531 || minMaxTest (floor context.self.bbox.height)
535 Expect.true "Element within el has fill height" <|
536 (floor parentAvailableHeight == floor context.self.bbox.height)
537 || minMaxTest (floor context.self.bbox.height)
542 parentAvailableHeight / toFloat (List.length context.siblings + 1)
544 Expect.true "el has fill height" <|
545 (floor spacePerPortion == floor context.self.bbox.height)
546 || minMaxTest (floor context.self.bbox.height)
551 { label = "height shrink" ++ minLabel ++ maxLabel
562 -- TODO: add margin values to heights
567 |> List.map childWidth
571 context.self.bbox.padding.top + context.self.bbox.padding.bottom
574 toFloat context.parentSpacing * (toFloat (List.length context.children) - 1)
576 if totalChildren == 0 then
577 -- TODO: The issue is that we have a hard time measuring `text` elements
578 -- So if a element has a text child, then it's height isn't going to show up in the system.
579 expectRoundedEquality context.self.bbox.height context.self.bbox.height
582 -- This fails if this element is actually a column
583 -- So we need to capture what this element is in order to do this calculation.
584 expectRoundedEquality (totalChildren + verticalPadding + spacingValue) context.self.bbox.height
588width : Length -> Testable.Attr msg
590 widthHelper Nothing Nothing len
593height : Length -> Testable.Attr msg
595 heightHelper Nothing Nothing len
598spacing : Int -> Testable.Attr msg
601 [ Testable.Spacing space
602 , Testable.LabeledTest
603 { label = "spacing: " ++ String.fromInt space
604 , attr = Element.spacing space
608 findDistance child total =
615 - otherChild.bbox.right
620 - otherChild.bbox.bottom
622 [ if horizontal > 0 then
627 , if vertical > 0 then
638 List.foldl findDistance [] found.children
643 if not (x >= space) then
653 ("All children are at least "
654 ++ String.fromInt space
656 ++ Debug.toString allAreSpaced
664{-| alignLeft needs to account for
667 - elements to the left
670in order to calculate the expected result.
672Also need parent rendering context if this is to work with wrapped rows in the future.
677alignLeft : Testable.Attr msg
680 { label = "alignLeft"
681 , attr = Element.alignLeft
684 if List.member found.location [ Testable.IsNearby Testable.OnLeft, Testable.IsNearby Testable.OnRight ] then
685 Expect.true "alignLeft doesn't apply to elements that are onLeft or onRight" True
688 List.member found.location
689 [ Testable.IsNearby Testable.InFront
690 , Testable.IsNearby Testable.Behind
691 , Testable.IsNearby Testable.Above
692 , Testable.IsNearby Testable.Below
695 expectRoundedEquality
697 found.parent.bbox.left
699 else if List.length found.siblings == 0 then
700 expectRoundedEquality
702 (found.parent.bbox.left + found.parent.bbox.padding.left)
705 case found.location of
709 List.filter (\x -> x.bbox.right < found.self.bbox.left) found.siblings
712 toFloat (List.length siblingsOnLeft * found.parentSpacing)
716 |> List.map (.width << .bbox)
719 expectRoundedEquality
721 (found.parent.bbox.left + (found.parent.bbox.padding.left + widthsOnLeft + spacings))
724 expectRoundedEquality
726 (found.parent.bbox.left + found.parent.bbox.padding.left)
731centerX : Testable.Attr msg
735 , attr = Element.centerX
741 found.self.bbox.left + (found.self.bbox.width / 2)
745 found.parent.bbox.left + (found.parent.bbox.width / 2)
747 if List.member found.location [ Testable.IsNearby Testable.OnRight, Testable.IsNearby Testable.OnLeft ] then
748 Expect.true "centerX doesn't apply to elements that are onLeft or onRight" True
750 else if List.length found.siblings == 0 then
751 expectRoundedEquality
756 case found.location of
760 List.filter (\x -> x.bbox.right < found.self.bbox.left) found.siblings
763 List.filter (\x -> x.bbox.left > found.self.bbox.right) found.siblings
768 |> List.map (.width << .bbox)
770 |> (\x -> x + (toFloat (List.length siblingsOnLeft) * toFloat found.parentSpacing))
774 |> List.map (.width << .bbox)
776 |> (\x -> x + (toFloat (List.length siblingsOnRight) * toFloat found.parentSpacing))
778 expectedCenter : Float
780 found.parent.bbox.left
782 + ((found.parent.bbox.width - (widthsOnRight + widthsOnLeft))
786 expectRoundedEquality
791 expectRoundedEquality selfCenter parentCenter
796alignRight : Testable.Attr msg
799 { label = "alignRight"
800 , attr = Element.alignRight
803 if List.member found.location [ Testable.IsNearby Testable.OnLeft, Testable.IsNearby Testable.OnRight ] then
804 Expect.true "alignRight doesn't apply to elements that are onLeft or onRight" True
807 List.member found.location
808 [ Testable.IsNearby Testable.InFront
809 , Testable.IsNearby Testable.Behind
810 , Testable.IsNearby Testable.Above
811 , Testable.IsNearby Testable.Below
814 expectRoundedEquality
815 found.self.bbox.right
816 found.parent.bbox.right
818 else if List.length found.siblings == 0 then
819 expectRoundedEquality
820 found.self.bbox.right
821 (found.parent.bbox.right + found.parent.bbox.padding.right)
824 case found.location of
828 List.filter (\x -> x.bbox.left > found.self.bbox.right) found.siblings
831 toFloat (List.length siblingsOnRight * found.parentSpacing)
835 |> List.map (.width << .bbox)
838 expectRoundedEquality
839 found.self.bbox.right
840 (found.parent.bbox.right - (found.parent.bbox.padding.right + widthsOnRight + spacings))
843 expectRoundedEquality
844 found.self.bbox.right
845 (found.parent.bbox.right + found.parent.bbox.padding.right)
850alignTop : Testable.Attr msg
854 , attr = Element.alignTop
857 if List.member found.location [ Testable.IsNearby Testable.Above, Testable.IsNearby Testable.Below ] then
858 Expect.true "alignTop doesn't apply to elements that are above or below" True
861 List.member found.location
862 [ Testable.IsNearby Testable.InFront
863 , Testable.IsNearby Testable.Behind
864 , Testable.IsNearby Testable.OnRight
865 , Testable.IsNearby Testable.OnLeft
868 expectRoundedEquality
870 found.parent.bbox.top
872 else if List.length found.siblings == 0 then
873 expectRoundedEquality
875 (found.parent.bbox.top + found.parent.bbox.padding.top)
878 case found.location of
882 List.filter (\x -> x.bbox.bottom < found.self.bbox.top) found.siblings
885 toFloat (List.length siblingsAbove * found.parentSpacing)
889 |> List.map (.height << .bbox)
892 expectRoundedEquality
894 (found.parent.bbox.top + (found.parent.bbox.padding.top + heightsAbove + spacings))
897 expectRoundedEquality
899 found.parent.bbox.top
904alignBottom : Testable.Attr msg
907 { label = "alignBottom"
908 , attr = Element.alignBottom
911 if List.member found.location [ Testable.IsNearby Testable.Above, Testable.IsNearby Testable.Below ] then
912 Expect.true "alignBottom doesn't apply to elements that are above or below" True
915 List.member found.location
916 [ Testable.IsNearby Testable.InFront
917 , Testable.IsNearby Testable.Behind
918 , Testable.IsNearby Testable.OnRight
919 , Testable.IsNearby Testable.OnLeft
922 expectRoundedEquality
923 found.self.bbox.bottom
924 found.parent.bbox.bottom
926 else if List.length found.siblings == 0 then
927 expectRoundedEquality
928 found.self.bbox.bottom
929 (found.parent.bbox.bottom + found.parent.bbox.padding.bottom)
932 case found.location of
936 List.filter (\x -> x.bbox.top > found.self.bbox.bottom) found.siblings
939 toFloat (List.length siblingsBelow * found.parentSpacing)
943 |> List.map (.height << .bbox)
946 expectRoundedEquality
947 found.self.bbox.bottom
948 (found.parent.bbox.bottom - (found.parent.bbox.padding.bottom + heightsBelow + spacings))
951 expectRoundedEquality
952 found.self.bbox.bottom
953 (found.parent.bbox.bottom + found.parent.bbox.padding.bottom)
957expectRoundedEquality x y =
958 Expect.true ("within 1 of each other " ++ String.fromFloat x ++ ":" ++ String.fromFloat y)
963centerY : Testable.Attr msg
967 , attr = Element.centerY
972 found.self.bbox.top + (found.self.bbox.height / 2)
975 found.parent.bbox.top + (found.parent.bbox.height / 2)
977 if List.member found.location [ Testable.IsNearby Testable.Above, Testable.IsNearby Testable.Below ] then
978 Expect.true "centerY doesn't apply to elements that are above or below" True
980 else if List.length found.siblings == 0 then
981 expectRoundedEquality
986 case found.location of
990 List.filter (\x -> x.bbox.bottom < found.self.bbox.top) found.siblings
993 List.filter (\x -> x.bbox.top > found.self.bbox.bottom) found.siblings
998 |> List.map (.height << .bbox)
1000 |> (\x -> x + (toFloat (List.length siblingsOnTop) * toFloat found.parentSpacing))
1004 |> List.map (.height << .bbox)
1006 |> (\x -> x + (toFloat (List.length siblingsBelow) * toFloat found.parentSpacing))
1008 expectedCenter : Float
1010 found.parent.bbox.top
1012 + ((found.parent.bbox.height - (heightsBelow + heightsAbove))
1016 expectRoundedEquality
1021 expectRoundedEquality selfCenter parentCenter
1026above : Testable.Element msg -> Testable.Attr msg
1029 { location = Testable.Above
1034 expectRoundedEquality found.self.bbox.bottom found.parent.bbox.top
1039below : Testable.Element msg -> Testable.Attr msg
1042 { location = Testable.Below
1047 expectRoundedEquality found.self.bbox.top found.parent.bbox.bottom
1052onRight : Testable.Element msg -> Testable.Attr msg
1055 { location = Testable.OnRight
1060 expectRoundedEquality found.self.bbox.left found.parent.bbox.right
1065onLeft : Testable.Element msg -> Testable.Attr msg
1068 { location = Testable.OnLeft
1073 expectRoundedEquality found.self.bbox.right found.parent.bbox.left
1078 vs (round x) (round y) || vs (floor x) (floor y)
1082inFront : Testable.Element msg -> Testable.Attr msg
1085 { location = Testable.InFront
1093withinHelper found _ =
1096 if found.self.bbox.width > found.parent.bbox.width then
1097 [ compare found.self.bbox.right (<=) found.parent.bbox.right
1098 || compare found.self.bbox.left (>=) found.parent.bbox.left
1102 [ compare found.self.bbox.right (<=) found.parent.bbox.right
1103 , compare found.self.bbox.left (>=) found.parent.bbox.left
1107 if found.self.bbox.width > found.parent.bbox.width then
1108 [ compare found.self.bbox.top (>=) found.parent.bbox.top
1109 || compare found.self.bbox.bottom (<=) found.parent.bbox.bottom
1113 [ compare found.self.bbox.top (>=) found.parent.bbox.top
1114 , compare found.self.bbox.bottom (<=) found.parent.bbox.bottom
1117 Expect.true "within the confines of the parent"
1118 (List.all ((==) True)
1128behindContent : Testable.Element msg -> Testable.Attr msg
1129behindContent element =
1131 { location = Testable.Behind
1133 , 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