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); - } - }) - });