mirror of
https://github.com/mdgriffith/elm-ui.git
synced 2024-11-22 11:52:09 +03:00
redo testing interface so it's actually readable by a human.
This commit is contained in:
parent
510b32ae82
commit
639efbb5ab
@ -265,31 +265,29 @@ function renderEnvName(env) {
|
||||
return `${env.platform}, ${env.browser} ${env.browserVersion}`;
|
||||
}
|
||||
|
||||
function print_results(label, results) {
|
||||
function print_results(label, tests) {
|
||||
var total_passed = 0;
|
||||
var total_failed = 0;
|
||||
var i;
|
||||
if (program.verbose) {
|
||||
console.log(label);
|
||||
}
|
||||
for (i = 0; i < results.length; i++) {
|
||||
for (i = 0; i < tests.length; i++) {
|
||||
var passed = 0;
|
||||
var failed = 0;
|
||||
for (j = 0; j < results[i].results.length; j++) {
|
||||
if (results[i].results[j][1] == null) {
|
||||
for (j = 0; j < tests[i].results.length; j++) {
|
||||
if (tests[i].results[j].passing) {
|
||||
passed = passed + 1;
|
||||
} else {
|
||||
if (failed == 0) {
|
||||
if (!program.verbose) {
|
||||
console.log(label);
|
||||
}
|
||||
console.log(results[i].label);
|
||||
console.log(tests[i].label);
|
||||
}
|
||||
failed = failed + 1;
|
||||
console.log(
|
||||
" " + chalk.red("fail") + " -> " + results[i].results[j][0]
|
||||
);
|
||||
console.log(" " + results[i].results[j][1].description);
|
||||
console.log(" " + chalk.red("fail") + " ->");
|
||||
console.log(" " + tests[i].results[j][1].description);
|
||||
}
|
||||
}
|
||||
total_passed = total_passed + passed;
|
||||
@ -300,7 +298,7 @@ function print_results(label, results) {
|
||||
console.log(chalk.red(` ${failed} tests failed`));
|
||||
console.log();
|
||||
} else if (program.verbose) {
|
||||
console.log(results[i].label + chalk.green(` ${passed} tests passed`));
|
||||
console.log(tests[i].label + chalk.green(` ${passed} tests passed`));
|
||||
}
|
||||
}
|
||||
if (total_failed == 0) {
|
||||
|
@ -1,105 +1,107 @@
|
||||
<!DOCTYPE HTML>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Rendering Benchmark Viewer</title>
|
||||
<script>
|
||||
${compiled_elm_code}
|
||||
</script>
|
||||
</head>
|
||||
<style>
|
||||
</style>
|
||||
<body id="root"></body>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var app = Elm.Tests.Run.init();
|
||||
|
||||
var test_results = "waiting.."
|
||||
|
||||
app.ports.report.subscribe(function (results) {
|
||||
test_results = results;
|
||||
})
|
||||
|
||||
app.ports.analyze.subscribe(function (ids) {
|
||||
// ids : List String
|
||||
var idsLength = ids.length;
|
||||
var results = [];
|
||||
for (var i = 0; i < idsLength; i++) {
|
||||
var id = ids[i];
|
||||
var element = document.getElementById(id);
|
||||
if (element == null) {
|
||||
console.log("id " + id + " not found");
|
||||
}
|
||||
var style = getStyle(element);
|
||||
var bbox = getBoundingBox(element);
|
||||
|
||||
var visible = isVisible(id, bbox);
|
||||
|
||||
|
||||
var result = { "bbox": bbox, "style": style, "id": id, "isVisible": visible };
|
||||
results.push(result);
|
||||
|
||||
}
|
||||
app.ports.styles.send(results);
|
||||
});
|
||||
|
||||
function isVisible(id, bbox) {
|
||||
var current = document.getElementById(id);
|
||||
var result = 0;
|
||||
if (current == document.elementFromPoint(bbox['left'], bbox['top'])) {
|
||||
result++;
|
||||
}
|
||||
if (current == document.elementFromPoint(bbox['left'], bbox['bottom'] - 1)) {
|
||||
result++;
|
||||
}
|
||||
if (current == document.elementFromPoint(bbox['right'] - 1, bbox['top'])) {
|
||||
result++;
|
||||
}
|
||||
if (current == document.elementFromPoint(bbox['right'] - 1, bbox['bottom'] - 1)) {
|
||||
result++;
|
||||
}
|
||||
|
||||
|
||||
if (result == 4) {
|
||||
return true;
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function getStyle(element) {
|
||||
var props = []
|
||||
var style = window.getComputedStyle(element);
|
||||
for (var i = style.length; i--;) {
|
||||
var name = style.item(i);
|
||||
var value = style.getPropertyValue(name);
|
||||
props.push([name, value]);
|
||||
}
|
||||
return props;
|
||||
}
|
||||
|
||||
function getBoundingBox(element) {
|
||||
var bbox = element.getBoundingClientRect();
|
||||
var style = window.getComputedStyle(element, null);
|
||||
|
||||
var padding = {
|
||||
'top': parseFloat(style.getPropertyValue('padding-top'))
|
||||
, 'bottom': parseFloat(style.getPropertyValue('padding-bottom'))
|
||||
, 'left': parseFloat(style.getPropertyValue('padding-left'))
|
||||
, 'right': parseFloat(style.getPropertyValue('padding-right'))
|
||||
};
|
||||
|
||||
return {
|
||||
'top': bbox.top
|
||||
, 'bottom': bbox.bottom
|
||||
, 'left': bbox.left
|
||||
, 'right': bbox.right
|
||||
, 'width': bbox.width
|
||||
, 'height': bbox.height
|
||||
, 'padding': padding
|
||||
}
|
||||
}
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Rendering Benchmark Viewer</title>
|
||||
<script>
|
||||
${compiled_elm_code}
|
||||
</script>
|
||||
</html>
|
||||
</head>
|
||||
<style></style>
|
||||
<body id="root"></body>
|
||||
|
||||
<script type="text/javascript">
|
||||
var app = Elm.Tests.Run.init();
|
||||
|
||||
var test_results = "waiting..";
|
||||
|
||||
app.ports.report.subscribe(function (results) {
|
||||
// these are extracted by the script that runs the browser automation.
|
||||
test_results = results;
|
||||
});
|
||||
|
||||
app.ports.analyze.subscribe(function (ids) {
|
||||
// ids : List String
|
||||
var idsLength = ids.length;
|
||||
var results = [];
|
||||
for (var i = 0; i < idsLength; i++) {
|
||||
var id = ids[i];
|
||||
var element = document.getElementById(id);
|
||||
if (element == null) {
|
||||
console.log("id " + id + " not found");
|
||||
}
|
||||
var style = getStyle(element);
|
||||
var bbox = getBoundingBox(element);
|
||||
|
||||
var visible = isVisible(id, bbox);
|
||||
|
||||
var result = { bbox: bbox, style: style, id: id, isVisible: visible };
|
||||
results.push(result);
|
||||
}
|
||||
app.ports.styles.send(results);
|
||||
});
|
||||
|
||||
function isVisible(id, bbox) {
|
||||
var current = document.getElementById(id);
|
||||
var result = 0;
|
||||
if (current == document.elementFromPoint(bbox["left"], bbox["top"])) {
|
||||
result++;
|
||||
}
|
||||
if (
|
||||
current == document.elementFromPoint(bbox["left"], bbox["bottom"] - 1)
|
||||
) {
|
||||
result++;
|
||||
}
|
||||
if (
|
||||
current == document.elementFromPoint(bbox["right"] - 1, bbox["top"])
|
||||
) {
|
||||
result++;
|
||||
}
|
||||
if (
|
||||
current ==
|
||||
document.elementFromPoint(bbox["right"] - 1, bbox["bottom"] - 1)
|
||||
) {
|
||||
result++;
|
||||
}
|
||||
|
||||
if (result == 4) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getStyle(element) {
|
||||
var props = [];
|
||||
var style = window.getComputedStyle(element);
|
||||
for (var i = style.length; i--; ) {
|
||||
var name = style.item(i);
|
||||
var value = style.getPropertyValue(name);
|
||||
props.push([name, value]);
|
||||
}
|
||||
return props;
|
||||
}
|
||||
|
||||
function getBoundingBox(element) {
|
||||
var bbox = element.getBoundingClientRect();
|
||||
var style = window.getComputedStyle(element, null);
|
||||
|
||||
var padding = {
|
||||
top: parseFloat(style.getPropertyValue("padding-top")),
|
||||
bottom: parseFloat(style.getPropertyValue("padding-bottom")),
|
||||
left: parseFloat(style.getPropertyValue("padding-left")),
|
||||
right: parseFloat(style.getPropertyValue("padding-right")),
|
||||
};
|
||||
|
||||
return {
|
||||
top: bbox.top,
|
||||
bottom: bbox.bottom,
|
||||
left: bbox.left,
|
||||
right: bbox.right,
|
||||
width: bbox.width,
|
||||
height: bbox.height,
|
||||
padding: padding,
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</html>
|
||||
|
@ -1,2 +1,2 @@
|
||||
|
||||
elm-live cases/open/InFrontSize.elm --open --dir=view -- --output=view/elm.js --debug
|
||||
elm-live cases/open/WeirdCentering.elm --dir=view -- --output=view/elm.js --debug
|
@ -4,40 +4,32 @@ module Testable exposing
|
||||
, Element(..)
|
||||
, Found
|
||||
, LayoutContext(..)
|
||||
, LayoutExpectation(..)
|
||||
, LayoutTest
|
||||
, Location(..)
|
||||
, Style
|
||||
, Surroundings
|
||||
, addAttribute
|
||||
, applyLabels
|
||||
, compareFormattedColor
|
||||
, createAttributeTest
|
||||
, createTest
|
||||
, equal
|
||||
, formatColor
|
||||
, formatColorWithAlpha
|
||||
, getElementId
|
||||
, getIds
|
||||
, getSpacing
|
||||
, idAttr
|
||||
, levelToString
|
||||
, render
|
||||
, renderAttribute
|
||||
, renderElement
|
||||
, runTests
|
||||
, toTest
|
||||
, toElement
|
||||
, toHtml
|
||||
, todo
|
||||
, true
|
||||
)
|
||||
|
||||
{-| -}
|
||||
|
||||
import Dict exposing (Dict)
|
||||
import Element exposing (Color)
|
||||
import Expect
|
||||
import Html exposing (Html)
|
||||
import Html.Attributes
|
||||
import Internal.Model as Internal
|
||||
import Random
|
||||
import Test exposing (Test)
|
||||
import Test.Runner
|
||||
import Test.Runner.Failure
|
||||
|
||||
|
||||
type Element msg
|
||||
@ -52,18 +44,20 @@ type Element msg
|
||||
|
||||
type Attr msg
|
||||
= Attr (Element.Attribute msg)
|
||||
| AttrTest (Surroundings -> Test)
|
||||
| AttrTest
|
||||
{ test : Surroundings -> List LayoutExpectation
|
||||
, label : String
|
||||
}
|
||||
| Batch (List (Attr msg))
|
||||
| Spacing Int
|
||||
| Nearby
|
||||
{ location : Location
|
||||
, element : Element msg
|
||||
, test : Surroundings -> () -> Expect.Expectation
|
||||
, test : Surroundings -> List LayoutExpectation
|
||||
, label : String
|
||||
}
|
||||
| Label String
|
||||
| LabeledTest
|
||||
{ test : Surroundings -> () -> Expect.Expectation
|
||||
{ test : Surroundings -> List LayoutExpectation
|
||||
, label : String
|
||||
, attr : Element.Attribute msg
|
||||
}
|
||||
@ -125,6 +119,46 @@ type alias BoundingBox =
|
||||
}
|
||||
|
||||
|
||||
type LayoutExpectation
|
||||
= Expect
|
||||
{ description : String
|
||||
, result : Bool
|
||||
}
|
||||
| Todo String
|
||||
|
||||
|
||||
type alias LayoutTest =
|
||||
{ elementDomId : String
|
||||
, label : String
|
||||
, expectations : List LayoutExpectation
|
||||
}
|
||||
|
||||
|
||||
|
||||
{- Expectations -}
|
||||
|
||||
|
||||
equal : a -> a -> LayoutExpectation
|
||||
equal one two =
|
||||
Expect
|
||||
{ description = "Are equal"
|
||||
, result = one == two
|
||||
}
|
||||
|
||||
|
||||
true : String -> Bool -> LayoutExpectation
|
||||
true label passing =
|
||||
Expect
|
||||
{ description = label
|
||||
, result = passing
|
||||
}
|
||||
|
||||
|
||||
todo : String -> LayoutExpectation
|
||||
todo =
|
||||
Todo
|
||||
|
||||
|
||||
|
||||
{- Retrieve Ids -}
|
||||
|
||||
@ -183,8 +217,13 @@ getElementId level el =
|
||||
{- Render as Html -}
|
||||
|
||||
|
||||
render : Element msg -> Html msg
|
||||
render el =
|
||||
toElement : Element msg -> Element.Element msg
|
||||
toElement el =
|
||||
renderElement [ 0, 0 ] el
|
||||
|
||||
|
||||
toHtml : Element msg -> Html msg
|
||||
toHtml el =
|
||||
Element.layout [ idAttr "0" ] <|
|
||||
renderElement [ 0, 0 ] el
|
||||
|
||||
@ -253,9 +292,6 @@ renderAttribute level attrIndex attr =
|
||||
Spacing _ ->
|
||||
[]
|
||||
|
||||
Label _ ->
|
||||
[]
|
||||
|
||||
Nearby { location, element } ->
|
||||
case location of
|
||||
Above ->
|
||||
@ -288,30 +324,35 @@ renderAttribute level attrIndex attr =
|
||||
{- Convert to Test -}
|
||||
|
||||
|
||||
toTest : String -> Dict String Found -> Element msg -> Test
|
||||
toTest label harvested el =
|
||||
runTests : Dict String Found -> Element msg -> List LayoutTest
|
||||
runTests harvested el =
|
||||
let
|
||||
maybeFound =
|
||||
Dict.get "se-0" harvested
|
||||
in
|
||||
case maybeFound of
|
||||
Nothing ->
|
||||
Test.describe label
|
||||
[ Test.test "Find Root" <|
|
||||
\_ -> Expect.fail "unable to find root"
|
||||
]
|
||||
[ { elementDomId = "se-0"
|
||||
, label = "Finding root element"
|
||||
, expectations =
|
||||
[ Expect
|
||||
{ description = "Locating root element for rendering tests"
|
||||
, result = False
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
Just root ->
|
||||
Test.describe label <|
|
||||
createTest
|
||||
{ siblings = []
|
||||
, parent = root
|
||||
, cache = harvested
|
||||
, parentSpacing = 0
|
||||
, level = [ 0, 0 ]
|
||||
, element = el
|
||||
, location = InEl
|
||||
}
|
||||
createTest
|
||||
{ siblings = []
|
||||
, parent = root
|
||||
, cache = harvested
|
||||
, parentSpacing = 0
|
||||
, level = [ 0, 0 ]
|
||||
, element = el
|
||||
, location = InEl
|
||||
}
|
||||
|
||||
|
||||
levelToString : List Int -> String
|
||||
@ -331,7 +372,7 @@ createTest :
|
||||
, location : LayoutContext
|
||||
, parentSpacing : Int
|
||||
}
|
||||
-> List Test
|
||||
-> List LayoutTest
|
||||
createTest { siblings, parent, cache, level, element, location, parentSpacing } =
|
||||
let
|
||||
spacing =
|
||||
@ -341,7 +382,7 @@ createTest { siblings, parent, cache, level, element, location, parentSpacing }
|
||||
id =
|
||||
levelToString level
|
||||
|
||||
testChildren : Found -> List (Element msg) -> List Test
|
||||
testChildren : Found -> List (Element msg) -> List LayoutTest
|
||||
testChildren found children =
|
||||
let
|
||||
childrenFound =
|
||||
@ -369,13 +410,13 @@ createTest { siblings, parent, cache, level, element, location, parentSpacing }
|
||||
{ a
|
||||
| index : Int
|
||||
, previous : List Found
|
||||
, tests : List Test
|
||||
, tests : List LayoutTest
|
||||
, upcoming : List Found
|
||||
}
|
||||
->
|
||||
{ index : Int
|
||||
, previous : List Found
|
||||
, tests : List Test
|
||||
, tests : List LayoutTest
|
||||
, upcoming : List Found
|
||||
}
|
||||
applyChildTest found child childTest =
|
||||
@ -439,7 +480,7 @@ createTest { siblings, parent, cache, level, element, location, parentSpacing }
|
||||
rest
|
||||
}
|
||||
|
||||
tests : Found -> List (Attr msg) -> List (Element msg) -> List Test
|
||||
tests : Found -> List (Attr msg) -> List (Element msg) -> List LayoutTest
|
||||
tests self attributes children =
|
||||
let
|
||||
findBBox elem ( i, gathered ) =
|
||||
@ -479,7 +520,6 @@ createTest { siblings, parent, cache, level, element, location, parentSpacing }
|
||||
|
||||
attributeTests =
|
||||
attributes
|
||||
|> applyLabels
|
||||
|> List.indexedMap
|
||||
-- Found -> Dict String Found -> List Int -> Int -> Surroundings -> Attr msg -> List Test
|
||||
(\i attr ->
|
||||
@ -511,7 +551,16 @@ createTest { siblings, parent, cache, level, element, location, parentSpacing }
|
||||
[]
|
||||
|
||||
_ ->
|
||||
[ Test.test ("Unable to find " ++ id) (always <| Expect.fail "failed id lookup") ]
|
||||
[ { elementDomId = id
|
||||
, label = "Finding element in DOM"
|
||||
, expectations =
|
||||
[ Expect
|
||||
{ description = "Locating element for rendering test"
|
||||
, result = False
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
Just self ->
|
||||
case element of
|
||||
@ -537,59 +586,31 @@ createTest { siblings, parent, cache, level, element, location, parentSpacing }
|
||||
[]
|
||||
|
||||
|
||||
applyLabels : List (Attr msg) -> List (Attr msg)
|
||||
applyLabels attrs =
|
||||
let
|
||||
toLabel attr =
|
||||
case attr of
|
||||
Label label ->
|
||||
Just label
|
||||
|
||||
_ ->
|
||||
Nothing
|
||||
|
||||
newLabels =
|
||||
attrs
|
||||
|> List.filterMap toLabel
|
||||
|> String.join ", "
|
||||
|
||||
applyLabel newLabel attr =
|
||||
case attr of
|
||||
LabeledTest labeled ->
|
||||
LabeledTest
|
||||
{ labeled
|
||||
| label =
|
||||
if newLabel == "" then
|
||||
labeled.label
|
||||
|
||||
else
|
||||
newLabel ++ ", " ++ labeled.label
|
||||
}
|
||||
|
||||
x ->
|
||||
x
|
||||
in
|
||||
List.map (applyLabel newLabels) attrs
|
||||
|
||||
|
||||
createAttributeTest : Found -> Dict String Found -> List Int -> Int -> Surroundings -> Attr msg -> List Test
|
||||
createAttributeTest :
|
||||
Found
|
||||
-> Dict String Found
|
||||
-> List Int
|
||||
-> Int
|
||||
-> Surroundings
|
||||
-> Attr msg
|
||||
-> List LayoutTest
|
||||
createAttributeTest parent cache level attrIndex surroundings attr =
|
||||
let
|
||||
indexLabel =
|
||||
levelToString (attrIndex :: level)
|
||||
domId =
|
||||
"#" ++ levelToString level
|
||||
in
|
||||
case attr of
|
||||
Attr _ ->
|
||||
[]
|
||||
|
||||
Label _ ->
|
||||
[]
|
||||
|
||||
Spacing _ ->
|
||||
[]
|
||||
|
||||
AttrTest test ->
|
||||
[ test surroundings
|
||||
AttrTest details ->
|
||||
[ { elementDomId = domId
|
||||
, label = details.label
|
||||
, expectations = details.test surroundings
|
||||
}
|
||||
]
|
||||
|
||||
Nearby nearby ->
|
||||
@ -600,7 +621,15 @@ createAttributeTest parent cache level attrIndex surroundings attr =
|
||||
, parentSpacing = 0
|
||||
, level = attrIndex :: -1 :: level
|
||||
, location = IsNearby nearby.location
|
||||
, element = addAttribute (AttrTest (\context -> Test.test (nearby.label ++ " #" ++ indexLabel) (nearby.test context))) nearby.element
|
||||
, element =
|
||||
addAttribute
|
||||
(AttrTest
|
||||
{ label = nearby.label
|
||||
, test =
|
||||
nearby.test
|
||||
}
|
||||
)
|
||||
nearby.element
|
||||
}
|
||||
|
||||
Batch batch ->
|
||||
@ -609,7 +638,10 @@ createAttributeTest parent cache level attrIndex surroundings attr =
|
||||
|> List.concat
|
||||
|
||||
LabeledTest { label, test } ->
|
||||
[ Test.test (label ++ " #" ++ indexLabel) (test surroundings)
|
||||
[ { elementDomId = domId
|
||||
, label = label
|
||||
, expectations = test surroundings
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@ -638,46 +670,43 @@ addAttribute attr el =
|
||||
Text str
|
||||
|
||||
|
||||
runTests :
|
||||
Random.Seed
|
||||
-> Test
|
||||
->
|
||||
List
|
||||
( String
|
||||
, Maybe
|
||||
{ given : Maybe String
|
||||
, description : String
|
||||
, reason : Test.Runner.Failure.Reason
|
||||
}
|
||||
)
|
||||
runTests seed tests =
|
||||
let
|
||||
run runner =
|
||||
let
|
||||
ran =
|
||||
List.map Test.Runner.getFailureReason (runner.run ())
|
||||
in
|
||||
List.map2 Tuple.pair runner.labels ran
|
||||
|
||||
results =
|
||||
case Test.Runner.fromTest 100 seed tests of
|
||||
Test.Runner.Plain rnrs ->
|
||||
List.map run rnrs
|
||||
|
||||
Test.Runner.Only rnrs ->
|
||||
List.map run rnrs
|
||||
|
||||
Test.Runner.Skipping rnrs ->
|
||||
List.map run rnrs
|
||||
|
||||
Test.Runner.Invalid invalid ->
|
||||
let
|
||||
_ =
|
||||
Debug.log "Invalid tests" invalid
|
||||
in
|
||||
[]
|
||||
in
|
||||
List.concat results
|
||||
-- runTests :
|
||||
-- Random.Seed
|
||||
-- -> Test
|
||||
-- ->
|
||||
-- List
|
||||
-- ( String
|
||||
-- , Maybe
|
||||
-- { given : Maybe String
|
||||
-- , description : String
|
||||
-- , reason : Test.Runner.Failure.Reason
|
||||
-- }
|
||||
-- )
|
||||
-- runTests seed tests =
|
||||
-- let
|
||||
-- run runner =
|
||||
-- let
|
||||
-- ran =
|
||||
-- List.map Test.Runner.getFailureReason (runner.run ())
|
||||
-- in
|
||||
-- List.map2 Tuple.pair runner.labels ran
|
||||
-- results =
|
||||
-- case Test.Runner.fromTest 100 seed tests of
|
||||
-- Test.Runner.Plain rnrs ->
|
||||
-- List.map run rnrs
|
||||
-- Test.Runner.Only rnrs ->
|
||||
-- List.map run rnrs
|
||||
-- Test.Runner.Skipping rnrs ->
|
||||
-- List.map run rnrs
|
||||
-- Test.Runner.Invalid invalid ->
|
||||
-- let
|
||||
-- _ =
|
||||
-- Debug.log "Invalid tests" invalid
|
||||
-- in
|
||||
-- []
|
||||
-- in
|
||||
-- List.concat results
|
||||
|
||||
|
||||
compareFormattedColor : Color -> String -> Bool
|
||||
|
@ -23,6 +23,8 @@ module Testable.Element exposing
|
||||
, maximum
|
||||
, minimum
|
||||
, moveDown
|
||||
, moveLeft
|
||||
, moveRight
|
||||
, moveUp
|
||||
, none
|
||||
, onLeft
|
||||
@ -104,6 +106,12 @@ textColumn =
|
||||
Testable.TextColumn
|
||||
|
||||
|
||||
{-| Old labeling mechanism that i removed to hastily
|
||||
-}
|
||||
label str =
|
||||
Testable.Batch []
|
||||
|
||||
|
||||
moveUp x =
|
||||
Testable.Attr (Element.moveUp x)
|
||||
|
||||
@ -112,6 +120,14 @@ moveDown x =
|
||||
Testable.Attr (Element.moveDown x)
|
||||
|
||||
|
||||
moveRight x =
|
||||
Testable.Attr (Element.moveRight x)
|
||||
|
||||
|
||||
moveLeft x =
|
||||
Testable.Attr (Element.moveLeft x)
|
||||
|
||||
|
||||
type Length
|
||||
= Px Int
|
||||
| Fill Int
|
||||
@ -156,11 +172,6 @@ fillPortion =
|
||||
Fill
|
||||
|
||||
|
||||
label : String -> Testable.Attr msg
|
||||
label =
|
||||
Testable.Label
|
||||
|
||||
|
||||
transparent : Bool -> Testable.Attr msg
|
||||
transparent on =
|
||||
Testable.LabeledTest
|
||||
@ -172,7 +183,7 @@ transparent on =
|
||||
"opaque"
|
||||
, attr = Element.transparent on
|
||||
, test =
|
||||
\context _ ->
|
||||
\context ->
|
||||
let
|
||||
selfTransparency =
|
||||
context.self.style
|
||||
@ -186,7 +197,7 @@ transparent on =
|
||||
else
|
||||
"1"
|
||||
in
|
||||
Expect.equal value selfTransparency
|
||||
[ Testable.equal value selfTransparency ]
|
||||
}
|
||||
|
||||
|
||||
@ -197,8 +208,8 @@ isVisible =
|
||||
{ label = "is-visible"
|
||||
, attr = Element.htmlAttribute (Html.Attributes.style "not" "applicable")
|
||||
, test =
|
||||
\context _ ->
|
||||
Expect.equal context.self.isVisible True
|
||||
\context ->
|
||||
[ Testable.equal context.self.isVisible True ]
|
||||
}
|
||||
|
||||
|
||||
@ -209,14 +220,14 @@ alpha a =
|
||||
{ label = "alpha-" ++ String.fromFloat a
|
||||
, attr = Element.alpha a
|
||||
, test =
|
||||
\context _ ->
|
||||
\context ->
|
||||
let
|
||||
selfTransparency =
|
||||
context.self.style
|
||||
|> Dict.get "opacity"
|
||||
|> Maybe.withDefault "notfound"
|
||||
in
|
||||
Expect.equal (String.fromFloat a) selfTransparency
|
||||
[ Testable.equal (String.fromFloat a) selfTransparency ]
|
||||
}
|
||||
|
||||
|
||||
@ -227,8 +238,8 @@ padding pad =
|
||||
{ label = "padding " ++ String.fromInt pad
|
||||
, attr = Element.padding pad
|
||||
, test =
|
||||
\found _ ->
|
||||
Expect.true ("Padding " ++ String.fromInt pad ++ " is present")
|
||||
\found ->
|
||||
[ Testable.true ("Padding " ++ String.fromInt pad ++ " is present")
|
||||
(List.all ((==) pad)
|
||||
[ floor found.self.bbox.padding.left
|
||||
, floor found.self.bbox.padding.right
|
||||
@ -236,6 +247,7 @@ padding pad =
|
||||
, floor found.self.bbox.padding.bottom
|
||||
]
|
||||
)
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@ -246,8 +258,8 @@ paddingXY x y =
|
||||
{ label = "paddingXY " ++ String.fromInt x ++ ", " ++ String.fromInt y
|
||||
, attr = Element.paddingXY x y
|
||||
, test =
|
||||
\found _ ->
|
||||
Expect.true ("PaddingXY (" ++ String.fromInt x ++ ", " ++ String.fromInt y ++ ") is present")
|
||||
\found ->
|
||||
[ Testable.true ("PaddingXY (" ++ String.fromInt x ++ ", " ++ String.fromInt y ++ ") is present")
|
||||
(List.all ((==) x)
|
||||
[ floor found.self.bbox.padding.left
|
||||
, floor found.self.bbox.padding.right
|
||||
@ -257,6 +269,7 @@ paddingXY x y =
|
||||
, floor found.self.bbox.padding.bottom
|
||||
]
|
||||
)
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@ -326,18 +339,20 @@ widthHelper maybeMin maybeMax len =
|
||||
|> addMax
|
||||
)
|
||||
, test =
|
||||
\found _ ->
|
||||
Expect.all
|
||||
[ \_ ->
|
||||
Expect.true "exact width is exact" (floor found.self.bbox.width == val)
|
||||
, \_ -> Expect.true "min/max is upheld" (minMaxTest (floor found.self.bbox.width))
|
||||
]
|
||||
()
|
||||
\found ->
|
||||
[ Testable.true "exact width is exact" (floor found.self.bbox.width == val)
|
||||
, Testable.true "min/max is upheld" (minMaxTest (floor found.self.bbox.width))
|
||||
]
|
||||
}
|
||||
|
||||
Fill portion ->
|
||||
Testable.LabeledTest
|
||||
{ label = "width fill-" ++ String.fromInt portion ++ minLabel ++ maxLabel
|
||||
{ label =
|
||||
if portion == 1 then
|
||||
"width fill" ++ minLabel ++ maxLabel
|
||||
|
||||
else
|
||||
"width fill-" ++ String.fromInt portion ++ minLabel ++ maxLabel
|
||||
, attr =
|
||||
Element.width
|
||||
(Element.fillPortion portion
|
||||
@ -345,30 +360,30 @@ widthHelper maybeMin maybeMax len =
|
||||
|> addMax
|
||||
)
|
||||
, test =
|
||||
\context _ ->
|
||||
\context ->
|
||||
if List.member context.location [ Testable.IsNearby Testable.OnRight, Testable.IsNearby Testable.OnLeft ] then
|
||||
Expect.true "width fill doesn't apply to onright/onleft elements" True
|
||||
[ Testable.true "width fill doesn't apply to onright/onleft elements" True ]
|
||||
|
||||
else
|
||||
let
|
||||
parentAvailableWidth =
|
||||
context.parent.bbox.width - (context.self.bbox.padding.left + context.self.bbox.padding.right)
|
||||
in
|
||||
case context.location of
|
||||
[ case context.location of
|
||||
Testable.IsNearby _ ->
|
||||
Expect.true "Nearby Element has fill width"
|
||||
Testable.true "Nearby Element has fill width"
|
||||
((floor context.parent.bbox.width == floor context.self.bbox.width)
|
||||
|| minMaxTest (floor context.self.bbox.width)
|
||||
)
|
||||
|
||||
Testable.InColumn ->
|
||||
Expect.true "Element within column has fill width"
|
||||
Testable.true "Element within column has fill width"
|
||||
((floor parentAvailableWidth == floor context.self.bbox.width)
|
||||
|| minMaxTest (floor context.self.bbox.width)
|
||||
)
|
||||
|
||||
Testable.InEl ->
|
||||
Expect.true "Element within element has fill width" <|
|
||||
Testable.true "Element within element has fill width" <|
|
||||
(floor parentAvailableWidth == floor context.self.bbox.width)
|
||||
|| minMaxTest (floor context.self.bbox.width)
|
||||
|
||||
@ -377,9 +392,10 @@ widthHelper maybeMin maybeMax len =
|
||||
spacePerPortion =
|
||||
parentAvailableWidth / toFloat (List.length context.siblings + 1)
|
||||
in
|
||||
Expect.true "element has fill width" <|
|
||||
Testable.true "element has fill width" <|
|
||||
(floor spacePerPortion == floor context.self.bbox.width)
|
||||
|| minMaxTest (floor context.self.bbox.width)
|
||||
]
|
||||
}
|
||||
|
||||
Shrink ->
|
||||
@ -392,7 +408,7 @@ widthHelper maybeMin maybeMax len =
|
||||
|> addMax
|
||||
)
|
||||
, test =
|
||||
\context _ ->
|
||||
\context ->
|
||||
let
|
||||
childWidth child =
|
||||
-- TODO: add margin values to widths
|
||||
@ -412,12 +428,12 @@ widthHelper maybeMin maybeMax len =
|
||||
if totalChildren == 0 then
|
||||
-- TODO: The issue is that we have a hard time measuring `text` elements
|
||||
-- So if a element has a text child, then it's width isn't going to show up in the system.
|
||||
expectRoundedEquality context.self.bbox.width context.self.bbox.width
|
||||
[ expectRoundedEquality context.self.bbox.width context.self.bbox.width ]
|
||||
|
||||
else
|
||||
-- This fails if this element is actually a column
|
||||
-- So we need to capture what this element is in order to do this calculation.
|
||||
expectRoundedEquality (totalChildren + horizontalPadding + spacingValue) context.self.bbox.width
|
||||
[ expectRoundedEquality (totalChildren + horizontalPadding + spacingValue) context.self.bbox.width ]
|
||||
}
|
||||
|
||||
|
||||
@ -487,16 +503,12 @@ heightHelper maybeMin maybeMax len =
|
||||
|> addMax
|
||||
)
|
||||
, test =
|
||||
\found _ ->
|
||||
Expect.all
|
||||
[ \_ ->
|
||||
Expect.true ("exact height is exact: " ++ String.fromInt (floor found.self.bbox.height) ++ "," ++ String.fromInt val)
|
||||
(floor found.self.bbox.height == val)
|
||||
, \_ ->
|
||||
Expect.true "min/max holds true"
|
||||
(minMaxTest (floor found.self.bbox.height))
|
||||
]
|
||||
()
|
||||
\found ->
|
||||
[ Testable.true ("exact height is exact: " ++ String.fromInt (floor found.self.bbox.height) ++ "," ++ String.fromInt val)
|
||||
(floor found.self.bbox.height == val)
|
||||
, Testable.true "min/max holds true"
|
||||
(minMaxTest (floor found.self.bbox.height))
|
||||
]
|
||||
}
|
||||
|
||||
Fill portion ->
|
||||
@ -509,30 +521,30 @@ heightHelper maybeMin maybeMax len =
|
||||
|> addMax
|
||||
)
|
||||
, test =
|
||||
\context _ ->
|
||||
if List.member context.location [ Testable.IsNearby Testable.Above, Testable.IsNearby Testable.Below ] then
|
||||
Expect.true "height fill doesn't apply to above/below elements" True
|
||||
\context ->
|
||||
[ if List.member context.location [ Testable.IsNearby Testable.Above, Testable.IsNearby Testable.Below ] then
|
||||
Testable.true "height fill doesn't apply to above/below elements" True
|
||||
|
||||
else
|
||||
else
|
||||
let
|
||||
parentAvailableHeight =
|
||||
context.parent.bbox.height - (context.self.bbox.padding.top + context.self.bbox.padding.bottom)
|
||||
in
|
||||
case context.location of
|
||||
Testable.IsNearby _ ->
|
||||
Expect.true "Nearby Element has fill height"
|
||||
Testable.true "Nearby Element has fill height"
|
||||
((floor context.parent.bbox.height == floor context.self.bbox.height)
|
||||
|| minMaxTest (floor context.self.bbox.height)
|
||||
)
|
||||
|
||||
Testable.InColumn ->
|
||||
Expect.true "Element within column has fill height"
|
||||
Testable.true "Element within column has fill height"
|
||||
((floor parentAvailableHeight == floor context.self.bbox.height)
|
||||
|| minMaxTest (floor context.self.bbox.height)
|
||||
)
|
||||
|
||||
Testable.InEl ->
|
||||
Expect.true "Element within el has fill height" <|
|
||||
Testable.true "Element within el has fill height" <|
|
||||
(floor parentAvailableHeight == floor context.self.bbox.height)
|
||||
|| minMaxTest (floor context.self.bbox.height)
|
||||
|
||||
@ -541,9 +553,10 @@ heightHelper maybeMin maybeMax len =
|
||||
spacePerPortion =
|
||||
parentAvailableHeight / toFloat (List.length context.siblings + 1)
|
||||
in
|
||||
Expect.true "el has fill height" <|
|
||||
Testable.true "el has fill height" <|
|
||||
(floor spacePerPortion == floor context.self.bbox.height)
|
||||
|| minMaxTest (floor context.self.bbox.height)
|
||||
]
|
||||
}
|
||||
|
||||
Shrink ->
|
||||
@ -556,7 +569,7 @@ heightHelper maybeMin maybeMax len =
|
||||
|> addMax
|
||||
)
|
||||
, test =
|
||||
\context _ ->
|
||||
\context ->
|
||||
let
|
||||
childWidth child =
|
||||
-- TODO: add margin values to heights
|
||||
@ -576,12 +589,12 @@ heightHelper maybeMin maybeMax len =
|
||||
if totalChildren == 0 then
|
||||
-- TODO: The issue is that we have a hard time measuring `text` elements
|
||||
-- So if a element has a text child, then it's height isn't going to show up in the system.
|
||||
expectRoundedEquality context.self.bbox.height context.self.bbox.height
|
||||
[ expectRoundedEquality context.self.bbox.height context.self.bbox.height ]
|
||||
|
||||
else
|
||||
-- This fails if this element is actually a column
|
||||
-- So we need to capture what this element is in order to do this calculation.
|
||||
expectRoundedEquality (totalChildren + verticalPadding + spacingValue) context.self.bbox.height
|
||||
[ expectRoundedEquality (totalChildren + verticalPadding + spacingValue) context.self.bbox.height ]
|
||||
}
|
||||
|
||||
|
||||
@ -603,7 +616,7 @@ spacing space =
|
||||
{ label = "spacing: " ++ String.fromInt space
|
||||
, attr = Element.spacing space
|
||||
, test =
|
||||
\found _ ->
|
||||
\found ->
|
||||
let
|
||||
findDistance child total =
|
||||
List.concatMap
|
||||
@ -649,7 +662,7 @@ spacing space =
|
||||
[]
|
||||
distances
|
||||
in
|
||||
Expect.true
|
||||
[ Testable.true
|
||||
("All children are at least "
|
||||
++ String.fromInt space
|
||||
++ " pixels apart."
|
||||
@ -657,6 +670,7 @@ spacing space =
|
||||
++ " are not though"
|
||||
)
|
||||
(allAreSpaced == [])
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@ -680,28 +694,28 @@ alignLeft =
|
||||
{ label = "alignLeft"
|
||||
, attr = Element.alignLeft
|
||||
, test =
|
||||
\found _ ->
|
||||
if List.member found.location [ Testable.IsNearby Testable.OnLeft, Testable.IsNearby Testable.OnRight ] then
|
||||
Expect.true "alignLeft doesn't apply to elements that are onLeft or onRight" True
|
||||
\found ->
|
||||
[ if List.member found.location [ Testable.IsNearby Testable.OnLeft, Testable.IsNearby Testable.OnRight ] then
|
||||
Testable.true "alignLeft doesn't apply to elements that are onLeft or onRight" True
|
||||
|
||||
else if
|
||||
else if
|
||||
List.member found.location
|
||||
[ Testable.IsNearby Testable.InFront
|
||||
, Testable.IsNearby Testable.Behind
|
||||
, Testable.IsNearby Testable.Above
|
||||
, Testable.IsNearby Testable.Below
|
||||
]
|
||||
then
|
||||
then
|
||||
expectRoundedEquality
|
||||
found.self.bbox.left
|
||||
found.parent.bbox.left
|
||||
|
||||
else if List.length found.siblings == 0 then
|
||||
else if List.length found.siblings == 0 then
|
||||
expectRoundedEquality
|
||||
found.self.bbox.left
|
||||
(found.parent.bbox.left + found.parent.bbox.padding.left)
|
||||
|
||||
else
|
||||
else
|
||||
case found.location of
|
||||
Testable.InRow ->
|
||||
let
|
||||
@ -724,6 +738,7 @@ alignLeft =
|
||||
expectRoundedEquality
|
||||
found.self.bbox.left
|
||||
(found.parent.bbox.left + found.parent.bbox.padding.left)
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@ -734,7 +749,7 @@ centerX =
|
||||
{ label = "centerX"
|
||||
, attr = Element.centerX
|
||||
, test =
|
||||
\found _ ->
|
||||
\found ->
|
||||
let
|
||||
selfCenter : Float
|
||||
selfCenter =
|
||||
@ -745,12 +760,13 @@ centerX =
|
||||
found.parent.bbox.left + (found.parent.bbox.width / 2)
|
||||
in
|
||||
if List.member found.location [ Testable.IsNearby Testable.OnRight, Testable.IsNearby Testable.OnLeft ] then
|
||||
Expect.true "centerX doesn't apply to elements that are onLeft or onRight" True
|
||||
[ Testable.true "centerX doesn't apply to elements that are onLeft or onRight" True ]
|
||||
|
||||
else if List.length found.siblings == 0 then
|
||||
expectRoundedEquality
|
||||
[ expectRoundedEquality
|
||||
selfCenter
|
||||
parentCenter
|
||||
]
|
||||
|
||||
else
|
||||
case found.location of
|
||||
@ -783,12 +799,13 @@ centerX =
|
||||
/ 2
|
||||
)
|
||||
in
|
||||
expectRoundedEquality
|
||||
[ expectRoundedEquality
|
||||
selfCenter
|
||||
expectedCenter
|
||||
]
|
||||
|
||||
_ ->
|
||||
expectRoundedEquality selfCenter parentCenter
|
||||
[ expectRoundedEquality selfCenter parentCenter ]
|
||||
}
|
||||
|
||||
|
||||
@ -799,9 +816,9 @@ alignRight =
|
||||
{ label = "alignRight"
|
||||
, attr = Element.alignRight
|
||||
, test =
|
||||
\found _ ->
|
||||
\found ->
|
||||
if List.member found.location [ Testable.IsNearby Testable.OnLeft, Testable.IsNearby Testable.OnRight ] then
|
||||
Expect.true "alignRight doesn't apply to elements that are onLeft or onRight" True
|
||||
[ Testable.true "alignRight doesn't apply to elements that are onLeft or onRight" True ]
|
||||
|
||||
else if
|
||||
List.member found.location
|
||||
@ -811,14 +828,16 @@ alignRight =
|
||||
, Testable.IsNearby Testable.Below
|
||||
]
|
||||
then
|
||||
expectRoundedEquality
|
||||
[ expectRoundedEquality
|
||||
found.self.bbox.right
|
||||
found.parent.bbox.right
|
||||
]
|
||||
|
||||
else if List.length found.siblings == 0 then
|
||||
expectRoundedEquality
|
||||
[ expectRoundedEquality
|
||||
found.self.bbox.right
|
||||
(found.parent.bbox.right + found.parent.bbox.padding.right)
|
||||
]
|
||||
|
||||
else
|
||||
case found.location of
|
||||
@ -835,14 +854,16 @@ alignRight =
|
||||
|> List.map (.width << .bbox)
|
||||
|> List.sum
|
||||
in
|
||||
expectRoundedEquality
|
||||
[ expectRoundedEquality
|
||||
found.self.bbox.right
|
||||
(found.parent.bbox.right - (found.parent.bbox.padding.right + widthsOnRight + spacings))
|
||||
]
|
||||
|
||||
_ ->
|
||||
expectRoundedEquality
|
||||
[ expectRoundedEquality
|
||||
found.self.bbox.right
|
||||
(found.parent.bbox.right + found.parent.bbox.padding.right)
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@ -853,9 +874,9 @@ alignTop =
|
||||
{ label = "alignTop"
|
||||
, attr = Element.alignTop
|
||||
, test =
|
||||
\found _ ->
|
||||
\found ->
|
||||
if List.member found.location [ Testable.IsNearby Testable.Above, Testable.IsNearby Testable.Below ] then
|
||||
Expect.true "alignTop doesn't apply to elements that are above or below" True
|
||||
[ Testable.true "alignTop doesn't apply to elements that are above or below" True ]
|
||||
|
||||
else if
|
||||
List.member found.location
|
||||
@ -865,14 +886,16 @@ alignTop =
|
||||
, Testable.IsNearby Testable.OnLeft
|
||||
]
|
||||
then
|
||||
expectRoundedEquality
|
||||
[ expectRoundedEquality
|
||||
found.self.bbox.top
|
||||
found.parent.bbox.top
|
||||
]
|
||||
|
||||
else if List.length found.siblings == 0 then
|
||||
expectRoundedEquality
|
||||
[ expectRoundedEquality
|
||||
found.self.bbox.top
|
||||
(found.parent.bbox.top + found.parent.bbox.padding.top)
|
||||
]
|
||||
|
||||
else
|
||||
case found.location of
|
||||
@ -889,14 +912,16 @@ alignTop =
|
||||
|> List.map (.height << .bbox)
|
||||
|> List.sum
|
||||
in
|
||||
expectRoundedEquality
|
||||
[ expectRoundedEquality
|
||||
found.self.bbox.top
|
||||
(found.parent.bbox.top + (found.parent.bbox.padding.top + heightsAbove + spacings))
|
||||
]
|
||||
|
||||
_ ->
|
||||
expectRoundedEquality
|
||||
[ expectRoundedEquality
|
||||
found.self.bbox.top
|
||||
found.parent.bbox.top
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@ -907,9 +932,9 @@ alignBottom =
|
||||
{ label = "alignBottom"
|
||||
, attr = Element.alignBottom
|
||||
, test =
|
||||
\found _ ->
|
||||
\found ->
|
||||
if List.member found.location [ Testable.IsNearby Testable.Above, Testable.IsNearby Testable.Below ] then
|
||||
Expect.true "alignBottom doesn't apply to elements that are above or below" True
|
||||
[ Testable.true "alignBottom doesn't apply to elements that are above or below" True ]
|
||||
|
||||
else if
|
||||
List.member found.location
|
||||
@ -919,14 +944,16 @@ alignBottom =
|
||||
, Testable.IsNearby Testable.OnLeft
|
||||
]
|
||||
then
|
||||
expectRoundedEquality
|
||||
[ expectRoundedEquality
|
||||
found.self.bbox.bottom
|
||||
found.parent.bbox.bottom
|
||||
]
|
||||
|
||||
else if List.length found.siblings == 0 then
|
||||
expectRoundedEquality
|
||||
[ expectRoundedEquality
|
||||
found.self.bbox.bottom
|
||||
(found.parent.bbox.bottom + found.parent.bbox.padding.bottom)
|
||||
]
|
||||
|
||||
else
|
||||
case found.location of
|
||||
@ -943,22 +970,30 @@ alignBottom =
|
||||
|> List.map (.height << .bbox)
|
||||
|> List.sum
|
||||
in
|
||||
expectRoundedEquality
|
||||
[ expectRoundedEquality
|
||||
found.self.bbox.bottom
|
||||
(found.parent.bbox.bottom - (found.parent.bbox.padding.bottom + heightsBelow + spacings))
|
||||
]
|
||||
|
||||
_ ->
|
||||
expectRoundedEquality
|
||||
[ expectRoundedEquality
|
||||
found.self.bbox.bottom
|
||||
(found.parent.bbox.bottom + found.parent.bbox.padding.bottom)
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
expectRoundedEquality x y =
|
||||
Expect.true ("within 1 of each other " ++ String.fromFloat x ++ ":" ++ String.fromFloat y)
|
||||
Testable.true
|
||||
("within 1 of each other " ++ floatToString x ++ ", " ++ floatToString y)
|
||||
(abs (x - y) < 1)
|
||||
|
||||
|
||||
floatToString : Float -> String
|
||||
floatToString x =
|
||||
String.fromFloat (toFloat (round (x * 100)) / 100)
|
||||
|
||||
|
||||
{-| -}
|
||||
centerY : Testable.Attr msg
|
||||
centerY =
|
||||
@ -966,7 +1001,7 @@ centerY =
|
||||
{ label = "centerY"
|
||||
, attr = Element.centerY
|
||||
, test =
|
||||
\found _ ->
|
||||
\found ->
|
||||
let
|
||||
selfCenter =
|
||||
found.self.bbox.top + (found.self.bbox.height / 2)
|
||||
@ -975,12 +1010,13 @@ centerY =
|
||||
found.parent.bbox.top + (found.parent.bbox.height / 2)
|
||||
in
|
||||
if List.member found.location [ Testable.IsNearby Testable.Above, Testable.IsNearby Testable.Below ] then
|
||||
Expect.true "centerY doesn't apply to elements that are above or below" True
|
||||
[ Testable.true "centerY doesn't apply to elements that are above or below" True ]
|
||||
|
||||
else if List.length found.siblings == 0 then
|
||||
expectRoundedEquality
|
||||
[ expectRoundedEquality
|
||||
selfCenter
|
||||
parentCenter
|
||||
]
|
||||
|
||||
else
|
||||
case found.location of
|
||||
@ -1013,12 +1049,13 @@ centerY =
|
||||
/ 2
|
||||
)
|
||||
in
|
||||
expectRoundedEquality
|
||||
[ expectRoundedEquality
|
||||
selfCenter
|
||||
expectedCenter
|
||||
]
|
||||
|
||||
_ ->
|
||||
expectRoundedEquality selfCenter parentCenter
|
||||
[ expectRoundedEquality selfCenter parentCenter ]
|
||||
}
|
||||
|
||||
|
||||
@ -1030,8 +1067,8 @@ above element =
|
||||
, element = element
|
||||
, label = "above"
|
||||
, test =
|
||||
\found _ ->
|
||||
expectRoundedEquality found.self.bbox.bottom found.parent.bbox.top
|
||||
\found ->
|
||||
[ expectRoundedEquality found.self.bbox.bottom found.parent.bbox.top ]
|
||||
}
|
||||
|
||||
|
||||
@ -1043,8 +1080,8 @@ below element =
|
||||
, element = element
|
||||
, label = "below"
|
||||
, test =
|
||||
\found _ ->
|
||||
expectRoundedEquality found.self.bbox.top found.parent.bbox.bottom
|
||||
\found ->
|
||||
[ expectRoundedEquality found.self.bbox.top found.parent.bbox.bottom ]
|
||||
}
|
||||
|
||||
|
||||
@ -1056,8 +1093,8 @@ onRight element =
|
||||
, element = element
|
||||
, label = "onRight"
|
||||
, test =
|
||||
\found _ ->
|
||||
expectRoundedEquality found.self.bbox.left found.parent.bbox.right
|
||||
\found ->
|
||||
[ expectRoundedEquality found.self.bbox.left found.parent.bbox.right ]
|
||||
}
|
||||
|
||||
|
||||
@ -1069,8 +1106,8 @@ onLeft element =
|
||||
, element = element
|
||||
, label = "onLeft"
|
||||
, test =
|
||||
\found _ ->
|
||||
expectRoundedEquality found.self.bbox.right found.parent.bbox.left
|
||||
\found ->
|
||||
[ expectRoundedEquality found.self.bbox.right found.parent.bbox.left ]
|
||||
}
|
||||
|
||||
|
||||
@ -1086,11 +1123,12 @@ inFront element =
|
||||
, element = element
|
||||
, label = "inFront"
|
||||
, test =
|
||||
withinHelper
|
||||
\found ->
|
||||
[ withinHelper found ]
|
||||
}
|
||||
|
||||
|
||||
withinHelper found _ =
|
||||
withinHelper found =
|
||||
let
|
||||
horizontalCheck =
|
||||
if found.self.bbox.width > found.parent.bbox.width then
|
||||
@ -1114,7 +1152,7 @@ withinHelper found _ =
|
||||
, compare found.self.bbox.bottom (<=) found.parent.bbox.bottom
|
||||
]
|
||||
in
|
||||
Expect.true "within the confines of the parent"
|
||||
Testable.true "within the confines of the parent"
|
||||
(List.all ((==) True)
|
||||
(List.concat
|
||||
[ horizontalCheck
|
||||
@ -1132,5 +1170,6 @@ behindContent element =
|
||||
, element = element
|
||||
, label = "behindContent"
|
||||
, test =
|
||||
withinHelper
|
||||
\found ->
|
||||
[ withinHelper found ]
|
||||
}
|
||||
|
@ -5,23 +5,23 @@ module Testable.Element.Background exposing (color)
|
||||
import Dict
|
||||
import Element exposing (Color)
|
||||
import Element.Background as Background
|
||||
import Expect
|
||||
import Testable
|
||||
|
||||
|
||||
color : Color -> Testable.Attr msg
|
||||
color clr =
|
||||
Testable.LabeledTest
|
||||
{ label = "background color-" ++ Testable.formatColor clr
|
||||
{ label = "background color"
|
||||
, attr = Background.color clr
|
||||
, test =
|
||||
\context _ ->
|
||||
\context ->
|
||||
let
|
||||
selfBackgroundColor =
|
||||
context.self.style
|
||||
|> Dict.get "background-color"
|
||||
|> Maybe.withDefault "notfound"
|
||||
in
|
||||
Expect.true ("Expected color: " ++ (Testable.formatColor clr ++ " vs found:" ++ selfBackgroundColor))
|
||||
[ Testable.true ("expected: " ++ (Testable.formatColor clr ++ ", found:" ++ selfBackgroundColor))
|
||||
(Testable.compareFormattedColor clr selfBackgroundColor)
|
||||
]
|
||||
}
|
||||
|
@ -15,15 +15,16 @@ color clr =
|
||||
{ label = "font color-" ++ Testable.formatColor clr
|
||||
, attr = Font.color clr
|
||||
, test =
|
||||
\context _ ->
|
||||
\context ->
|
||||
let
|
||||
selfFontColor =
|
||||
context.self.style
|
||||
|> Dict.get "color"
|
||||
|> Maybe.withDefault "notfound"
|
||||
in
|
||||
Expect.true ("Color Match - " ++ (Testable.formatColor clr ++ " vs " ++ selfFontColor))
|
||||
[ Testable.true ("Color Match - " ++ (Testable.formatColor clr ++ " vs " ++ selfFontColor))
|
||||
(Testable.compareFormattedColor clr selfFontColor)
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@ -33,7 +34,7 @@ size i =
|
||||
{ label = "font size-" ++ String.fromInt i
|
||||
, attr = Font.size i
|
||||
, test =
|
||||
\context _ ->
|
||||
\context ->
|
||||
let
|
||||
selfFontSize =
|
||||
context.self.style
|
||||
@ -43,6 +44,7 @@ size i =
|
||||
formattedInt =
|
||||
String.fromInt i
|
||||
in
|
||||
Expect.true ("Size Match - " ++ (formattedInt ++ " vs " ++ selfFontSize))
|
||||
[ Testable.true ("Size Match - " ++ (formattedInt ++ " vs " ++ selfFontSize))
|
||||
(formattedInt == selfFontSize)
|
||||
]
|
||||
}
|
||||
|
@ -3,27 +3,23 @@ port module Testable.Runner exposing (Msg, TestableProgram, program, show)
|
||||
{-| -}
|
||||
|
||||
import Browser
|
||||
import Char
|
||||
import Dict exposing (Dict)
|
||||
import Element
|
||||
import Element.Background as Background
|
||||
import Element.Border as Border
|
||||
import Element.Events as Events
|
||||
import Element.Font as Font
|
||||
import Html exposing (Html)
|
||||
import Parser exposing ((|.), (|=))
|
||||
import Html.Attributes
|
||||
import Process
|
||||
import Random
|
||||
import Set
|
||||
import Task
|
||||
import Test.Runner
|
||||
import Test.Runner.Failure as Failure
|
||||
import Testable
|
||||
import Time
|
||||
|
||||
|
||||
show : Testable.Element msg -> Html msg
|
||||
show =
|
||||
Testable.render
|
||||
Testable.toHtml
|
||||
|
||||
|
||||
type alias TestableProgram =
|
||||
@ -56,6 +52,7 @@ program tests =
|
||||
( { current = current
|
||||
, upcoming = upcoming
|
||||
, finished = []
|
||||
, highlightDomId = Nothing
|
||||
}
|
||||
, Task.perform (always Analyze)
|
||||
(Process.sleep 32
|
||||
@ -80,6 +77,7 @@ type alias Model msg =
|
||||
{ current : Maybe ( String, Testable.Element msg )
|
||||
, upcoming : List ( String, Testable.Element msg )
|
||||
, finished : List (WithResults (Testable.Element msg))
|
||||
, highlightDomId : Maybe String
|
||||
}
|
||||
|
||||
|
||||
@ -87,49 +85,44 @@ type alias WithResults thing =
|
||||
{ element : thing
|
||||
, label : String
|
||||
, results :
|
||||
List
|
||||
( String
|
||||
, Maybe
|
||||
{ given : Maybe String
|
||||
, description : String
|
||||
, reason : Failure.Reason
|
||||
}
|
||||
)
|
||||
List Testable.LayoutTest
|
||||
}
|
||||
|
||||
|
||||
prepareResults :
|
||||
encodeForReport :
|
||||
List (WithResults (Testable.Element msg))
|
||||
->
|
||||
List
|
||||
{ label : String
|
||||
, results :
|
||||
List
|
||||
( String
|
||||
, Maybe
|
||||
{ given : Maybe String
|
||||
, description : String
|
||||
}
|
||||
)
|
||||
{ description : String
|
||||
, passing : Bool
|
||||
, todo : Bool
|
||||
}
|
||||
}
|
||||
prepareResults withResults =
|
||||
encodeForReport withResults =
|
||||
let
|
||||
prepareNode ( x, maybeResult ) =
|
||||
( x
|
||||
, case maybeResult of
|
||||
Nothing ->
|
||||
Nothing
|
||||
prepareExpectation layoutTest exp =
|
||||
case exp of
|
||||
Testable.Todo description ->
|
||||
{ description = description
|
||||
, passing = False
|
||||
, todo = True
|
||||
}
|
||||
|
||||
Just res ->
|
||||
Just
|
||||
{ given = res.given
|
||||
, description = res.description
|
||||
}
|
||||
)
|
||||
Testable.Expect details ->
|
||||
{ description = details.description
|
||||
, passing = details.result
|
||||
, todo = False
|
||||
}
|
||||
|
||||
prepareNode layoutTest =
|
||||
List.map (prepareExpectation layoutTest) layoutTest.expectations
|
||||
|
||||
prepare { label, results } =
|
||||
{ label = label
|
||||
, results = List.map prepareNode results
|
||||
, results = List.concatMap prepareNode results
|
||||
}
|
||||
in
|
||||
List.map prepare withResults
|
||||
@ -138,6 +131,7 @@ prepareResults withResults =
|
||||
type Msg
|
||||
= NoOp
|
||||
| Analyze
|
||||
| HighlightDomID (Maybe String)
|
||||
| RefreshBoundingBox
|
||||
(List
|
||||
{ id : String
|
||||
@ -151,14 +145,8 @@ type Msg
|
||||
runTest : Dict String Testable.Found -> String -> Testable.Element msg -> WithResults (Testable.Element msg)
|
||||
runTest boxes label element =
|
||||
let
|
||||
tests =
|
||||
Testable.toTest label boxes element
|
||||
|
||||
seed =
|
||||
Random.initialSeed 227852860
|
||||
|
||||
results =
|
||||
Testable.runTests seed tests
|
||||
Testable.runTests boxes element
|
||||
in
|
||||
{ element = element
|
||||
, label = label
|
||||
@ -172,6 +160,11 @@ update msg model =
|
||||
NoOp ->
|
||||
( model, Cmd.none )
|
||||
|
||||
HighlightDomID newId ->
|
||||
( { model | highlightDomId = newId }
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
RefreshBoundingBox boxes ->
|
||||
case model.current of
|
||||
Nothing ->
|
||||
@ -203,7 +196,7 @@ update msg model =
|
||||
| current = Nothing
|
||||
, finished = model.finished ++ [ currentResults ]
|
||||
}
|
||||
, report (prepareResults (currentResults :: model.finished))
|
||||
, report (encodeForReport (currentResults :: model.finished))
|
||||
)
|
||||
|
||||
newCurrent :: remaining ->
|
||||
@ -246,23 +239,42 @@ view model =
|
||||
[ Element.spacing 20
|
||||
, Element.padding 20
|
||||
, Element.width (Element.px 800)
|
||||
|
||||
-- , Background.color Color.grey
|
||||
]
|
||||
[ Element.none ]
|
||||
|
||||
finished :: remaining ->
|
||||
if False then
|
||||
viewResultsInline finished
|
||||
|
||||
else
|
||||
Element.layout [] <|
|
||||
Element.column
|
||||
Element.layout
|
||||
[ Font.size 16
|
||||
, Element.inFront (Element.html (viewElementHighlight model))
|
||||
]
|
||||
<|
|
||||
Element.row [ Element.width Element.fill ]
|
||||
[ Element.el
|
||||
[ Element.width Element.fill
|
||||
]
|
||||
(Element.el
|
||||
[ Element.centerX
|
||||
, Element.padding 100
|
||||
, Border.dashed
|
||||
, Border.width 2
|
||||
, Border.color palette.lightGrey
|
||||
, Element.inFront
|
||||
(Element.el
|
||||
[ Font.size 14
|
||||
, Font.color palette.lightGrey
|
||||
]
|
||||
(Element.text "test case")
|
||||
)
|
||||
]
|
||||
(Testable.toElement finished.element)
|
||||
)
|
||||
, Element.column
|
||||
[ Element.spacing 20
|
||||
, Element.padding 20
|
||||
, Element.width (Element.px 800)
|
||||
, Element.width Element.fill
|
||||
]
|
||||
(List.map viewResult (finished :: remaining))
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@ -274,162 +286,181 @@ view model =
|
||||
Just ( label, current ) ->
|
||||
{ title = "running"
|
||||
, body =
|
||||
[ Testable.render current ]
|
||||
[ Testable.toHtml current ]
|
||||
}
|
||||
|
||||
|
||||
viewResultsInline : WithResults (Testable.Element Msg) -> Html Msg
|
||||
viewResultsInline testable =
|
||||
Html.div
|
||||
[]
|
||||
[ viewResultsAnnotationStylesheet testable.results
|
||||
, Testable.render testable.element
|
||||
]
|
||||
viewElementHighlight model =
|
||||
case model.highlightDomId of
|
||||
Nothing ->
|
||||
Html.text ""
|
||||
|
||||
Just highlightDomId ->
|
||||
let
|
||||
elementHighlight =
|
||||
highlightDomId ++ " { outline: solid; }"
|
||||
|
||||
{-| Our ID is part of our label. This could be fixed farther down the chain, but I think it'd be pretty involved.
|
||||
testId =
|
||||
highlightDomId
|
||||
|> String.dropLeft 1
|
||||
|> String.append "#tests-"
|
||||
|
||||
So, now we can just parse the id out of the label.
|
||||
testHighlight =
|
||||
testId ++ " { outline: dashed; }"
|
||||
|
||||
-}
|
||||
parseId str =
|
||||
str
|
||||
|> Parser.run
|
||||
(Parser.succeed identity
|
||||
|. Parser.chompWhile (\c -> c /= '#')
|
||||
|= Parser.variable
|
||||
{ start = \c -> c == '#'
|
||||
, inner = \c -> Char.isAlphaNum c || c == '-'
|
||||
, reserved = Set.empty
|
||||
}
|
||||
)
|
||||
|> Result.toMaybe
|
||||
|
||||
|
||||
viewResultsAnnotationStylesheet results =
|
||||
let
|
||||
toStyleClass ( label, maybeFailure ) =
|
||||
case maybeFailure of
|
||||
Nothing ->
|
||||
""
|
||||
|
||||
Just failure ->
|
||||
case parseId label of
|
||||
Nothing ->
|
||||
Debug.log "NO ID FOUND" label
|
||||
|
||||
Just id ->
|
||||
id ++ " { background-color:red; outline: dashed; };"
|
||||
|
||||
styleSheet =
|
||||
results
|
||||
|> List.map toStyleClass
|
||||
|> String.join ""
|
||||
in
|
||||
Html.node "style"
|
||||
[]
|
||||
[ Html.text styleSheet
|
||||
]
|
||||
styleSheet =
|
||||
String.join "\n"
|
||||
[ elementHighlight
|
||||
, testHighlight
|
||||
]
|
||||
in
|
||||
Html.node "style"
|
||||
[]
|
||||
[ Html.text styleSheet
|
||||
]
|
||||
|
||||
|
||||
viewResult : WithResults (Testable.Element Msg) -> Element.Element Msg
|
||||
viewResult testable =
|
||||
let
|
||||
isPassing result =
|
||||
case Tuple.second result of
|
||||
Nothing ->
|
||||
isExpectationPassing result =
|
||||
case result of
|
||||
Testable.Todo label ->
|
||||
True
|
||||
|
||||
Just _ ->
|
||||
False
|
||||
Testable.Expect details ->
|
||||
details.result
|
||||
|
||||
isPassing layoutTest =
|
||||
List.any isExpectationPassing layoutTest.expectations
|
||||
|
||||
( passing, failing ) =
|
||||
List.partition isPassing testable.results
|
||||
|
||||
viewSingle result =
|
||||
case result of
|
||||
( label, Nothing ) ->
|
||||
Element.el
|
||||
[ Background.color palette.green
|
||||
, Font.color palette.black
|
||||
, Element.paddingXY 20 10
|
||||
, Element.alignLeft
|
||||
, Border.rounded 3
|
||||
]
|
||||
<|
|
||||
Element.text ("Success! - " ++ label)
|
||||
|
||||
( label, Just ({ given, description } as reason) ) ->
|
||||
Element.column
|
||||
[ Background.color palette.red
|
||||
, Font.color palette.black
|
||||
, Element.paddingXY 20 10
|
||||
, Element.alignLeft
|
||||
, Element.width Element.shrink
|
||||
|
||||
-- , Element.spacing 25
|
||||
, Border.rounded 3
|
||||
]
|
||||
[ Element.el [ Element.width Element.fill ] <| Element.text label
|
||||
, Element.el [ Element.width Element.fill ] <| Element.text (viewReason reason)
|
||||
]
|
||||
in
|
||||
Element.column
|
||||
[ Border.width 1
|
||||
, Border.color palette.lightGrey
|
||||
, Element.padding 20
|
||||
, Element.height Element.shrink
|
||||
, Element.alignLeft
|
||||
[ Element.alignLeft
|
||||
, Element.spacing 16
|
||||
]
|
||||
[ Element.el [ Font.bold, Font.size 64 ] (Element.text testable.label)
|
||||
[ Element.el [ Font.size 24 ] (Element.text testable.label)
|
||||
, Element.column [ Element.alignLeft, Element.spacing 20 ]
|
||||
(failing
|
||||
|> List.map viewSingle
|
||||
(List.map viewLayoutTest failing)
|
||||
, Element.column
|
||||
[ Element.alignLeft, Element.spacing 16 ]
|
||||
(passing
|
||||
|> groupBy .elementDomId
|
||||
|> List.map viewLayoutTestGroup
|
||||
)
|
||||
, Element.el
|
||||
[ Element.alignLeft
|
||||
, Element.spacing 20
|
||||
, Background.color palette.green
|
||||
, Font.color palette.black
|
||||
, Element.paddingXY 20 10
|
||||
, Element.alignLeft
|
||||
, Border.rounded 3
|
||||
]
|
||||
(Element.text (String.fromInt (List.length passing) ++ " tests passing!"))
|
||||
]
|
||||
|
||||
|
||||
viewReason { description, reason } =
|
||||
case reason of
|
||||
Failure.Custom ->
|
||||
description
|
||||
groupBy fn list =
|
||||
groupWhile (\one two -> fn one == fn two) list
|
||||
|> List.map
|
||||
(\( fst, remaining ) ->
|
||||
{ id = fn fst
|
||||
, members = fst :: remaining
|
||||
}
|
||||
)
|
||||
|
||||
Failure.Equality one two ->
|
||||
description ++ " " ++ one ++ " " ++ two
|
||||
|
||||
Failure.Comparison one two ->
|
||||
description ++ " " ++ one ++ " " ++ two
|
||||
groupWhile : (a -> a -> Bool) -> List a -> List ( a, List a )
|
||||
groupWhile isSameGroup items =
|
||||
List.foldr
|
||||
(\x acc ->
|
||||
case acc of
|
||||
[] ->
|
||||
[ ( x, [] ) ]
|
||||
|
||||
Failure.ListDiff expected actual ->
|
||||
"expected\n"
|
||||
++ String.join " \n" expected
|
||||
++ "actual\n"
|
||||
++ String.join " \n" actual
|
||||
( y, restOfGroup ) :: groups ->
|
||||
if isSameGroup x y then
|
||||
( x, y :: restOfGroup ) :: groups
|
||||
|
||||
Failure.CollectionDiff { expected, actual, extra, missing } ->
|
||||
String.join "\n"
|
||||
[ formatKeyValue "expected" expected
|
||||
, formatKeyValue "actual" actual
|
||||
, formatKeyValue "extra" (String.join ", " extra)
|
||||
, formatKeyValue "missing" (String.join ", " missing)
|
||||
]
|
||||
else
|
||||
( x, [] ) :: acc
|
||||
)
|
||||
[]
|
||||
items
|
||||
|
||||
Failure.TODO ->
|
||||
description
|
||||
|
||||
Failure.Invalid _ ->
|
||||
description
|
||||
viewLayoutTestGroup group =
|
||||
let
|
||||
testId =
|
||||
group.id
|
||||
|> String.dropLeft 1
|
||||
|> String.append "tests-"
|
||||
in
|
||||
Element.column
|
||||
[ Element.spacing 8
|
||||
, Element.htmlAttribute (Html.Attributes.id testId)
|
||||
, Events.onMouseEnter (HighlightDomID (Just group.id))
|
||||
, Events.onMouseLeave (HighlightDomID Nothing)
|
||||
, Element.htmlAttribute (Html.Attributes.style "user-select" "none")
|
||||
]
|
||||
[ Element.el [ Font.color palette.lightGrey ] (Element.text group.id)
|
||||
, Element.column
|
||||
[ Element.spacing 8
|
||||
, Element.paddingXY 32 0
|
||||
]
|
||||
(List.map viewLayoutTest group.members)
|
||||
]
|
||||
|
||||
|
||||
type alias Grouped thing =
|
||||
{ id : String
|
||||
, members : List thing
|
||||
}
|
||||
|
||||
|
||||
viewLayoutTest layoutTest =
|
||||
Element.column
|
||||
[ Element.spacing 8
|
||||
]
|
||||
[ Element.row [ Element.spacing 8 ]
|
||||
[ Element.el [ Font.bold ] (Element.text layoutTest.label)
|
||||
|
||||
-- , Element.el [ Font.color palette.lightGrey ] (Element.text layoutTest.elementDomId)
|
||||
]
|
||||
, Element.column [ Element.spacing 8 ]
|
||||
(List.map viewLayoutExpectation layoutTest.expectations)
|
||||
]
|
||||
|
||||
|
||||
viewLayoutExpectation expectation =
|
||||
case expectation of
|
||||
Testable.Todo label ->
|
||||
Element.row [ Element.spacing 4 ]
|
||||
[ todo, Element.text label ]
|
||||
|
||||
Testable.Expect details ->
|
||||
if details.result then
|
||||
Element.row [ Element.spacing 4 ]
|
||||
[ pass, Element.text details.description ]
|
||||
|
||||
else
|
||||
Element.row [ Element.spacing 4 ]
|
||||
[ fail, Element.text details.description ]
|
||||
|
||||
|
||||
badge color text =
|
||||
Element.el
|
||||
[ Background.color color
|
||||
, Font.color palette.black
|
||||
, Element.paddingXY 4 8
|
||||
, Border.rounded 2
|
||||
]
|
||||
(Element.text text)
|
||||
|
||||
|
||||
todo =
|
||||
badge palette.lightGrey "todo"
|
||||
|
||||
|
||||
pass =
|
||||
badge palette.green "pass"
|
||||
|
||||
|
||||
fail =
|
||||
badge palette.red "fail"
|
||||
|
||||
|
||||
formatKeyValue : String -> String -> String
|
||||
@ -442,12 +473,10 @@ port report :
|
||||
{ label : String
|
||||
, results :
|
||||
List
|
||||
( String
|
||||
, Maybe
|
||||
{ given : Maybe String
|
||||
, description : String
|
||||
}
|
||||
)
|
||||
{ description : String
|
||||
, passing : Bool
|
||||
, todo : Bool
|
||||
}
|
||||
}
|
||||
-> Cmd msg
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
<body id="root"></body>
|
||||
|
||||
<script type="text/javascript">
|
||||
var app = Elm.InFrontSize.init();
|
||||
var app = Elm.WeirdCentering.init();
|
||||
|
||||
var test_results = "waiting..";
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user