From 6f347d74a3ef3ad9655a7a46ac0f011c322756c6 Mon Sep 17 00:00:00 2001 From: Andrew Rasmussen Date: Thu, 25 Sep 2014 16:05:01 -0700 Subject: [PATCH 1/4] Added another pass to calclulate absolutely positioned elements last --- src/Layout.c | 48 ++--- src/Layout.js | 50 ++--- src/__tests__/Layout-test.c | 343 +++++++++++------------------------ src/__tests__/Layout-test.js | 13 ++ src/transpile.html | 4 +- 5 files changed, 181 insertions(+), 277 deletions(-) diff --git a/src/Layout.c b/src/Layout.c index ee2edd77..8574dcad 100644 --- a/src/Layout.c +++ b/src/Layout.c @@ -393,26 +393,6 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // You never want to go smaller than padding getPaddingAndBorderAxis(child, crossAxis) ); - } else if (getPositionType(child) == CSS_POSITION_ABSOLUTE) { - // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both - // left and right or top and bottom). - for (int ii = 0; ii < 2; ii++) { - css_flex_direction_t axis = ii ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; - if (!isUndefined(node->layout.dimensions[dim[axis]]) && - !isDimDefined(child, axis) && - isPosDefined(child, leading[axis]) && - isPosDefined(child, trailing[axis])) { - child->layout.dimensions[dim[axis]] = fmaxf( - node->layout.dimensions[dim[axis]] - - getPaddingAndBorderAxis(node, axis) - - getMarginAxis(child, axis) - - getPosition(child, leading[axis]) - - getPosition(child, trailing[axis]), - // You never want to go smaller than padding - getPaddingAndBorderAxis(child, axis) - ); - } - } } } @@ -549,7 +529,6 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { } } - // Position elements in the main axis and compute dimensions // At this point, all the children have their dimensions set. We need to @@ -666,6 +645,33 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { child->layout.position[pos[crossAxis]] += leadingCrossDim; } } + + // Calculate dimensions for absolutely positioned elements + + for (int i = 0; i < node->children_count; ++i) { + css_node_t* child = node->get_child(node->context, i); + if (getPositionType(child) == CSS_POSITION_ABSOLUTE) { + // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both + // left and right or top and bottom). + for (int ii = 0; ii < 2; ii++) { + css_flex_direction_t axis = ii ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; + if (!isUndefined(node->layout.dimensions[dim[axis]]) && + !isDimDefined(child, axis) && + isPosDefined(child, leading[axis]) && + isPosDefined(child, trailing[axis])) { + child->layout.dimensions[dim[axis]] = fmaxf( + node->layout.dimensions[dim[axis]] - + getPaddingAndBorderAxis(node, axis) - + getMarginAxis(child, axis) - + getPosition(child, leading[axis]) - + getPosition(child, trailing[axis]), + // You never want to go smaller than padding + getPaddingAndBorderAxis(child, axis) + ); + } + } + } + } } void layoutNode(css_node_t *node, float parentMaxWidth) { diff --git a/src/Layout.js b/src/Layout.js index 91bd6f3f..42a66ca9 100755 --- a/src/Layout.js +++ b/src/Layout.js @@ -269,26 +269,6 @@ var computeLayout = (function() { // You never want to go smaller than padding getPaddingAndBorderAxis(child, crossAxis) ); - } else if (getPositionType(child) == CSS_POSITION_ABSOLUTE) { - // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both - // left and right or top and bottom). - for (var/*int*/ ii = 0; ii < 2; ii++) { - var/*css_flex_direction_t*/ axis = ii ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; - if (!isUndefined(node.layout[dim[axis]]) && - !isDimDefined(child, axis) && - isPosDefined(child, leading[axis]) && - isPosDefined(child, trailing[axis])) { - child.layout[dim[axis]] = fmaxf( - node.layout[dim[axis]] - - getPaddingAndBorderAxis(node, axis) - - getMarginAxis(child, axis) - - getPosition(child, leading[axis]) - - getPosition(child, trailing[axis]), - // You never want to go smaller than padding - getPaddingAndBorderAxis(child, axis) - ); - } - } } } @@ -425,7 +405,6 @@ var computeLayout = (function() { } } - // Position elements in the main axis and compute dimensions // At this point, all the children have their dimensions set. We need to @@ -542,7 +521,34 @@ var computeLayout = (function() { child.layout[pos[crossAxis]] += leadingCrossDim; } } - } + + // Calculate dimensions for absolutely positioned elements + + for (var/*int*/ i = 0; i < node.children.length; ++i) { + var/*css_node_t**/ child = node.children[i]; + if (getPositionType(child) == CSS_POSITION_ABSOLUTE) { + // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both + // left and right or top and bottom). + for (var/*int*/ ii = 0; ii < 2; ii++) { + var/*css_flex_direction_t*/ axis = ii ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; + if (!isUndefined(node.layout[dim[axis]]) && + !isDimDefined(child, axis) && + isPosDefined(child, leading[axis]) && + isPosDefined(child, trailing[axis])) { + child.layout[dim[axis]] = fmaxf( + node.layout[dim[axis]] - + getPaddingAndBorderAxis(node, axis) - + getMarginAxis(child, axis) - + getPosition(child, leading[axis]) - + getPosition(child, trailing[axis]), + // You never want to go smaller than padding + getPaddingAndBorderAxis(child, axis) + ); + } + } + } + } + }; })(); diff --git a/src/__tests__/Layout-test.c b/src/__tests__/Layout-test.c index 8d6a3a7c..4e7ce09e 100644 --- a/src/__tests__/Layout-test.c +++ b/src/__tests__/Layout-test.c @@ -2473,7 +2473,7 @@ int main() css_node_t *node_0 = root_layout; node_0->layout.position[CSS_TOP] = 0; node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 33; + node_0->layout.dimensions[CSS_WIDTH] = 34.671875; node_0->layout.dimensions[CSS_HEIGHT] = 18; } @@ -2505,14 +2505,6 @@ int main() css_node_t *root_node = new_test_css_node(); { css_node_t *node_0 = root_node; - node_0->style.margin[CSS_LEFT] = 5; - node_0->style.margin[CSS_TOP] = 5; - node_0->style.margin[CSS_RIGHT] = 5; - node_0->style.margin[CSS_BOTTOM] = 5; - node_0->style.padding[CSS_LEFT] = 5; - node_0->style.padding[CSS_TOP] = 5; - node_0->style.padding[CSS_RIGHT] = 5; - node_0->style.padding[CSS_BOTTOM] = 5; node_0->measure = measure; node_0->context = "loooooooooong with space"; } @@ -2520,10 +2512,10 @@ int main() css_node_t *root_layout = new_test_css_node(); { css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 5; - node_0->layout.position[CSS_LEFT] = 5; - node_0->layout.dimensions[CSS_WIDTH] = 181; - node_0->layout.dimensions[CSS_HEIGHT] = 28; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 172.421875; + node_0->layout.dimensions[CSS_HEIGHT] = 18; } test("should layout node with text, padding and margin", root_node, root_layout); @@ -2759,7 +2751,7 @@ int main() node_1 = node_0->get_child(node_0->context, 0); node_1->layout.position[CSS_TOP] = 0; node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_WIDTH] = 100.453125; node_1->layout.dimensions[CSS_HEIGHT] = 36; } } @@ -2807,7 +2799,7 @@ int main() node_1 = node_0->get_child(node_0->context, 0); node_1->layout.position[CSS_TOP] = 20; node_1->layout.position[CSS_LEFT] = 20; - node_1->layout.dimensions[CSS_WIDTH] = 100; + node_1->layout.dimensions[CSS_WIDTH] = 100.453125; node_1->layout.dimensions[CSS_HEIGHT] = 36; init_css_node_children(node_1, 1); { @@ -2815,7 +2807,7 @@ int main() node_2 = node_1->get_child(node_1->context, 0); node_2->layout.position[CSS_TOP] = 0; node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 100; + node_2->layout.dimensions[CSS_WIDTH] = 100.453125; node_2->layout.dimensions[CSS_HEIGHT] = 36; } } @@ -2946,7 +2938,7 @@ int main() node_2 = node_1->get_child(node_1->context, 0); node_2->layout.position[CSS_TOP] = 20; node_2->layout.position[CSS_LEFT] = 20; - node_2->layout.dimensions[CSS_WIDTH] = 171; + node_2->layout.dimensions[CSS_WIDTH] = 172.421875; node_2->layout.dimensions[CSS_HEIGHT] = 18; } } @@ -3130,6 +3122,49 @@ int main() test("should layout with negative flex", root_node, root_layout); } + { + css_node_t *root_node = new_test_css_node(); + { + css_node_t *node_0 = root_node; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->style.dimensions[CSS_WIDTH] = 50; + node_1->style.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->style.position_type = CSS_POSITION_ABSOLUTE; + node_1->style.position[CSS_LEFT] = 0; + node_1->style.position[CSS_RIGHT] = 0; + } + } + + css_node_t *root_layout = new_test_css_node(); + { + css_node_t *node_0 = root_layout; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 50; + node_0->layout.dimensions[CSS_HEIGHT] = 100; + init_css_node_children(node_0, 2); + { + css_node_t *node_1; + node_1 = node_0->get_child(node_0->context, 0); + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 50; + node_1->layout.dimensions[CSS_HEIGHT] = 100; + node_1 = node_0->get_child(node_0->context, 1); + node_1->layout.position[CSS_TOP] = 100; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 50; + node_1->layout.dimensions[CSS_HEIGHT] = 0; + } + } + + test("should layout with ne3gative flex", root_node, root_layout); + } + { css_node_t *root_node = new_test_css_node(); { @@ -3164,7 +3199,6 @@ int main() { css_node_t *node_1; node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; node_1->measure = measure; node_1->context = "loooooooooong with space"; } @@ -3290,7 +3324,7 @@ int main() css_node_t *node_0 = root_layout; node_0->layout.position[CSS_TOP] = 18; node_0->layout.position[CSS_LEFT] = -5; - node_0->layout.dimensions[CSS_WIDTH] = 194; + node_0->layout.dimensions[CSS_WIDTH] = 195.421875; node_0->layout.dimensions[CSS_HEIGHT] = 338; } @@ -3383,7 +3417,7 @@ int main() css_node_t *node_0 = root_layout; node_0->layout.position[CSS_TOP] = 10; node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 46; + node_0->layout.dimensions[CSS_WIDTH] = 47.671875; node_0->layout.dimensions[CSS_HEIGHT] = 116; init_css_node_children(node_0, 2); { @@ -3391,7 +3425,7 @@ int main() node_1 = node_0->get_child(node_0->context, 0); node_1->layout.position[CSS_TOP] = 25; node_1->layout.position[CSS_LEFT] = -7; - node_1->layout.dimensions[CSS_WIDTH] = 35; + node_1->layout.dimensions[CSS_WIDTH] = 36.671875; node_1->layout.dimensions[CSS_HEIGHT] = 633; node_1 = node_0->get_child(node_0->context, 1); node_1->layout.position[CSS_TOP] = 3; @@ -3512,7 +3546,7 @@ int main() css_node_t *node_0 = root_layout; node_0->layout.position[CSS_TOP] = 4; node_0->layout.position[CSS_LEFT] = 13; - node_0->layout.dimensions[CSS_WIDTH] = 109; + node_0->layout.dimensions[CSS_WIDTH] = 110.671875; node_0->layout.dimensions[CSS_HEIGHT] = 757; init_css_node_children(node_0, 1); { @@ -3520,7 +3554,7 @@ int main() node_1 = node_0->get_child(node_0->context, 0); node_1->layout.position[CSS_TOP] = 35.5; node_1->layout.position[CSS_LEFT] = 6; - node_1->layout.dimensions[CSS_WIDTH] = 80; + node_1->layout.dimensions[CSS_WIDTH] = 81.671875; node_1->layout.dimensions[CSS_HEIGHT] = 669; init_css_node_children(node_1, 1); { @@ -3528,7 +3562,7 @@ int main() node_2 = node_1->get_child(node_1->context, 0); node_2->layout.position[CSS_TOP] = 37; node_2->layout.position[CSS_LEFT] = 21; - node_2->layout.dimensions[CSS_WIDTH] = 38; + node_2->layout.dimensions[CSS_WIDTH] = 39.671875; node_2->layout.dimensions[CSS_HEIGHT] = 626; } } @@ -3658,7 +3692,7 @@ int main() css_node_t *node_0 = root_layout; node_0->layout.position[CSS_TOP] = 6; node_0->layout.position[CSS_LEFT] = 2; - node_0->layout.dimensions[CSS_WIDTH] = 187; + node_0->layout.dimensions[CSS_WIDTH] = 188.421875; node_0->layout.dimensions[CSS_HEIGHT] = 948; } @@ -3720,7 +3754,7 @@ int main() css_node_t *node_0 = root_layout; node_0->layout.position[CSS_TOP] = 0; node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 171; + node_0->layout.dimensions[CSS_WIDTH] = 172.421875; node_0->layout.dimensions[CSS_HEIGHT] = 36; init_css_node_children(node_0, 1); { @@ -3728,7 +3762,7 @@ int main() node_1 = node_0->get_child(node_0->context, 0); node_1->layout.position[CSS_TOP] = 0; node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 171; + node_1->layout.dimensions[CSS_WIDTH] = 172.421875; node_1->layout.dimensions[CSS_HEIGHT] = 36; init_css_node_children(node_1, 1); { @@ -4006,7 +4040,7 @@ int main() css_node_t *node_0 = root_layout; node_0->layout.position[CSS_TOP] = 7; node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 45; + node_0->layout.dimensions[CSS_WIDTH] = 46.671875; node_0->layout.dimensions[CSS_HEIGHT] = 605; } @@ -4391,7 +4425,7 @@ int main() css_node_t *node_0 = root_layout; node_0->layout.position[CSS_TOP] = 6; node_0->layout.position[CSS_LEFT] = -2; - node_0->layout.dimensions[CSS_WIDTH] = 171; + node_0->layout.dimensions[CSS_WIDTH] = 172.421875; node_0->layout.dimensions[CSS_HEIGHT] = 635; } @@ -4663,7 +4697,7 @@ int main() css_node_t *node_0 = root_layout; node_0->layout.position[CSS_TOP] = 17; node_0->layout.position[CSS_LEFT] = 16; - node_0->layout.dimensions[CSS_WIDTH] = 171; + node_0->layout.dimensions[CSS_WIDTH] = 172.421875; node_0->layout.dimensions[CSS_HEIGHT] = 712; } @@ -4724,7 +4758,7 @@ int main() css_node_t *node_0 = root_layout; node_0->layout.position[CSS_TOP] = -10; node_0->layout.position[CSS_LEFT] = -15; - node_0->layout.dimensions[CSS_WIDTH] = 171; + node_0->layout.dimensions[CSS_WIDTH] = 172.421875; node_0->layout.dimensions[CSS_HEIGHT] = 335; } @@ -4878,8 +4912,8 @@ int main() css_node_t *node_2; node_2 = node_1->get_child(node_1->context, 0); node_2->layout.position[CSS_TOP] = 31; - node_2->layout.position[CSS_LEFT] = 806; - node_2->layout.dimensions[CSS_WIDTH] = 115; + node_2->layout.position[CSS_LEFT] = 804.328125; + node_2->layout.dimensions[CSS_WIDTH] = 116.671875; node_2->layout.dimensions[CSS_HEIGHT] = 898; init_css_node_children(node_2, 1); { @@ -4887,7 +4921,7 @@ int main() node_3 = node_2->get_child(node_2->context, 0); node_3->layout.position[CSS_TOP] = 1; node_3->layout.position[CSS_LEFT] = 6; - node_3->layout.dimensions[CSS_WIDTH] = 103; + node_3->layout.dimensions[CSS_WIDTH] = 104.671875; node_3->layout.dimensions[CSS_HEIGHT] = 274; init_css_node_children(node_3, 2); { @@ -4900,7 +4934,7 @@ int main() node_4 = node_3->get_child(node_3->context, 1); node_4->layout.position[CSS_TOP] = 208; node_4->layout.position[CSS_LEFT] = 34; - node_4->layout.dimensions[CSS_WIDTH] = 53; + node_4->layout.dimensions[CSS_WIDTH] = 54.671875; node_4->layout.dimensions[CSS_HEIGHT] = 37; } } @@ -4908,12 +4942,12 @@ int main() node_1 = node_0->get_child(node_0->context, 1); node_1->layout.position[CSS_TOP] = 33; node_1->layout.position[CSS_LEFT] = 23; - node_1->layout.dimensions[CSS_WIDTH] = 47; + node_1->layout.dimensions[CSS_WIDTH] = 48.671875; node_1->layout.dimensions[CSS_HEIGHT] = 49; node_1 = node_0->get_child(node_0->context, 2); node_1->layout.position[CSS_TOP] = 31.5; - node_1->layout.position[CSS_LEFT] = 66; - node_1->layout.dimensions[CSS_WIDTH] = 33; + node_1->layout.position[CSS_LEFT] = 67.671875; + node_1->layout.dimensions[CSS_WIDTH] = 34.671875; node_1->layout.dimensions[CSS_HEIGHT] = 46; } } @@ -4973,7 +5007,7 @@ int main() css_node_t *node_0 = root_layout; node_0->layout.position[CSS_TOP] = 0; node_0->layout.position[CSS_LEFT] = -12; - node_0->layout.dimensions[CSS_WIDTH] = 33; + node_0->layout.dimensions[CSS_WIDTH] = 34.671875; node_0->layout.dimensions[CSS_HEIGHT] = 861; } @@ -5136,72 +5170,11 @@ int main() { css_node_t *node_0 = root_node; node_0->style.align_items = CSS_ALIGN_CENTER; - node_0->style.dimensions[CSS_WIDTH] = 632; - node_0->style.dimensions[CSS_HEIGHT] = 810; - node_0->style.margin[CSS_LEFT] = 1; - node_0->style.margin[CSS_TOP] = 1; - node_0->style.margin[CSS_RIGHT] = 1; - node_0->style.margin[CSS_BOTTOM] = 1; - node_0->style.margin[CSS_LEFT] = -9; - node_0->style.margin[CSS_TOP] = 10; - node_0->style.padding[CSS_BOTTOM] = 1; - node_0->style.border[CSS_RIGHT] = 3; - node_0->style.position[CSS_LEFT] = -4; init_css_node_children(node_0, 2); { css_node_t *node_1; node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN; - node_1->style.margin[CSS_TOP] = 15; - node_1->style.padding[CSS_TOP] = 0; - node_1->style.padding[CSS_BOTTOM] = 12; - node_1->style.border[CSS_LEFT] = 1; - node_1->style.border[CSS_TOP] = 1; - node_1->style.border[CSS_RIGHT] = 1; - node_1->style.border[CSS_BOTTOM] = 1; - node_1->style.border[CSS_TOP] = 2; - node_1->style.position[CSS_LEFT] = -5; - init_css_node_children(node_1, 2); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.justify_content = CSS_JUSTIFY_CENTER; - node_2->style.align_self = CSS_ALIGN_CENTER; - node_2->style.position_type = CSS_POSITION_ABSOLUTE; - node_2->style.dimensions[CSS_HEIGHT] = 674; - node_2->style.margin[CSS_RIGHT] = 11; - node_2->style.padding[CSS_LEFT] = 4; - node_2->style.padding[CSS_RIGHT] = 10; - node_2->style.border[CSS_LEFT] = 2; - node_2->style.border[CSS_TOP] = 1; - node_2->style.border[CSS_BOTTOM] = 1; - node_2->style.position[CSS_LEFT] = 6; - node_2 = node_1->get_child(node_1->context, 1); - node_2->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_2->style.justify_content = CSS_JUSTIFY_FLEX_START; - node_2->style.dimensions[CSS_WIDTH] = 811; - node_2->style.margin[CSS_TOP] = -5; - node_2->style.padding[CSS_LEFT] = 16; - node_2->style.padding[CSS_TOP] = 16; - node_2->style.padding[CSS_RIGHT] = 16; - node_2->style.padding[CSS_BOTTOM] = 16; - node_2->style.border[CSS_LEFT] = 0; - node_2->measure = measure; - node_2->context = "small"; - } node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_1->style.justify_content = CSS_JUSTIFY_CENTER; - node_1->style.dimensions[CSS_HEIGHT] = 51; - node_1->style.margin[CSS_TOP] = -4; - node_1->style.margin[CSS_RIGHT] = 14; - node_1->style.padding[CSS_LEFT] = 3; - node_1->style.padding[CSS_TOP] = 3; - node_1->style.padding[CSS_RIGHT] = 3; - node_1->style.padding[CSS_BOTTOM] = 3; - node_1->style.padding[CSS_LEFT] = 11; - node_1->style.padding[CSS_BOTTOM] = 18; - node_1->style.position[CSS_LEFT] = -9; node_1->measure = measure; node_1->context = "loooooooooong with space"; } @@ -5210,37 +5183,23 @@ int main() css_node_t *root_layout = new_test_css_node(); { css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 10; - node_0->layout.position[CSS_LEFT] = -13; - node_0->layout.dimensions[CSS_WIDTH] = 632; - node_0->layout.dimensions[CSS_HEIGHT] = 810; + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 172.421875; + node_0->layout.dimensions[CSS_HEIGHT] = 18; init_css_node_children(node_0, 2); { css_node_t *node_1; node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 15; - node_1->layout.position[CSS_LEFT] = -97; - node_1->layout.dimensions[CSS_WIDTH] = 813; - node_1->layout.dimensions[CSS_HEIGHT] = 60; - init_css_node_children(node_1, 2); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 2; - node_2->layout.position[CSS_LEFT] = 7; - node_2->layout.dimensions[CSS_WIDTH] = 16; - node_2->layout.dimensions[CSS_HEIGHT] = 674; - node_2 = node_1->get_child(node_1->context, 1); - node_2->layout.position[CSS_TOP] = -3; - node_2->layout.position[CSS_LEFT] = 1; - node_2->layout.dimensions[CSS_WIDTH] = 811; - node_2->layout.dimensions[CSS_HEIGHT] = 50; - } + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 86.203125; + node_1->layout.dimensions[CSS_WIDTH] = 0; + node_1->layout.dimensions[CSS_HEIGHT] = 0; node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 71; - node_1->layout.position[CSS_LEFT] = 206; - node_1->layout.dimensions[CSS_WIDTH] = 185; - node_1->layout.dimensions[CSS_HEIGHT] = 51; + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 172.421875; + node_1->layout.dimensions[CSS_HEIGHT] = 18; } } @@ -5403,85 +5362,13 @@ int main() css_node_t *root_node = new_test_css_node(); { css_node_t *node_0 = root_node; - node_0->style.justify_content = CSS_JUSTIFY_CENTER; - node_0->style.align_items = CSS_ALIGN_CENTER; - node_0->style.margin[CSS_TOP] = 7; - node_0->style.padding[CSS_LEFT] = 8; - node_0->style.padding[CSS_TOP] = 8; - node_0->style.padding[CSS_RIGHT] = 8; - node_0->style.padding[CSS_BOTTOM] = 8; - node_0->style.padding[CSS_BOTTOM] = 18; - node_0->style.border[CSS_RIGHT] = 0; - node_0->style.position[CSS_LEFT] = 8; - node_0->style.position[CSS_TOP] = 1; - init_css_node_children(node_0, 4); + init_css_node_children(node_0, 2); { css_node_t *node_1; node_1 = node_0->get_child(node_0->context, 0); - node_1->style.justify_content = CSS_JUSTIFY_FLEX_END; - node_1->style.align_items = CSS_ALIGN_CENTER; - node_1->style.align_self = CSS_ALIGN_STRETCH; - node_1->style.dimensions[CSS_HEIGHT] = 952; - node_1->style.margin[CSS_LEFT] = 17; - node_1->style.margin[CSS_TOP] = 17; - node_1->style.margin[CSS_RIGHT] = 17; - node_1->style.margin[CSS_BOTTOM] = 17; - node_1->style.margin[CSS_TOP] = 1; - node_1->style.margin[CSS_RIGHT] = 0; - node_1->style.padding[CSS_LEFT] = 11; - node_1->style.padding[CSS_TOP] = 11; - node_1->style.padding[CSS_RIGHT] = 11; - node_1->style.padding[CSS_BOTTOM] = 11; - node_1->style.padding[CSS_BOTTOM] = 11; - node_1->style.border[CSS_BOTTOM] = 2; - node_1->style.position[CSS_TOP] = 4; + node_1->style.dimensions[CSS_WIDTH] = 1000; node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_1->style.justify_content = CSS_JUSTIFY_SPACE_AROUND; - node_1->style.dimensions[CSS_WIDTH] = 229; - node_1->style.margin[CSS_LEFT] = 1; - node_1->style.margin[CSS_TOP] = 1; - node_1->style.margin[CSS_RIGHT] = 1; - node_1->style.margin[CSS_BOTTOM] = 1; - node_1->style.margin[CSS_TOP] = 12; - node_1->style.margin[CSS_RIGHT] = -2; - node_1->style.padding[CSS_RIGHT] = 14; - node_1->style.border[CSS_LEFT] = 3; - node_1->style.border[CSS_TOP] = 0; - node_1->style.border[CSS_BOTTOM] = 3; - node_1->style.position[CSS_TOP] = -3; - node_1->measure = measure; - node_1->context = "loooooooooong with space"; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_1->style.justify_content = CSS_JUSTIFY_SPACE_AROUND; - node_1->style.align_self = CSS_ALIGN_FLEX_END; - node_1->style.dimensions[CSS_WIDTH] = 971; - node_1->style.margin[CSS_LEFT] = 15; - node_1->style.margin[CSS_TOP] = 1; - node_1->style.padding[CSS_LEFT] = 0; - node_1->style.padding[CSS_TOP] = 0; - node_1->style.padding[CSS_RIGHT] = 0; - node_1->style.padding[CSS_BOTTOM] = 0; - node_1->measure = measure; - node_1->context = "small"; - node_1 = node_0->get_child(node_0->context, 3); - node_1->style.justify_content = CSS_JUSTIFY_FLEX_END; node_1->style.align_self = CSS_ALIGN_CENTER; - node_1->style.margin[CSS_LEFT] = 0; - node_1->style.margin[CSS_TOP] = 0; - node_1->style.margin[CSS_RIGHT] = 0; - node_1->style.margin[CSS_BOTTOM] = 0; - node_1->style.margin[CSS_RIGHT] = 7; - node_1->style.padding[CSS_BOTTOM] = 16; - node_1->style.border[CSS_LEFT] = 0; - node_1->style.border[CSS_TOP] = 0; - node_1->style.border[CSS_RIGHT] = 0; - node_1->style.border[CSS_BOTTOM] = 0; - node_1->style.border[CSS_LEFT] = 2; - node_1->style.border[CSS_TOP] = 1; - node_1->style.border[CSS_RIGHT] = 0; - node_1->style.position[CSS_TOP] = -5; node_1->measure = measure; node_1->context = "small"; } @@ -5490,33 +5377,23 @@ int main() css_node_t *root_layout = new_test_css_node(); { css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 8; - node_0->layout.position[CSS_LEFT] = 8; - node_0->layout.dimensions[CSS_WIDTH] = 1002; - node_0->layout.dimensions[CSS_HEIGHT] = 1084; - init_css_node_children(node_0, 4); + node_0->layout.position[CSS_TOP] = 0; + node_0->layout.position[CSS_LEFT] = 0; + node_0->layout.dimensions[CSS_WIDTH] = 1000; + node_0->layout.dimensions[CSS_HEIGHT] = 18; + init_css_node_children(node_0, 2); { css_node_t *node_1; node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 13; - node_1->layout.position[CSS_LEFT] = 25; - node_1->layout.dimensions[CSS_WIDTH] = 969; - node_1->layout.dimensions[CSS_HEIGHT] = 952; + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 0; + node_1->layout.dimensions[CSS_WIDTH] = 1000; + node_1->layout.dimensions[CSS_HEIGHT] = 0; node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 987; - node_1->layout.position[CSS_LEFT] = 388; - node_1->layout.dimensions[CSS_WIDTH] = 229; - node_1->layout.dimensions[CSS_HEIGHT] = 21; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 1013; - node_1->layout.position[CSS_LEFT] = 23; - node_1->layout.dimensions[CSS_WIDTH] = 971; + node_1->layout.position[CSS_TOP] = 0; + node_1->layout.position[CSS_LEFT] = 482.65625; + node_1->layout.dimensions[CSS_WIDTH] = 34.671875; node_1->layout.dimensions[CSS_HEIGHT] = 18; - node_1 = node_0->get_child(node_0->context, 3); - node_1->layout.position[CSS_TOP] = 1026; - node_1->layout.position[CSS_LEFT] = 480; - node_1->layout.dimensions[CSS_WIDTH] = 35; - node_1->layout.dimensions[CSS_HEIGHT] = 35; } } @@ -5764,7 +5641,7 @@ int main() node_2 = node_1->get_child(node_1->context, 0); node_2->layout.position[CSS_TOP] = 0; node_2->layout.position[CSS_LEFT] = 6; - node_2->layout.dimensions[CSS_WIDTH] = 211; + node_2->layout.dimensions[CSS_WIDTH] = 212.421875; node_2->layout.dimensions[CSS_HEIGHT] = 193; init_css_node_children(node_2, 3); { @@ -5772,12 +5649,12 @@ int main() node_3 = node_2->get_child(node_2->context, 0); node_3->layout.position[CSS_TOP] = 7; node_3->layout.position[CSS_LEFT] = 11; - node_3->layout.dimensions[CSS_WIDTH] = 177; + node_3->layout.dimensions[CSS_WIDTH] = 178.421875; node_3->layout.dimensions[CSS_HEIGHT] = 32; node_3 = node_2->get_child(node_2->context, 1); node_3->layout.position[CSS_TOP] = 49; - node_3->layout.position[CSS_LEFT] = 53; - node_3->layout.dimensions[CSS_WIDTH] = 92; + node_3->layout.position[CSS_LEFT] = 52.875; + node_3->layout.dimensions[CSS_WIDTH] = 93.671875; node_3->layout.dimensions[CSS_HEIGHT] = 128; init_css_node_children(node_3, 2); { @@ -5785,7 +5662,7 @@ int main() node_4 = node_3->get_child(node_3->context, 0); node_4->layout.position[CSS_TOP] = 26; node_4->layout.position[CSS_LEFT] = 18; - node_4->layout.dimensions[CSS_WIDTH] = 49; + node_4->layout.dimensions[CSS_WIDTH] = 50.671875; node_4->layout.dimensions[CSS_HEIGHT] = 96; node_4 = node_3->get_child(node_3->context, 1); node_4->layout.position[CSS_TOP] = 123; @@ -5805,7 +5682,7 @@ int main() node_3 = node_2->get_child(node_2->context, 2); node_3->layout.position[CSS_TOP] = 183; node_3->layout.position[CSS_LEFT] = 17; - node_3->layout.dimensions[CSS_WIDTH] = 196; + node_3->layout.dimensions[CSS_WIDTH] = 197.421875; node_3->layout.dimensions[CSS_HEIGHT] = 18; } } @@ -5930,7 +5807,7 @@ int main() css_node_t *node_0 = root_layout; node_0->layout.position[CSS_TOP] = 20; node_0->layout.position[CSS_LEFT] = -5; - node_0->layout.dimensions[CSS_WIDTH] = 187; + node_0->layout.dimensions[CSS_WIDTH] = 188.421875; node_0->layout.dimensions[CSS_HEIGHT] = 20; } @@ -6260,7 +6137,7 @@ int main() css_node_t *node_0 = root_layout; node_0->layout.position[CSS_TOP] = -13; node_0->layout.position[CSS_LEFT] = 18; - node_0->layout.dimensions[CSS_WIDTH] = 171; + node_0->layout.dimensions[CSS_WIDTH] = 172.421875; node_0->layout.dimensions[CSS_HEIGHT] = 20; } @@ -6440,7 +6317,7 @@ int main() css_node_t *node_0 = root_layout; node_0->layout.position[CSS_TOP] = 4; node_0->layout.position[CSS_LEFT] = -1; - node_0->layout.dimensions[CSS_WIDTH] = 36; + node_0->layout.dimensions[CSS_WIDTH] = 37.671875; node_0->layout.dimensions[CSS_HEIGHT] = 21; } @@ -6467,7 +6344,7 @@ int main() css_node_t *node_0 = root_layout; node_0->layout.position[CSS_TOP] = 0; node_0->layout.position[CSS_LEFT] = -8; - node_0->layout.dimensions[CSS_WIDTH] = 33; + node_0->layout.dimensions[CSS_WIDTH] = 34.671875; node_0->layout.dimensions[CSS_HEIGHT] = 20; } @@ -6580,7 +6457,7 @@ int main() css_node_t *node_0 = root_layout; node_0->layout.position[CSS_TOP] = 3; node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 35; + node_0->layout.dimensions[CSS_WIDTH] = 36.671875; node_0->layout.dimensions[CSS_HEIGHT] = 863; } diff --git a/src/__tests__/Layout-test.js b/src/__tests__/Layout-test.js index f73995ac..d40358ae 100755 --- a/src/__tests__/Layout-test.js +++ b/src/__tests__/Layout-test.js @@ -945,6 +945,19 @@ describe('Layout', function() { ); }); + it('should layout with ne3gative flex', function() { + testLayout( + {style: {}, children: [ + {style: {width: 50, height: 100}}, + {style: {position: 'absolute', left: 0, right: 0}} + ]}, + {width: 50, height: 100, top: 0, left: 0, children: [ + {width: 50, height: 100, top: 0, left: 0}, + {width: 50, height: 0, top: 100, left: 0}, + ]} + ); + }); + xit('should layout text with alignItems: stretch', function() { testLayout( {style: {width: 80, padding: 7, alignItems: 'stretch', measure: text(texts.big)}}, diff --git a/src/transpile.html b/src/transpile.html index 179a4f9c..9a838e86 100644 --- a/src/transpile.html +++ b/src/transpile.html @@ -53,7 +53,9 @@ var layoutTestUtils = { computeLayout: computeLayout, computeDOMLayout: computeDOMLayout, reduceTest: reduceTest, - text: text + text: text, + texts: layoutTestUtils.texts, + textSizes: layoutTestUtils.textSizes, }; function describe(name, cb) { cb(); } function it(name, cb) { currentTest = name; cb(); } -- 2.50.1.windows.1 From b91bc8b3fc804b5708ebf9c068b9e90a738c17f9 Mon Sep 17 00:00:00 2001 From: Andrew Rasmussen Date: Thu, 25 Sep 2014 16:21:20 -0700 Subject: [PATCH 2/4] rename position: absolute bottom test case --- src/__tests__/Layout-test.c | 2 +- src/__tests__/Layout-test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/__tests__/Layout-test.c b/src/__tests__/Layout-test.c index 4e7ce09e..d6340b9c 100644 --- a/src/__tests__/Layout-test.c +++ b/src/__tests__/Layout-test.c @@ -3162,7 +3162,7 @@ int main() } } - test("should layout with ne3gative flex", root_node, root_layout); + test("should layout with absolutely position bottom", root_node, root_layout); } { diff --git a/src/__tests__/Layout-test.js b/src/__tests__/Layout-test.js index d40358ae..4dcd29d5 100755 --- a/src/__tests__/Layout-test.js +++ b/src/__tests__/Layout-test.js @@ -945,7 +945,7 @@ describe('Layout', function() { ); }); - it('should layout with ne3gative flex', function() { + it('should layout with absolutely position bottom', function() { testLayout( {style: {}, children: [ {style: {width: 50, height: 100}}, -- 2.50.1.windows.1 From e506416fa3b91d4c9907b59cccf5a3c6b6927828 Mon Sep 17 00:00:00 2001 From: Andrew Rasmussen Date: Thu, 25 Sep 2014 17:56:02 -0700 Subject: [PATCH 3/4] aggregate test failures and print a summary after running tests --- src/Layout-test-utils.c | 68 ++++++++++++++++++++++++++++++++----- src/Layout-test-utils.h | 1 + src/Layout-test-utils.js | 3 ++ src/__tests__/Layout-test.c | 2 ++ src/transpile.html | 2 ++ 5 files changed, 67 insertions(+), 9 deletions(-) diff --git a/src/Layout-test-utils.c b/src/Layout-test-utils.c index e90a4c2e..b71dd4ce 100644 --- a/src/Layout-test-utils.c +++ b/src/Layout-test-utils.c @@ -2,6 +2,30 @@ #include "Layout-test-utils.h" #include +typedef struct failed_test_t { + struct failed_test_t *next; + const char *name; + css_node_t *style; + css_node_t *expected; +} failed_test_t; + +static failed_test_t *failed_test_head = NULL; +static failed_test_t *failed_test_tail = NULL; +static void add_failed_test(const char *name, css_node_t *style, css_node_t *expected) { + failed_test_t *failed_test = malloc(sizeof(failed_test_t)); + failed_test->name = name; + failed_test->style = style; + failed_test->expected = expected; + + if (!failed_test_head) { + failed_test_head = failed_test; + failed_test_tail = failed_test; + } else { + failed_test_tail->next = failed_test; + failed_test_tail = failed_test; + } +} + static bool eq(float a, float b) { return fabs(a - b) < 0.0001; } @@ -49,21 +73,47 @@ void test(const char *name, css_node_t *style, css_node_t *expected_layout) { layoutNode(style, CSS_UNDEFINED); if (!are_layout_equal(style, expected_layout)) { - printf("%sFAIL%s %s\n", "\x1B[31m", "\x1B[0m", name); + printf("%sF%s", "\x1B[31m", "\x1B[0m"); + add_failed_test(name, style, expected_layout); + } else { + printf("%s.%s", "\x1B[32m", "\x1B[0m"); + free_css_node(style); + free_css_node(expected_layout); + } +} + +void tests_finished() { + failed_test_t *failed_test = failed_test_head; + printf("\n"); + + int tests_failed = 0; + while (failed_test) { + printf("%sFAIL%s %s\n", "\x1B[31m", "\x1B[0m", failed_test->name); printf("Input: "); - print_css_node(style, CSS_PRINT_STYLE); + print_css_node(failed_test->style, CSS_PRINT_STYLE); printf("Output: "); - print_css_node(style, CSS_PRINT_LAYOUT); + print_css_node(failed_test->style, CSS_PRINT_LAYOUT); printf("Expected: "); - print_css_node(expected_layout, CSS_PRINT_LAYOUT); - } else { - printf("%sPASS%s %s\n", "\x1B[32m", "\x1B[0m", name); - } + print_css_node(failed_test->expected, CSS_PRINT_LAYOUT); - free_css_node(style); - free_css_node(expected_layout); + free_css_node(failed_test->style); + free_css_node(failed_test->expected); + + failed_test_t *next_failed_test = failed_test->next; + free(failed_test); + failed_test = next_failed_test; + + tests_failed++; + } + printf("\n\n"); + + if (tests_failed > 0) { + printf("TESTS FAILED: %d\n", tests_failed); + } else { + printf("ALL TESTS PASSED\n"); + } } static css_node_t* get_child(void *context, int i) { diff --git a/src/Layout-test-utils.h b/src/Layout-test-utils.h index 5cba72c5..216d0b00 100644 --- a/src/Layout-test-utils.h +++ b/src/Layout-test-utils.h @@ -5,6 +5,7 @@ #include void test(const char *name, css_node_t *style, css_node_t *expected_layout); +void tests_finished(void); css_dim_t measure(void *context, float width); void init_css_node_children(css_node_t *node, int children_count); css_node_t *new_test_css_node(void); diff --git a/src/Layout-test-utils.js b/src/Layout-test-utils.js index 960bf9b8..1f43099b 100644 --- a/src/Layout-test-utils.js +++ b/src/Layout-test-utils.js @@ -283,6 +283,9 @@ var layoutTestUtils = (function() { expect({i: i, node: node, layout: computeCSSLayout(node)}) .toEqual({i: i, node: node, layout: computeDOMLayout(node)}); }, + testsFinished: function() { + console.log('tests finished!'); + }, computeLayout: computeCSSLayout, computeDOMLayout: computeDOMLayout, reduceTest: reduceTest, diff --git a/src/__tests__/Layout-test.c b/src/__tests__/Layout-test.c index d6340b9c..b362580e 100644 --- a/src/__tests__/Layout-test.c +++ b/src/__tests__/Layout-test.c @@ -6525,4 +6525,6 @@ int main() test("Random #99", root_node, root_layout); } + + tests_finished(); } diff --git a/src/transpile.html b/src/transpile.html index 9a838e86..e515acd7 100644 --- a/src/transpile.html +++ b/src/transpile.html @@ -237,6 +237,8 @@ function printLayout(test) { add('test("' + test.name.replace(/"/g, '\\"') + '", root_node, root_layout);'); level--; add('}'); + add(''); + add('tests_finished();'); return res.join('\n'); } -- 2.50.1.windows.1 From 2e954232d99682dfbd8ee63597c1784a1431aa72 Mon Sep 17 00:00:00 2001 From: Alex Kotliarskyi Date: Fri, 26 Sep 2014 16:00:56 -0700 Subject: [PATCH 4/4] Split JS tests into manual and random --- RunLayoutRandomTests.html | 22 ++++++ SpecRunner.html => RunLayoutTests.html | 0 src/__tests__/Layout-random-test.js | 99 ++++++++++++++++++++++++++ src/__tests__/Layout-test.js | 88 ----------------------- 4 files changed, 121 insertions(+), 88 deletions(-) create mode 100644 RunLayoutRandomTests.html rename SpecRunner.html => RunLayoutTests.html (100%) create mode 100644 src/__tests__/Layout-random-test.js diff --git a/RunLayoutRandomTests.html b/RunLayoutRandomTests.html new file mode 100644 index 00000000..0fddf6ab --- /dev/null +++ b/RunLayoutRandomTests.html @@ -0,0 +1,22 @@ + + + + + Jasmine Spec Runner v2.0.0 + + + + + + + + + + + + + + + + + diff --git a/SpecRunner.html b/RunLayoutTests.html similarity index 100% rename from SpecRunner.html rename to RunLayoutTests.html diff --git a/src/__tests__/Layout-random-test.js b/src/__tests__/Layout-random-test.js new file mode 100644 index 00000000..4218e08a --- /dev/null +++ b/src/__tests__/Layout-random-test.js @@ -0,0 +1,99 @@ +/* globals layoutTestUtils */ +var testRandomLayout = layoutTestUtils.testRandomLayout; +var computeLayout = layoutTestUtils.computeLayout; +var computeDOMLayout = layoutTestUtils.computeDOMLayout; +var reduceTest = layoutTestUtils.reduceTest; +var text = layoutTestUtils.text; +var texts = layoutTestUtils.texts; + +describe('Random layout', function() { + + function RNG(seed) { + this.state = seed; + } + RNG.prototype.nextFloat = function() { + // LCG using GCC's constants + this.state = (1103515245 * this.state + 12345) % 0x80000000; + return this.state / (0x80000000 - 1); + }; + + var rng = new RNG(0); + function randMinMax(node, chance, attribute, min, max) { + if (rng.nextFloat() < chance) { + if (attribute === 'right' || attribute === 'bottom') { + return; + } + node.style[attribute] = Math.floor(rng.nextFloat() * (max - min)) + min; + } + } + function randEnum(node, chance, attribute, enumValues) { + if (rng.nextFloat() < chance) { + node.style[attribute] = enumValues[Math.floor(rng.nextFloat() * enumValues.length)]; + } + } + function randChildren(node, chance) { + while (rng.nextFloat() < chance) { + if (!node.children) { + node.children = []; + } + node.children.push(generateRandomNode()); + } + } + function randSpacing(node, chance, type, suffix, min, max) { + randMinMax(node, chance, type + suffix, min, max); + randMinMax(node, chance, type + 'Left' + suffix, min, max); + randMinMax(node, chance, type + 'Top' + suffix, min, max); + randMinMax(node, chance, type + 'Right' + suffix, min, max); + randMinMax(node, chance, type + 'Bottom' + suffix, min, max); + } + function generateRandomNode() { + var node = {style: {}}; + randMinMax(node, 0.5, 'width', -100, 1000); + randMinMax(node, 0.5, 'height', -100, 1000); + randMinMax(node, 0.5, 'top', -10, 10); + randMinMax(node, 0.5, 'left', -10, 10); + randMinMax(node, 0.5, 'right', -10, 10); + randMinMax(node, 0.5, 'bottom', -10, 10); + randSpacing(node, 0.5, 'margin', '', -10, 20); + randSpacing(node, 0.5, 'padding', '', -10, 20); + randSpacing(node, 0.5, 'border', 'Width', -4, 4); + randMinMax(node, 0.5, 'flex', -10, 10); + randEnum(node, 0.5, 'flexDirection', ['column', 'row']); + randEnum(node, 0.5, 'justifyContent', ['flex-start', 'center', 'flex-end', 'space-between', 'space-around']); + randEnum(node, 0.5, 'alignItems', ['flex-start', 'center', 'flex-end', 'stretch']); + randEnum(node, 0.5, 'alignSelf', ['flex-start', 'center', 'flex-end', 'stretch']); + randEnum(node, 0.5, 'position', ['relative', 'absolute']); + randEnum(node, 0.5, 'measure', [text(texts.small), text(texts.big)]); + + if (node.style.measure) { + // align-items: stretch on a text node makes it wrap in a different way. + // We don't yet support this use case + delete node.style.alignItems; + + // Text that is position: absolute behaves very strangely + delete node.style.position; + } + + randChildren(node, 0.4); + return node; + } + + for (var i = 0; i < 100; ++i) { + var node = generateRandomNode(); + it('should layout randomly #' + i +'.', function(node) { + if (JSON.stringify(computeLayout(node)) !== JSON.stringify(computeDOMLayout(node))) { + node = reduceTest(node); + } + + // The iframe's body has a natural width of 300 that it doesn't really make + // to replicate in the test suite. The easiest workaround is not to test + // alignSelf, position and flex properties on the root element. + delete node.style.alignSelf; + delete node.style.flex; + delete node.style.position; + + testRandomLayout(node, i); + }.bind(this, node)); + } + +}); diff --git a/src/__tests__/Layout-test.js b/src/__tests__/Layout-test.js index f73995ac..fc893c67 100755 --- a/src/__tests__/Layout-test.js +++ b/src/__tests__/Layout-test.js @@ -963,93 +963,5 @@ describe('Layout', function() { ); }); - it('should layout randomly', function() { - function RNG(seed) { - this.state = seed; - } - RNG.prototype.nextFloat = function() { - // LCG using GCC's constants - this.state = (1103515245 * this.state + 12345) % 0x80000000; - return this.state / (0x80000000 - 1); - }; - - var rng = new RNG(0); - function randMinMax(node, chance, attribute, min, max) { - if (rng.nextFloat() < chance) { - if (attribute === 'right' || attribute === 'bottom') { - return; - } - node.style[attribute] = Math.floor(rng.nextFloat() * (max - min)) + min; - } - } - function randEnum(node, chance, attribute, enumValues) { - if (rng.nextFloat() < chance) { - node.style[attribute] = enumValues[Math.floor(rng.nextFloat() * enumValues.length)]; - } - } - function randChildren(node, chance) { - while (rng.nextFloat() < chance) { - if (!node.children) { - node.children = []; - } - node.children.push(generateRandomNode()); - } - } - function randSpacing(node, chance, type, suffix, min, max) { - randMinMax(node, chance, type + suffix, min, max); - randMinMax(node, chance, type + 'Left' + suffix, min, max); - randMinMax(node, chance, type + 'Top' + suffix, min, max); - randMinMax(node, chance, type + 'Right' + suffix, min, max); - randMinMax(node, chance, type + 'Bottom' + suffix, min, max); - } - function generateRandomNode() { - var node = {style: {}}; - randMinMax(node, 0.5, 'width', -100, 1000); - randMinMax(node, 0.5, 'height', -100, 1000); - randMinMax(node, 0.5, 'top', -10, 10); - randMinMax(node, 0.5, 'left', -10, 10); - randMinMax(node, 0.5, 'right', -10, 10); - randMinMax(node, 0.5, 'bottom', -10, 10); - randSpacing(node, 0.5, 'margin', '', -10, 20); - randSpacing(node, 0.5, 'padding', '', -10, 20); - randSpacing(node, 0.5, 'border', 'Width', -4, 4); - randMinMax(node, 0.5, 'flex', -10, 10); - randEnum(node, 0.5, 'flexDirection', ['column', 'row']); - randEnum(node, 0.5, 'justifyContent', ['flex-start', 'center', 'flex-end', 'space-between', 'space-around']); - randEnum(node, 0.5, 'alignItems', ['flex-start', 'center', 'flex-end', 'stretch']); - randEnum(node, 0.5, 'alignSelf', ['flex-start', 'center', 'flex-end', 'stretch']); - randEnum(node, 0.5, 'position', ['relative', 'absolute']); - randEnum(node, 0.5, 'measure', [text(texts.small), text(texts.big)]); - - if (node.style.measure) { - // align-items: stretch on a text node makes it wrap in a different way. - // We don't yet support this use case - delete node.style.alignItems; - - // Text that is position: absolute behaves very strangely - delete node.style.position; - } - - randChildren(node, 0.4); - return node; - } - - for (var i = 0; i < 100; ++i) { - var node = generateRandomNode(); - if (JSON.stringify(computeLayout(node)) !== JSON.stringify(computeDOMLayout(node))) { - node = reduceTest(node); - } - - // The iframe's body has a natural width of 300 that it doesn't really make - // to replicate in the test suite. The easiest workaround is not to test - // alignSelf, position and flex properties on the root element. - delete node.style.alignSelf; - delete node.style.flex; - delete node.style.position; - - testRandomLayout(node, i); - } - }) - }); -- 2.50.1.windows.1