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