diff --git a/gentest/fixtures/CSSLayoutAbsolutePositionTest.html b/gentest/fixtures/CSSLayoutAbsolutePositionTest.html
new file mode 100644
index 00000000..bb6e5673
--- /dev/null
+++ b/gentest/fixtures/CSSLayoutAbsolutePositionTest.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
diff --git a/gentest/fixtures/CSSLayoutAlignContentTest.html b/gentest/fixtures/CSSLayoutAlignContentTest.html
new file mode 100644
index 00000000..e0ead38f
--- /dev/null
+++ b/gentest/fixtures/CSSLayoutAlignContentTest.html
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
diff --git a/gentest/fixtures/CSSLayoutAlignItemsTest.html b/gentest/fixtures/CSSLayoutAlignItemsTest.html
new file mode 100644
index 00000000..e040b9ed
--- /dev/null
+++ b/gentest/fixtures/CSSLayoutAlignItemsTest.html
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
diff --git a/gentest/fixtures/CSSLayoutAlignSelfTest.html b/gentest/fixtures/CSSLayoutAlignSelfTest.html
new file mode 100644
index 00000000..047de30c
--- /dev/null
+++ b/gentest/fixtures/CSSLayoutAlignSelfTest.html
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
diff --git a/gentest/fixtures/CSSLayoutBorderTest.html b/gentest/fixtures/CSSLayoutBorderTest.html
new file mode 100644
index 00000000..9a65dc16
--- /dev/null
+++ b/gentest/fixtures/CSSLayoutBorderTest.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/gentest/fixtures/CSSLayoutFlexDirectionTest.html b/gentest/fixtures/CSSLayoutFlexDirectionTest.html
new file mode 100644
index 00000000..69dc5527
--- /dev/null
+++ b/gentest/fixtures/CSSLayoutFlexDirectionTest.html
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gentest/fixtures/CSSLayoutFlexTest.html b/gentest/fixtures/CSSLayoutFlexTest.html
new file mode 100644
index 00000000..5689a6e7
--- /dev/null
+++ b/gentest/fixtures/CSSLayoutFlexTest.html
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gentest/fixtures/CSSLayoutFlexWrapTest.html b/gentest/fixtures/CSSLayoutFlexWrapTest.html
new file mode 100644
index 00000000..7bb48cc9
--- /dev/null
+++ b/gentest/fixtures/CSSLayoutFlexWrapTest.html
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
diff --git a/gentest/fixtures/CSSLayoutJustifyContentTest.html b/gentest/fixtures/CSSLayoutJustifyContentTest.html
new file mode 100644
index 00000000..16c0dcc6
--- /dev/null
+++ b/gentest/fixtures/CSSLayoutJustifyContentTest.html
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gentest/fixtures/CSSLayoutMarginTest.html b/gentest/fixtures/CSSLayoutMarginTest.html
new file mode 100644
index 00000000..a71bb641
--- /dev/null
+++ b/gentest/fixtures/CSSLayoutMarginTest.html
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gentest/fixtures/CSSLayoutMinMaxDimensionTest.html b/gentest/fixtures/CSSLayoutMinMaxDimensionTest.html
new file mode 100644
index 00000000..d2925c04
--- /dev/null
+++ b/gentest/fixtures/CSSLayoutMinMaxDimensionTest.html
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gentest/fixtures/CSSLayoutPaddingTest.html b/gentest/fixtures/CSSLayoutPaddingTest.html
new file mode 100644
index 00000000..1f679780
--- /dev/null
+++ b/gentest/fixtures/CSSLayoutPaddingTest.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/gentest/gentest-cpp.js b/gentest/gentest-cpp.js
new file mode 100644
index 00000000..dc0427b9
--- /dev/null
+++ b/gentest/gentest-cpp.js
@@ -0,0 +1,203 @@
+/**
+ * Copyright (c) 2014-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+var CPPEmitter = function() {
+ Emitter.call(this, 'cpp', ' ');
+};
+
+CPPEmitter.prototype = Object.create(Emitter.prototype, {
+ constructor:{value:CPPEmitter},
+
+ emitPrologue:{value:function() {
+ this.push([
+ '#include ',
+ '#include ',
+ '',
+ ]);
+ }},
+
+ emitTestPrologue:{value:function(name) {
+ this.push('TEST(CSSLayoutTest, ' + name + ') {');
+ this.pushIndent();
+ }},
+
+ emitTestTreePrologue:{value:function(nodeName) {
+ this.push('const CSSNodeRef ' + nodeName + ' = CSSNodeNew();');
+ }},
+
+ emitTestEpilogue:{value:function() {
+ this.push([
+ '',
+ 'CSSNodeFreeRecursive(root);',
+ ]);
+ this.popIndent();
+ this.push([
+ '}',
+ '',
+ ]);
+ }},
+
+ emitEpilogue:{value:function() {
+ }},
+
+ AssertEQ:{value:function(v0, v1) {
+ this.push('ASSERT_EQ(' + v0 + ', ' + v1 + ');');
+ }},
+
+ CSSAlignAuto:{value:'CSSAlignAuto'},
+ CSSAlignCenter:{value:'CSSAlignCenter'},
+ CSSAlignFlexEnd:{value:'CSSAlignFlexEnd'},
+ CSSAlignFlexStart:{value:'CSSAlignFlexStart'},
+ CSSAlignStretch:{value:'CSSAlignStretch'},
+
+ CSSDirectionInherit:{value:'CSSDirectionInherit'},
+ CSSDirectionLTR:{value:'CSSDirectionLTR'},
+ CSSDirectionRTL:{value:'CSSDirectionRTL'},
+
+ CSSEdgeBottom:{value:'CSSEdgeBottom'},
+ CSSEdgeEnd:{value:'CSSEdgeEnd'},
+ CSSEdgeLeft:{value:'CSSEdgeLeft'},
+ CSSEdgeRight:{value:'CSSEdgeRight'},
+ CSSEdgeStart:{value:'CSSEdgeStart'},
+ CSSEdgeTop:{value:'CSSEdgeTop'},
+
+ CSSFlexDirectionColumn:{value:'CSSFlexDirectionColumn'},
+ CSSFlexDirectionColumnReverse:{value:'CSSFlexDirectionColumnReverse'},
+ CSSFlexDirectionRow:{value:'CSSFlexDirectionRow'},
+ CSSFlexDirectionRowReverse:{value:'CSSFlexDirectionRowReverse'},
+
+ CSSJustifyCenter:{value:'CSSJustifyCenter'},
+ CSSJustifyFlexEnd:{value:'CSSJustifyFlexEnd'},
+ CSSJustifyFlexStart:{value:'CSSJustifyFlexStart'},
+ CSSJustifySpaceAround:{value:'CSSJustifySpaceAround'},
+ CSSJustifySpaceBetween:{value:'CSSJustifySpaceBetween'},
+
+ CSSOverflowHidden:{value:'CSSOverflowHidden'},
+ CSSOverflowVisible:{value:'CSSOverflowVisible'},
+
+ CSSPositionTypeAbsolute:{value:'CSSPositionTypeAbsolute'},
+ CSSPositionTypeRelative:{value:'CSSPositionTypeRelative'},
+
+ CSSWrapTypeNoWrap:{value:'CSSWrapTypeNoWrap'},
+ CSSWrapTypeWrap:{value:'CSSWrapTypeWrap'},
+
+ CSSUndefined:{value:'CSSUndefined'},
+
+ CSSNodeCalculateLayout:{value:function(node, dir) {
+ this.push('CSSNodeCalculateLayout(' + node + ', CSSUndefined, CSSUndefined, ' + dir + ');');
+ }},
+
+ CSSNodeInsertChild:{value:function(parentName, nodeName, index) {
+ this.push('CSSNodeInsertChild(' + parentName + ', ' + nodeName + ', ' + index + ');');
+ }},
+
+ CSSNodeLayoutGetLeft:{value:function(nodeName) {
+ return 'CSSNodeLayoutGetLeft(' + nodeName + ')';
+ }},
+
+ CSSNodeLayoutGetTop:{value:function(nodeName) {
+ return 'CSSNodeLayoutGetTop(' + nodeName + ')';
+ }},
+
+ CSSNodeLayoutGetWidth:{value:function(nodeName) {
+ return 'CSSNodeLayoutGetWidth(' + nodeName + ')';
+ }},
+
+ CSSNodeLayoutGetHeight:{value:function(nodeName) {
+ return 'CSSNodeLayoutGetHeight(' + nodeName + ')';
+ }},
+
+ CSSNodeStyleSetAlignContent:{value:function(nodeName, value) {
+ this.push('CSSNodeStyleSetAlignContent(' + nodeName + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetAlignItems:{value:function(nodeName, value) {
+ this.push('CSSNodeStyleSetAlignItems(' + nodeName + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetAlignSelf:{value:function(nodeName, value) {
+ this.push('CSSNodeStyleSetAlignSelf(' + nodeName + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetBorder:{value:function(nodeName, edge, value) {
+ this.push('CSSNodeStyleSetBorder(' + nodeName + ', ' + edge + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetDirection:{value:function(nodeName, value) {
+ this.push('CSSNodeStyleSetDirection(' + nodeName + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetFlexBasis:{value:function(nodeName, value) {
+ this.push('CSSNodeStyleSetFlexBasis(' + nodeName + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetFlexDirection:{value:function(nodeName, value) {
+ this.push('CSSNodeStyleSetFlexDirection(' + nodeName + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetFlexGrow:{value:function(nodeName, value) {
+ this.push('CSSNodeStyleSetFlexGrow(' + nodeName + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetFlexShrink:{value:function(nodeName, value) {
+ this.push('CSSNodeStyleSetFlexShrink(' + nodeName + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetFlexWrap:{value:function(nodeName, value) {
+ this.push('CSSNodeStyleSetFlexWrap(' + nodeName + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetHeight:{value:function(nodeName, value) {
+ this.push('CSSNodeStyleSetHeight(' + nodeName + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetJustifyContent:{value:function(nodeName, value) {
+ this.push('CSSNodeStyleSetJustifyContent(' + nodeName + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetMargin:{value:function(nodeName, edge, value) {
+ this.push('CSSNodeStyleSetMargin(' + nodeName + ', ' + edge + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetMaxHeight:{value:function(nodeName, value) {
+ this.push('CSSNodeStyleSetMaxHeight(' + nodeName + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetMaxWidth:{value:function(nodeName, value) {
+ this.push('CSSNodeStyleSetMaxWidth(' + nodeName + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetMinHeight:{value:function(nodeName, value) {
+ this.push('CSSNodeStyleSetMinHeight(' + nodeName + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetMinWidth:{value:function(nodeName, value) {
+ this.push('CSSNodeStyleSetMinWidth(' + nodeName + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetOverflow:{value:function(nodeName, value) {
+ this.push('CSSNodeStyleSetOverflow(' + nodeName + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetPadding:{value:function(nodeName, edge, value) {
+ this.push('CSSNodeStyleSetPadding(' + nodeName + ', ' + edge + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetPosition:{value:function(nodeName, edge, value) {
+ this.push('CSSNodeStyleSetPosition(' + nodeName + ', ' + edge + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetPositionType:{value:function(nodeName, value) {
+ this.push('CSSNodeStyleSetPositionType(' + nodeName + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetWidth:{value:function(nodeName, value) {
+ this.push('CSSNodeStyleSetWidth(' + nodeName + ', ' + value + ');');
+ }},
+});
diff --git a/gentest/gentest-cs.js b/gentest/gentest-cs.js
new file mode 100644
index 00000000..c2046ef0
--- /dev/null
+++ b/gentest/gentest-cs.js
@@ -0,0 +1,218 @@
+/**
+ * Copyright (c) 2014-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+var CSEmitter = function() {
+ Emitter.call(this, 'cs', ' ');
+};
+
+CSEmitter.prototype = Object.create(Emitter.prototype, {
+ constructor:{value:CSEmitter},
+
+ emitPrologue:{value:function() {
+ this.push([
+ 'using System;',
+ 'using NUnit.Framework;',
+ '',
+ 'namespace Facebook.CSSLayout',
+ '{',
+ ]);
+ this.pushIndent();
+ this.push([
+ '[TestFixture]',
+ 'public class CSSNodeLayoutTest',
+ '{',
+ ]);
+ this.pushIndent();
+ }},
+
+ emitTestPrologue:{value:function(name) {
+ this.push('[Test]');
+ this.push('public void Test_' + name + '()');
+ this.push('{');
+ this.pushIndent();
+ }},
+
+ emitTestTreePrologue:{value:function(nodeName) {
+ this.push('CSSNode ' + nodeName + ' = new CSSNode();');
+ }},
+
+ emitTestEpilogue:{value:function() {
+ this.popIndent();
+ this.push([
+ '}',
+ '',
+ ]);
+ }},
+
+ emitEpilogue:{value:function(lines) {
+ this.popIndent();
+ this.push('}');
+ this.popIndent();
+ this.push([
+ '}',
+ '',
+ ]);
+ }},
+
+ AssertEQ:{value:function(v0, v1) {
+ this.push('Assert.AreEqual(' + v0 + ', ' + v1 + ');');
+ }},
+
+ CSSAlignAuto:{value:'CSSAlign.Auto'},
+ CSSAlignCenter:{value:'CSSAlign.Center'},
+ CSSAlignFlexEnd:{value:'CSSAlign.FlexEnd'},
+ CSSAlignFlexStart:{value:'CSSAlign.FlexStart'},
+ CSSAlignStretch:{value:'CSSAlign.Stretch'},
+
+ CSSDirectionInherit:{value:'CSSDirection.Inherit'},
+ CSSDirectionLTR:{value:'CSSDirection.LeftToRight'},
+ CSSDirectionRTL:{value:'CSSDirection.RightToLeft'},
+
+ CSSEdgeBottom:{value:'CSSEdge.Bottom'},
+ CSSEdgeEnd:{value:'CSSEdge.End'},
+ CSSEdgeLeft:{value:'CSSEdge.Left'},
+ CSSEdgeRight:{value:'CSSEdge.Right'},
+ CSSEdgeStart:{value:'CSSEdge.Start'},
+ CSSEdgeTop:{value:'CSSEdge.Top'},
+
+ CSSFlexDirectionColumn:{value:'CSSFlexDirection.Column'},
+ CSSFlexDirectionColumnReverse:{value:'CSSFlexDirection.ColumnReverse'},
+ CSSFlexDirectionRow:{value:'CSSFlexDirection.Row'},
+ CSSFlexDirectionRowReverse:{value:'CSSFlexDirection.RowReverse'},
+
+ CSSJustifyCenter:{value:'CSSJustify.Center'},
+ CSSJustifyFlexEnd:{value:'CSSJustify.FlexEnd'},
+ CSSJustifyFlexStart:{value:'CSSJustify.FlexStart'},
+ CSSJustifySpaceAround:{value:'CSSJustify.SpaceAround'},
+ CSSJustifySpaceBetween:{value:'CSSJustify.SpaceBetween'},
+
+ CSSOverflowHidden:{value:'CSSOverflow.Hidden'},
+ CSSOverflowVisible:{value:'CSSOverflow.Visible'},
+
+ CSSPositionTypeAbsolute:{value:'CSSPositionType.Absolute'},
+ CSSPositionTypeRelative:{value:'CSSPositionType.Relative'},
+
+ CSSUndefined:{value:'CSSConstants.Undefined'},
+
+ CSSWrapTypeNoWrap:{value:'CSSWrap.NoWrap'},
+ CSSWrapTypeWrap:{value:'CSSWrap.Wrap'},
+
+ CSSNodeCalculateLayout:{value:function(node, dir) {
+ this.push(node + '.StyleDirection = ' + dir + ';');
+ this.push(node + '.CalculateLayout();');
+ }},
+
+ CSSNodeInsertChild:{value:function(parentName, nodeName, index) {
+ this.push(parentName + '.Insert(' + index + ', ' + nodeName + ');');
+ }},
+
+ CSSNodeLayoutGetLeft:{value:function(nodeName) {
+ return nodeName + '.LayoutX';
+ }},
+
+ CSSNodeLayoutGetTop:{value:function(nodeName) {
+ return nodeName + '.LayoutY';
+ }},
+
+ CSSNodeLayoutGetWidth:{value:function(nodeName) {
+ return nodeName + '.LayoutWidth';
+ }},
+
+ CSSNodeLayoutGetHeight:{value:function(nodeName) {
+ return nodeName + '.LayoutHeight';
+ }},
+
+ CSSNodeStyleSetAlignContent:{value:function(nodeName, value) {
+ this.push(nodeName + '.AlignContent = ' + value + ';');
+ }},
+
+ CSSNodeStyleSetAlignItems:{value:function(nodeName, value) {
+ this.push(nodeName + '.AlignItems = ' + value + ';');
+ }},
+
+ CSSNodeStyleSetAlignSelf:{value:function(nodeName, value) {
+ this.push(nodeName + '.AlignSelf = ' + value + ';');
+ }},
+
+ CSSNodeStyleSetBorder:{value:function(nodeName, edge, value) {
+ this.push(nodeName + '.SetBorder(' + edge + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetDirection:{value:function(nodeName, value) {
+ this.push(nodeName + '.StyleDirection = ' + value + ';');
+ }},
+
+ CSSNodeStyleSetFlexBasis:{value:function(nodeName, value) {
+ this.push(nodeName + '.FlexBasis = ' + value + ';');
+ }},
+
+ CSSNodeStyleSetFlexDirection:{value:function(nodeName, value) {
+ this.push(nodeName + '.FlexDirection = ' + value + ';');
+ }},
+
+ CSSNodeStyleSetFlexGrow:{value:function(nodeName, value) {
+ this.push(nodeName + '.FlexGrow = ' + value + ';');
+ }},
+
+ CSSNodeStyleSetFlexShrink:{value:function(nodeName, value) {
+ this.push(nodeName + '.FlexShrink = ' + value + ';');
+ }},
+
+ CSSNodeStyleSetFlexWrap:{value:function(nodeName, value) {
+ this.push(nodeName + '.Wrap = ' + value + ';');
+ }},
+
+ CSSNodeStyleSetHeight:{value:function(nodeName, value) {
+ this.push(nodeName + '.StyleHeight = ' + value + ';');
+ }},
+
+ CSSNodeStyleSetJustifyContent:{value:function(nodeName, value) {
+ this.push(nodeName + '.JustifyContent = ' + value + ';');
+ }},
+
+ CSSNodeStyleSetMargin:{value:function(nodeName, edge, value) {
+ this.push(nodeName + '.SetMargin(' + edge + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetMaxHeight:{value:function(nodeName, value) {
+ this.push(nodeName + '.StyleMaxHeight = ' + value + ';');
+ }},
+
+ CSSNodeStyleSetMaxWidth:{value:function(nodeName, value) {
+ this.push(nodeName + '.StyleMaxWidth = ' + value + ';');
+ }},
+
+ CSSNodeStyleSetMinHeight:{value:function(nodeName, value) {
+ this.push(nodeName + '.StyleMinHeight = ' + value + ';');
+ }},
+
+ CSSNodeStyleSetMinWidth:{value:function(nodeName, value) {
+ this.push(nodeName + '.StyleMinWidth = ' + value + ';');
+ }},
+
+ CSSNodeStyleSetOverflow:{value:function(nodeName, value) {
+ this.push(nodeName + '.Overflow = ' + value + ';');
+ }},
+
+ CSSNodeStyleSetPadding:{value:function(nodeName, edge, value) {
+ this.push(nodeName + '.SetPadding(' + edge + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetPosition:{value:function(nodeName, edge, value) {
+ this.push(nodeName + '.SetPosition(' + edge + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetPositionType:{value:function(nodeName, value) {
+ this.push(nodeName + '.PositionType = ' + value + ';');
+ }},
+
+ CSSNodeStyleSetWidth:{value:function(nodeName, value) {
+ this.push(nodeName + '.StyleWidth = ' + value + ';');
+ }},
+});
diff --git a/gentest/gentest-java.js b/gentest/gentest-java.js
new file mode 100644
index 00000000..f1dbb06b
--- /dev/null
+++ b/gentest/gentest-java.js
@@ -0,0 +1,211 @@
+/**
+ * Copyright (c) 2014-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+var JavaEmitter = function() {
+ Emitter.call(this, 'java', ' ');
+};
+
+JavaEmitter.prototype = Object.create(Emitter.prototype, {
+ constructor:{value:JavaEmitter},
+
+ emitPrologue:{value:function() {
+ this.push([
+ 'package com.facebook.csslayout;',
+ '',
+ 'import org.junit.Test;',
+ '',
+ 'import static org.junit.Assert.assertEquals;',
+ '',
+ 'public class CSSNodeLayoutTest {',
+ ]);
+ this.pushIndent();
+ }},
+
+ emitTestPrologue:{value:function(name) {
+ this.push('@Test');
+ this.push('public void test_' + name + '() {');
+ this.pushIndent();
+ }},
+
+ emitTestTreePrologue:{value:function(nodeName) {
+ this.push('final CSSNode ' + nodeName + ' = new CSSNode();');
+ }},
+
+ emitTestEpilogue:{value:function() {
+ this.popIndent();
+ this.push([
+ '}',
+ '',
+ ]);
+ }},
+
+ emitEpilogue:{value:function(lines) {
+ this.popIndent();
+ this.push([
+ '}',
+ '',
+ ]);
+ }},
+
+ AssertEQ:{value:function(v0, v1) {
+ this.push('assertEquals(' + v0 + ', ' + v1 + ', 0.0f);');
+ }},
+
+ CSSAlignAuto:{value:'CSSAlign.AUTO'},
+ CSSAlignCenter:{value:'CSSAlign.CENTER'},
+ CSSAlignFlexEnd:{value:'CSSAlign.FLEX_END'},
+ CSSAlignFlexStart:{value:'CSSAlign.FLEX_START'},
+ CSSAlignStretch:{value:'CSSAlign.STRETCH'},
+
+ CSSDirectionInherit:{value:'CSSDirection.INHERIT'},
+ CSSDirectionLTR:{value:'CSSDirection.LTR'},
+ CSSDirectionRTL:{value:'CSSDirection.RTL'},
+
+ CSSEdgeBottom:{value:'Spacing.BOTTOM'},
+ CSSEdgeEnd:{value:'Spacing.END'},
+ CSSEdgeLeft:{value:'Spacing.LEFT'},
+ CSSEdgeRight:{value:'Spacing.RIGHT'},
+ CSSEdgeStart:{value:'Spacing.START'},
+ CSSEdgeTop:{value:'Spacing.TOP'},
+
+ CSSFlexDirectionColumn:{value:'CSSFlexDirection.COLUMN'},
+ CSSFlexDirectionColumnReverse:{value:'CSSFlexDirection.COLUMN_REVERSE'},
+ CSSFlexDirectionRow:{value:'CSSFlexDirection.ROW'},
+ CSSFlexDirectionRowReverse:{value:'CSSFlexDirection.ROW_REVERSE'},
+
+ CSSJustifyCenter:{value:'CSSJustify.CENTER'},
+ CSSJustifyFlexEnd:{value:'CSSJustify.FLEX_END'},
+ CSSJustifyFlexStart:{value:'CSSJustify.FLEX_START'},
+ CSSJustifySpaceAround:{value:'CSSJustify.SPACE_AROUND'},
+ CSSJustifySpaceBetween:{value:'CSSJustify.SPACE_BETWEEN'},
+
+ CSSOverflowHidden:{value:'CSSOverflow.HIDDEN'},
+ CSSOverflowVisible:{value:'CSSOverflow.VISIBLE'},
+
+ CSSPositionTypeAbsolute:{value:'CSSPositionType.ABSOLUTE'},
+ CSSPositionTypeRelative:{value:'CSSPositionType.RELATIVE'},
+
+ CSSUndefined:{value:'CSSConstants.UNDEFINED'},
+
+ CSSWrapTypeNoWrap:{value:'CSSWrap.NO_WRAP'},
+ CSSWrapTypeWrap:{value:'CSSWrap.WRAP'},
+
+ CSSNodeCalculateLayout:{value:function(node, dir) {
+ this.push(node + '.setDirection(' + dir + ');');
+ this.push(node + '.calculateLayout(null);');
+ }},
+
+ CSSNodeInsertChild:{value:function(parentName, nodeName, index) {
+ this.push(parentName + '.addChildAt(' + nodeName + ', ' + index + ');');
+ }},
+
+ CSSNodeLayoutGetLeft:{value:function(nodeName) {
+ return nodeName + '.getLayoutX()';
+ }},
+
+ CSSNodeLayoutGetTop:{value:function(nodeName) {
+ return nodeName + '.getLayoutY()';
+ }},
+
+ CSSNodeLayoutGetWidth:{value:function(nodeName) {
+ return nodeName + '.getLayoutWidth()';
+ }},
+
+ CSSNodeLayoutGetHeight:{value:function(nodeName) {
+ return nodeName + '.getLayoutHeight()';
+ }},
+
+ CSSNodeStyleSetAlignContent:{value:function(nodeName, value) {
+ this.push(nodeName + '.setAlignContent(' + value + ');');
+ }},
+
+ CSSNodeStyleSetAlignItems:{value:function(nodeName, value) {
+ this.push(nodeName + '.setAlignItems(' + value + ');');
+ }},
+
+ CSSNodeStyleSetAlignSelf:{value:function(nodeName, value) {
+ this.push(nodeName + '.setAlignSelf(' + value + ');');
+ }},
+
+ CSSNodeStyleSetBorder:{value:function(nodeName, edge, value) {
+ this.push(nodeName + '.setBorder(' + edge + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetDirection:{value:function(nodeName, value) {
+ this.push(nodeName + '.setDirection(' + value + ');');
+ }},
+
+ CSSNodeStyleSetFlexBasis:{value:function(nodeName, value) {
+ this.push(nodeName + '.setFlexBasis(' + value + ');');
+ }},
+
+ CSSNodeStyleSetFlexDirection:{value:function(nodeName, value) {
+ this.push(nodeName + '.setFlexDirection(' + value + ');');
+ }},
+
+ CSSNodeStyleSetFlexGrow:{value:function(nodeName, value) {
+ this.push(nodeName + '.setFlexGrow(' + value + ');');
+ }},
+
+ CSSNodeStyleSetFlexShrink:{value:function(nodeName, value) {
+ this.push(nodeName + '.setFlexShrink(' + value + ');');
+ }},
+
+ CSSNodeStyleSetFlexWrap:{value:function(nodeName, value) {
+ this.push(nodeName + '.setWrap(' + value + ');');
+ }},
+
+ CSSNodeStyleSetHeight:{value:function(nodeName, value) {
+ this.push(nodeName + '.setStyleHeight(' + value + ');');
+ }},
+
+ CSSNodeStyleSetJustifyContent:{value:function(nodeName, value) {
+ this.push(nodeName + '.setJustifyContent(' + value + ');');
+ }},
+
+ CSSNodeStyleSetMargin:{value:function(nodeName, edge, value) {
+ this.push(nodeName + '.setMargin(' + edge + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetMaxHeight:{value:function(nodeName, value) {
+ this.push(nodeName + '.setStyleMaxHeight(' + value + ');');
+ }},
+
+ CSSNodeStyleSetMaxWidth:{value:function(nodeName, value) {
+ this.push(nodeName + '.setStyleMaxWidth(' + value + ');');
+ }},
+
+ CSSNodeStyleSetMinHeight:{value:function(nodeName, value) {
+ this.push(nodeName + '.setStyleMinHeight(' + value + ');');
+ }},
+
+ CSSNodeStyleSetMinWidth:{value:function(nodeName, value) {
+ this.push(nodeName + '.setStyleMinWidth(' + value + ');');
+ }},
+
+ CSSNodeStyleSetOverflow:{value:function(nodeName, value) {
+ this.push(nodeName + '.setOverflow(' + value + ');');
+ }},
+
+ CSSNodeStyleSetPadding:{value:function(nodeName, edge, value) {
+ this.push(nodeName + '.setPadding(' + edge + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetPosition:{value:function(nodeName, edge, value) {
+ this.push(nodeName + '.setPosition(' + edge + ', ' + value + ');');
+ }},
+
+ CSSNodeStyleSetPositionType:{value:function(nodeName, value) {
+ this.push(nodeName + '.setPositionType(' + value + ');');
+ }},
+
+ CSSNodeStyleSetWidth:{value:function(nodeName, value) {
+ this.push(nodeName + '.setStyleWidth(' + value + ');');
+ }},
+});
diff --git a/gentest/gentest.js b/gentest/gentest.js
index ccd00062..a680a9d0 100755
--- a/gentest/gentest.js
+++ b/gentest/gentest.js
@@ -8,11 +8,35 @@
*/
window.onload = function() {
- printTest(document.body.children[0], document.body.children[1], document.body.children[2]);
+ checkDefaultValues();
+
+ printTest(
+ new CPPEmitter(),
+ document.body.children[0],
+ document.body.children[1],
+ document.body.children[2]);
+
+ printTest(
+ new JavaEmitter(),
+ document.body.children[0],
+ document.body.children[1],
+ document.body.children[2]);
+
+ printTest(
+ new CSEmitter(),
+ document.body.children[0],
+ document.body.children[1],
+ document.body.children[2]);
}
-function printTest(LTRContainer, RTLContainer, genericContainer) {
- var lines = [
+function assert(condition, message) {
+ if (!condition) {
+ throw new Error(message);
+ }
+}
+
+function printTest(e, LTRContainer, RTLContainer, genericContainer) {
+ e.push([
'/**',
' * Copyright (c) 2014-present, Facebook, Inc.',
' * All rights reserved.',
@@ -22,14 +46,13 @@ function printTest(LTRContainer, RTLContainer, genericContainer) {
' * of patent rights can be found in the PATENTS file in the same directory.',
' */',
'',
- ];
-
- lines.push('/**');
- lines.push(' * @Generated by gentest/gentest.sh with the following input');
- lines.push(' *');
+ '/**',
+ ' * @Generated by gentest/gentest.sh with the following input',
+ ' *',
+ ]);
var indentation = 0;
- lines.push(genericContainer.innerHTML.split('\n').map(function(line) {
+ e.push(genericContainer.innerHTML.split('\n').map(function(line) {
return line.trim();
}).filter(function(line) {
return line.length > 0 && line !== '';
@@ -50,81 +73,106 @@ function printTest(LTRContainer, RTLContainer, genericContainer) {
}
return curr + '\n' + prev;
}));
- lines.push(' *');
- lines.push(' */');
- lines.push('');
-
- lines.push([
- '#include ',
- '#include ',
+ e.push([
+ ' *',
+ ' */',
'',
- ].reduce(function(curr, prev) {
- return curr + '\n' + prev;
- }));
+ ]);
+ e.emitPrologue();
var LTRLayoutTree = calculateTree(LTRContainer);
var RTLLayoutTree = calculateTree(RTLContainer);
var genericLayoutTree = calculateTree(genericContainer);
- for (var i = 0; i < genericLayoutTree.length; i++) {
- lines.push('TEST(CSSLayoutTest, ' + genericLayoutTree[i].name + ') {');
- lines.push(' ' + setupTestTree(
+ for (var i = 0; i < genericLayoutTree.length; i++) {
+ e.emitTestPrologue(genericLayoutTree[i].name);
+
+ if (genericLayoutTree[i].name == 'wrap_column') {
+ // Modify width and left values due to both safari and chrome not abiding by the
+ // specification. The undefined dimension of a parent should be defined by the total size
+ // of their children in that dimension.
+ // See diagram under flex-wrap header https://www.w3.org/TR/css-flexbox-1/
+ assert(LTRLayoutTree[0].width == 30, 'wrap_column LTR root.width should be 30');
+ LTRLayoutTree[0].width = 60;
+ assert(RTLLayoutTree[0].width == 30, 'wrap_column RTL root.width should be 30');
+ RTLLayoutTree[0].width = 60;
+ var children = RTLLayoutTree[0].children;
+ assert(children[0].left == 0, 'wrap_column RTL root_child0.left should be 0');
+ children[0].left = 30;
+ assert(children[1].left == 0, 'wrap_column RTL root_child0.left should be 0');
+ children[1].left = 30;
+ assert(children[2].left == 0, 'wrap_column RTL root_child2.left should be 0');
+ children[2].left = 30;
+ assert(children[3].left == -30, 'wrap_column RTL root_child3.left should be -30');
+ children[3].left = 0;
+ }
+
+ setupTestTree(
+ e,
undefined,
LTRLayoutTree[i],
genericLayoutTree[i],
'root',
- null).reduce(function(curr, prev) {
- return curr + '\n ' + prev;
- }));
+ null);
- lines.push(' CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);');
- lines.push('');
+ e.CSSNodeCalculateLayout('root', e.CSSDirectionLTR);
+ e.push('');
- lines.push(' ' + assertTestTree(LTRLayoutTree[i], 'root', null).reduce(function(curr, prev) {
- return curr + '\n ' + prev;
- }));
- lines.push('');
+ assertTestTree(e, LTRLayoutTree[i], 'root', null);
+ e.push('');
- lines.push(' CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL);');
- lines.push('');
+ e.CSSNodeCalculateLayout('root', e.CSSDirectionRTL);
+ e.push('');
- lines.push(' ' + assertTestTree(RTLLayoutTree[i], 'root', null).reduce(function(curr, prev) {
- return curr + '\n ' + prev;
- }));
+ assertTestTree(e, RTLLayoutTree[i], 'root', null);
- lines.push('\n CSSNodeFreeRecursive(root);')
- lines.push('}');
- lines.push('');
+ e.emitTestEpilogue();
}
+ e.emitEpilogue();
- printLines(lines);
+ e.print();
}
-function assertTestTree(node, nodeName, parentName) {
- var lines = [
- 'ASSERT_EQ(' + node.left + ', CSSNodeLayoutGetLeft(' + nodeName + '));',
- 'ASSERT_EQ(' + node.top + ', CSSNodeLayoutGetTop(' + nodeName + '));',
- 'ASSERT_EQ(' + node.width + ', CSSNodeLayoutGetWidth(' + nodeName + '));',
- 'ASSERT_EQ(' + node.height + ', CSSNodeLayoutGetHeight(' + nodeName + '));',
- ];
+function assertTestTree(e, node, nodeName, parentName) {
+ e.AssertEQ(node.left, e.CSSNodeLayoutGetLeft(nodeName));
+ e.AssertEQ(node.top, e.CSSNodeLayoutGetTop(nodeName));
+ e.AssertEQ(node.width, e.CSSNodeLayoutGetWidth(nodeName));
+ e.AssertEQ(node.height, e.CSSNodeLayoutGetHeight(nodeName));
for (var i = 0; i < node.children.length; i++) {
- lines.push('');
+ e.push('');
var childName = nodeName + '_child' + i;
- lines = lines.concat(assertTestTree(node.children[i], childName, nodeName));
+ assertTestTree(e, node.children[i], childName, nodeName);
}
-
- return lines;
}
-function setupTestTree(parent, node, genericNode, nodeName, parentName, index) {
- var lines = [
- 'const CSSNodeRef ' + nodeName + ' = CSSNodeNew();',
- ];
+function checkDefaultValues() {
+ // Sanity check of the CSSLayout default values by test-template.html
+ [
+ {style:'flex-direction', value:'column'},
+ {style:'justify-content', value:'flex-start'},
+ {style:'align-content', value:'flex-start'},
+ {style:'align-items', value:'stretch'},
+ {style:'position', value:'relative'},
+ {style:'flex-wrap', value:'nowrap'},
+ {style:'overflow', value:'visible'},
+ {style:'flex-grow', value:'0'},
+ {style:'flex-shrink', value:'0'},
+ {style:'left', value:'0px'},
+ {style:'top', value:'0px'},
+ {style:'right', value:'0px'},
+ {style:'bottom', value:'0px'},
+ ].forEach(function(item) {
+ assert(item.value === getDefaultStyleValue(item.style),
+ item.style + ' should be ' + item.value);
+ });
+}
+
+function setupTestTree(e, parent, node, genericNode, nodeName, parentName, index) {
+ e.emitTestTreePrologue(nodeName);
for (var style in node.style) {
-
// Skip position info for root as it messes up tests
if (node.declaredStyle[style] === "" &&
(style == 'position' ||
@@ -140,267 +188,225 @@ function setupTestTree(parent, node, genericNode, nodeName, parentName, index) {
if (node.style[style] !== getDefaultStyleValue(style)) {
switch (style) {
case 'direction':
- lines.push('CSSNodeStyleSetDirection(' + nodeName + ', ' +
- directionValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetDirection(nodeName, directionValue(e, node.style[style]));
break;
case 'flex-direction':
- lines.push('CSSNodeStyleSetFlexDirection(' + nodeName + ', ' +
- flexDirectionValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetFlexDirection(nodeName, flexDirectionValue(e, node.style[style]));
break;
case 'justify-content':
- lines.push('CSSNodeStyleSetJustifyContent(' + nodeName + ', ' +
- justifyValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetJustifyContent(nodeName, justifyValue(e, node.style[style]));
break;
case 'align-content':
- lines.push('CSSNodeStyleSetAlignContent(' + nodeName + ', ' +
- alignValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetAlignContent(nodeName, alignValue(e, node.style[style]));
break;
case 'align-items':
- lines.push('CSSNodeStyleSetAlignItems(' + nodeName + ', ' +
- alignValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetAlignItems(nodeName, alignValue(e, node.style[style]));
break;
case 'align-self':
if (!parent || node.style[style] !== parent.style['align-items']) {
- lines.push('CSSNodeStyleSetAlignSelf(' + nodeName + ', ' +
- alignValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetAlignSelf(nodeName, alignValue(e, node.style[style]));
}
break;
case 'position':
- lines.push('CSSNodeStyleSetPositionType(' + nodeName + ', ' +
- positionValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetPositionType(nodeName, positionValue(e, node.style[style]));
break;
case 'flex-wrap':
- lines.push('CSSNodeStyleSetFlexWrap(' + nodeName + ', ' +
- wrapValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetFlexWrap(nodeName, wrapValue(e, node.style[style]));
break;
case 'overflow':
- lines.push('CSSNodeStyleSetOverflow(' + nodeName + ', ' +
- overflowValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetOverflow(nodeName, overflowValue(e, node.style[style]));
break;
case 'flex-grow':
- lines.push('CSSNodeStyleSetFlexGrow(' + nodeName + ', ' + node.style[style] + ');');
+ e.CSSNodeStyleSetFlexGrow(nodeName, node.style[style]);
break;
case 'flex-shrink':
- lines.push('CSSNodeStyleSetFlexShrink(' + nodeName + ', ' + node.style[style] + ');');
+ e.CSSNodeStyleSetFlexShrink(nodeName, node.style[style]);
break;
case 'flex-basis':
- lines.push('CSSNodeStyleSetFlexBasis(' + nodeName + ', ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetFlexBasis(nodeName, pixelValue(e, node.style[style]));
break;
case 'left':
if (genericNode.rawStyle.indexOf('start:') >= 0) {
- lines.push('CSSNodeStyleSetPosition(' + nodeName + ', CSSEdgeStart, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetPosition(nodeName, e.CSSEdgeStart, pixelValue(e, node.style[style]));
} else {
- lines.push('CSSNodeStyleSetPosition(' + nodeName + ', CSSEdgeLeft, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetPosition(nodeName, e.CSSEdgeLeft, pixelValue(e, node.style[style]));
}
break;
case 'top':
- lines.push('CSSNodeStyleSetPosition(' + nodeName + ', CSSEdgeTop, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetPosition(nodeName, e.CSSEdgeTop, pixelValue(e, node.style[style]));
break;
case 'right':
if (genericNode.rawStyle.indexOf('end:') >= 0) {
- lines.push('CSSNodeStyleSetPosition(' + nodeName + ', CSSEdgeEnd, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetPosition(nodeName, e.CSSEdgeEnd, pixelValue(e, node.style[style]));
} else {
- lines.push('CSSNodeStyleSetPosition(' + nodeName + ', CSSEdgeRight, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetPosition(nodeName, e.CSSEdgeRight, pixelValue(e, node.style[style]));
}
break;
case 'bottom':
- lines.push('CSSNodeStyleSetPosition(' + nodeName + ', CSSEdgeBottom, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetPosition(nodeName, e.CSSEdgeBottom, pixelValue(e, node.style[style]));
break;
case 'margin-left':
if (genericNode.rawStyle.indexOf('margin-start:') >= 0) {
- lines.push('CSSNodeStyleSetMargin(' + nodeName + ', CSSEdgeStart, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetMargin(nodeName, e.CSSEdgeStart, pixelValue(e, node.style[style]));
} else {
- lines.push('CSSNodeStyleSetMargin(' + nodeName + ', CSSEdgeLeft, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetMargin(nodeName, e.CSSEdgeLeft, pixelValue(e, node.style[style]));
}
break;
case 'margin-top':
- lines.push('CSSNodeStyleSetMargin(' + nodeName + ', CSSEdgeTop, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetMargin(nodeName, e.CSSEdgeTop, pixelValue(e, node.style[style]));
break;
case 'margin-right':
if (genericNode.rawStyle.indexOf('margin-end:') >= 0) {
- lines.push('CSSNodeStyleSetMargin(' + nodeName + ', CSSEdgeEnd, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetMargin(nodeName, e.CSSEdgeEnd, pixelValue(e, node.style[style]));
} else {
- lines.push('CSSNodeStyleSetMargin(' + nodeName + ', CSSEdgeRight, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetMargin(nodeName, e.CSSEdgeRight, pixelValue(e, node.style[style]));
}
break;
case 'margin-bottom':
- lines.push('CSSNodeStyleSetMargin(' + nodeName + ', CSSEdgeBottom, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetMargin(nodeName, e.CSSEdgeBottom, pixelValue(e, node.style[style]));
break;
case 'padding-left':
if (genericNode.rawStyle.indexOf('padding-start:') >= 0) {
- lines.push('CSSNodeStyleSetPadding(' + nodeName + ', CSSEdgeStart, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetPadding(nodeName, e.CSSEdgeStart, pixelValue(e, node.style[style]));
} else {
- lines.push('CSSNodeStyleSetPadding(' + nodeName + ', CSSEdgeLeft, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetPadding(nodeName, e.CSSEdgeLeft, pixelValue(e, node.style[style]));
}
break;
case 'padding-top':
- lines.push('CSSNodeStyleSetPadding(' + nodeName + ', CSSEdgeTop, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetPadding(nodeName, e.CSSEdgeTop, pixelValue(e, node.style[style]));
break;
case 'padding-right':
if (genericNode.rawStyle.indexOf('padding-end:') >= 0) {
- lines.push('CSSNodeStyleSetPadding(' + nodeName + ', CSSEdgeEnd, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetPadding(nodeName, e.CSSEdgeEnd, pixelValue(e, node.style[style]));
} else {
- lines.push('CSSNodeStyleSetPadding(' + nodeName + ', CSSEdgeRight, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetPadding(nodeName, e.CSSEdgeRight, pixelValue(e, node.style[style]));
}
break;
case 'padding-bottom':
- lines.push('CSSNodeStyleSetPadding(' + nodeName + ', CSSEdgeBottom, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetPadding(nodeName, e.CSSEdgeBottom, pixelValue(e, node.style[style]));
break;
case 'border-left-width':
if (genericNode.rawStyle.indexOf('border-start-width:') >= 0) {
- lines.push('CSSNodeStyleSetBorder(' + nodeName + ', CSSEdgeStart, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetBorder(nodeName, e.CSSEdgeStart, pixelValue(e, node.style[style]));
} else {
- lines.push('CSSNodeStyleSetBorder(' + nodeName + ', CSSEdgeLeft, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetBorder(nodeName, e.CSSEdgeLeft, pixelValue(e, node.style[style]));
}
break;
case 'border-top-width':
- lines.push('CSSNodeStyleSetBorder(' + nodeName + ', CSSEdgeTop, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetBorder(nodeName, e.CSSEdgeTop, pixelValue(e, node.style[style]));
break;
case 'border-right-width':
if (genericNode.rawStyle.indexOf('border-end-width:') >= 0) {
- lines.push('CSSNodeStyleSetBorder(' + nodeName + ', CSSEdgeEnd, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetBorder(nodeName, e.CSSEdgeEnd, pixelValue(e, node.style[style]));
} else {
- lines.push('CSSNodeStyleSetBorder(' + nodeName + ', CSSEdgeRight, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetBorder(nodeName, e.CSSEdgeRight, pixelValue(e, node.style[style]));
}
break;
case 'border-bottom-width':
- lines.push('CSSNodeStyleSetBorder(' + nodeName + ', CSSEdgeBottom, ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetBorder(nodeName, e.CSSEdgeBottom, pixelValue(e, node.style[style]));
break;
case 'width':
- lines.push('CSSNodeStyleSetWidth(' + nodeName + ', ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetWidth(nodeName, pixelValue(e, node.style[style]));
break;
case 'min-width':
- lines.push('CSSNodeStyleSetMinWidth(' + nodeName + ', ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetMinWidth(nodeName, pixelValue(e, node.style[style]));
break;
case 'max-width':
- lines.push('CSSNodeStyleSetMaxWidth(' + nodeName + ', ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetMaxWidth(nodeName, pixelValue(e, node.style[style]));
break;
case 'height':
- lines.push('CSSNodeStyleSetHeight(' + nodeName + ', ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetHeight(nodeName, pixelValue(e, node.style[style]));
break;
case 'min-height':
- lines.push('CSSNodeStyleSetMinHeight(' + nodeName + ', ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetMinHeight(nodeName, pixelValue(e, node.style[style]));
break;
case 'max-height':
- lines.push('CSSNodeStyleSetMaxHeight(' + nodeName + ', ' +
- pixelValue(node.style[style]) + ');');
+ e.CSSNodeStyleSetMaxHeight(nodeName, pixelValue(e, node.style[style]));
break;
}
}
}
if (parentName) {
- lines.push('CSSNodeInsertChild(' + parentName + ', ' + nodeName + ', ' + index + ');');
+ e.CSSNodeInsertChild(parentName, nodeName, index);
}
for (var i = 0; i < node.children.length; i++) {
- lines.push('');
+ e.push('');
var childName = nodeName + '_child' + i;
- lines = lines.concat(
- setupTestTree(
- node,
- node.children[i],
- genericNode.children[i],
- childName,
- nodeName,
- i));
- }
-
- return lines;
-}
-
-function overflowValue(value) {
- switch (value) {
- case 'visible': return 'CSSOverflowVisible';
- case 'hidden': return 'CSSOverflowHidden';
+ setupTestTree(
+ e,
+ node,
+ node.children[i],
+ genericNode.children[i],
+ childName,
+ nodeName,
+ i);
}
}
-function wrapValue(value) {
+function overflowValue(e, value) {
switch (value) {
- case 'wrap': return 'CSSWrapTypeWrap';
- case 'nowrap': return 'CSSWrapTypeNoWrap';
+ case 'visible': return e.CSSOverflowVisible;
+ case 'hidden': return e.CSSOverflowHidden;
}
}
-function flexDirectionValue(value) {
+function wrapValue(e, value) {
switch (value) {
- case 'row': return 'CSSFlexDirectionRow';
- case 'row-reverse': return 'CSSFlexDirectionRowReverse';
- case 'column': return 'CSSFlexDirectionColumn';
- case 'column-reverse': return 'CSSFlexDirectionColumnReverse';
+ case 'wrap': return e.CSSWrapTypeWrap;
+ case 'nowrap': return e.CSSWrapTypeNoWrap;
}
}
-function justifyValue(value) {
+function flexDirectionValue(e, value) {
switch (value) {
- case 'center': return 'CSSJustifyCenter';
- case 'space-around': return 'CSSJustifySpaceAround';
- case 'space-between': return 'CSSJustifySpaceBetween';
- case 'flex-start': return 'CSSJustifyFlexStart';
- case 'flex-end': return 'CSSJustifyFlexEnd';
+ case 'row': return e.CSSFlexDirectionRow;
+ case 'row-reverse': return e.CSSFlexDirectionRowReverse;
+ case 'column': return e.CSSFlexDirectionColumn;
+ case 'column-reverse': return e.CSSFlexDirectionColumnReverse;
}
}
-function positionValue(value) {
+function justifyValue(e, value) {
switch (value) {
- case 'absolute': return 'CSSPositionTypeAbsolute';
- default: return 'CSSPositionTypeRelative'
+ case 'center': return e.CSSJustifyCenter;
+ case 'space-around': return e.CSSJustifySpaceAround;
+ case 'space-between': return e.CSSJustifySpaceBetween;
+ case 'flex-start': return e.CSSJustifyFlexStart;
+ case 'flex-end': return e.CSSJustifyFlexEnd;
}
}
-function directionValue(value) {
+function positionValue(e, value) {
switch (value) {
- case 'ltr': return 'CSSDirectionLTR';
- case 'rtl': return 'CSSDirectionRTL';
- case 'inherit': return 'CSSDirectionInherit';
+ case 'absolute': return e.CSSPositionTypeAbsolute;
+ default: return e.CSSPositionTypeRelative
}
}
-function alignValue(value) {
+function directionValue(e, value) {
switch (value) {
- case 'auto': return 'CSSAlignAuto';
- case 'center': return 'CSSAlignCenter';
- case 'stretch': return 'CSSAlignStretch';
- case 'flex-start': return 'CSSAlignFlexStart';
- case 'flex-end': return 'CSSAlignFlexEnd';
+ case 'ltr': return e.CSSDirectionLTR;
+ case 'rtl': return e.CSSDirectionRTL;
+ case 'inherit': return e.CSSDirectionInherit;
}
}
-function pixelValue(value) {
+function alignValue(e, value) {
switch (value) {
- case 'auto': return 'CSSUndefined';
- case 'undefined': return 'CSSUndefined';
+ case 'auto': return e.CSSAlignAuto;
+ case 'center': return e.CSSAlignCenter;
+ case 'stretch': return e.CSSAlignStretch;
+ case 'flex-start': return e.CSSAlignFlexStart;
+ case 'flex-end': return e.CSSAlignFlexEnd;
+ }
+}
+
+function pixelValue(e, value) {
+ switch (value) {
+ case 'auto': return e.CSSUndefined;
+ case 'undefined': return e.CSSUndefined;
default: return value.replace('px', '');
}
}
@@ -413,14 +419,6 @@ function getDefaultStyleValue(style) {
return getComputedStyle(node, null).getPropertyValue(style);
}
-function printLines(lines) {
- console.log(lines.map(function(value) {
- return value + '\n';
- }).reduce(function(prev, curr) {
- return prev + curr;
- }, ''));
-}
-
function calculateTree(root) {
var rootLayout = [];
@@ -483,3 +481,38 @@ function getCSSLayoutStyle(node) {
return map;
}, {});
}
+
+var Emitter = function(lang, indent) {
+ this.lang = lang;
+ this.indent = indent;
+ this.indents = [];
+ this.lines = [];
+};
+
+Emitter.prototype = Object.create(Object.prototype, {
+ constructor:{value:Emitter},
+
+ pushIndent:{value:function() {
+ this.indents.push(this.indent);
+ }},
+
+ popIndent:{value:function() {
+ this.indents.pop();
+ }},
+
+ push:{value:function(line) {
+ if (line instanceof Array) {
+ line.forEach(function(element) {
+ this.push(element);
+ }, this);
+ return;
+ } else if (line.length > 0) {
+ line = this.indents.join('') + line;
+ }
+ this.lines.push(line);
+ }},
+
+ print:{value:function() {
+ console.log(this.lines.join('\n'));
+ }},
+});
diff --git a/gentest/gentest.rb b/gentest/gentest.rb
new file mode 100644
index 00000000..65139bf9
--- /dev/null
+++ b/gentest/gentest.rb
@@ -0,0 +1,44 @@
+#!/usr/bin/env ruby
+require 'watir-webdriver'
+require 'fileutils'
+caps = Selenium::WebDriver::Remote::Capabilities.chrome(
+ "loggingPrefs"=>{"browser"=>"ALL", "performance"=>"ALL"})
+browser = Watir::Browser.new(:chrome, :desired_capabilities => caps)
+Dir['fixtures/*.html'].each do |file|
+ fixture = File.read(file)
+ name = File.basename(file, '.*')
+ puts "Generate #{name}"
+
+ ltr_fixture = fixture.gsub('start', 'left')
+ .gsub('end', 'right')
+ .gsub('flex-left', 'flex-start')
+ .gsub('flex-right', 'flex-end')
+
+ rtl_fixture = fixture.gsub('start', 'right')
+ .gsub('end', 'left')
+ .gsub('flex-right', 'flex-start')
+ .gsub('flex-left', 'flex-end')
+
+ template = File.open('test-template.html').read
+ f = File.open('test.html', 'w')
+ f.write sprintf(template, ltr_fixture, rtl_fixture, fixture)
+ f.close
+ FileUtils.copy('test.html', "#{name}.html") if $DEBUG
+
+ browser.goto('file://' + Dir.pwd + '/test.html')
+ logs = browser.driver.manage.logs.get(:browser)
+
+ f = File.open("../tests/#{name}.cpp", 'w')
+ f.write eval(logs[0].message.sub(/^[^"]*/, ''))
+ f.close
+
+ f = File.open("../java/tests/com/facebook/csslayout/#{name}.java", 'w')
+ f.write eval(logs[1].message.sub(/^[^"]*/, '')).sub('CSSNodeLayoutTest', name)
+ f.close
+
+ f = File.open("../csharp/tests/Facebook.CSSLayout/#{name}.cs", 'w')
+ f.write eval(logs[2].message.sub(/^[^"]*/, '')).sub('CSSNodeLayoutTest', name)
+ f.close
+end
+File.delete('test.html')
+browser.close
diff --git a/gentest/gentest.sh b/gentest/gentest.sh
deleted file mode 100755
index c19cfeef..00000000
--- a/gentest/gentest.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-rm $(dirname $0)/test.html
-$EDITOR $(dirname $0)/test.html
-
-GENERIC_TEST="$(cat $(dirname $0)/test.html)"
-LTR_TEST="$(cat $(dirname $0)/test.html)"
-RTL_TEST="$(cat $(dirname $0)/test.html)"
-
-LTR_TEST=${LTR_TEST//start/left}
-LTR_TEST=${LTR_TEST//end/right}
-LTR_TEST=${LTR_TEST//flex-left/flex-start}
-LTR_TEST=${LTR_TEST//flex-right/flex-end}
-
-RTL_TEST=${RTL_TEST//start/right}
-RTL_TEST=${RTL_TEST//end/left}
-RTL_TEST=${RTL_TEST//flex-right/flex-start}
-RTL_TEST=${RTL_TEST//flex-left/flex-end}
-
-printf "$(cat $(dirname $0)/test-template.html)" "$LTR_TEST" "$RTL_TEST" "$GENERIC_TEST" > $(dirname $0)/test.html
-open $(dirname $0)/test.html
diff --git a/gentest/test-template.html b/gentest/test-template.html
index 81ea2552..9e0364c3 100644
--- a/gentest/test-template.html
+++ b/gentest/test-template.html
@@ -4,6 +4,9 @@
test page
+
+
+