From dc5e6132852694949131d372e9f6c56052b8a73e Mon Sep 17 00:00:00 2001 From: Kazuki Sakamoto Date: Sun, 23 Oct 2016 10:27:30 -0700 Subject: [PATCH] gentest for Java and C# Summary: - Revise scripts to generate Java and C# unittests using the same HTML fixtures as well as C for code coverage. - Add wrap_column test workaround in gentest.js. - Add checkDefaultValues for sanity check of the CSSLayout default values by test-template.html - Add `align-content: flex-start;` in default div to align with CSSLayout default $ cd csharp/gentest $ ruby gentest.rb - macOS example for C# $ cd csharp/tests/Facebook.CSSLayout $ clang -DCSS_ASSERT_FAIL_ENABLED -Wall -Wextra -dynamiclib -o libCSSLayout.dylib -g -I../../.. ../../../CSSLayout/*.c ../../CSSLayout/CSSInterop.cpp $ mcs -debug -t:library -r:nunit.framework.dll -out:CSSLayoutTest.dll *.cs ../../../csharp/Facebook.CSSLayout/*cs $ mono64 --debug nunit-console.exe CSSLayoutTest.dll Reviewed By: emilsjolander Differential Revision: D4053777 fbshipit-source-id: 84450208015e65baf604987bd56c6a268598b545 --- .../CSSLayoutAbsolutePositionTest.html | 21 + .../fixtures/CSSLayoutAlignContentTest.html | 31 ++ gentest/fixtures/CSSLayoutAlignItemsTest.html | 15 + gentest/fixtures/CSSLayoutAlignSelfTest.html | 15 + gentest/fixtures/CSSLayoutBorderTest.html | 18 + .../fixtures/CSSLayoutFlexDirectionTest.html | 35 ++ gentest/fixtures/CSSLayoutFlexTest.html | 31 ++ gentest/fixtures/CSSLayoutFlexWrapTest.html | 27 ++ .../fixtures/CSSLayoutJustifyContentTest.html | 59 +++ gentest/fixtures/CSSLayoutMarginTest.html | 41 ++ .../CSSLayoutMinMaxDimensionTest.html | 31 ++ gentest/fixtures/CSSLayoutPaddingTest.html | 18 + gentest/gentest-cpp.js | 203 +++++++++ gentest/gentest-cs.js | 218 +++++++++ gentest/gentest-java.js | 211 +++++++++ gentest/gentest.js | 423 ++++++++++-------- gentest/gentest.rb | 44 ++ gentest/gentest.sh | 19 - gentest/test-template.html | 4 + tests/CSSLayoutAlignContentTest.cpp | 1 - tests/CSSLayoutBorderTest.cpp | 1 - tests/CSSLayoutFlexWrapTest.cpp | 5 - tests/CSSLayoutPaddingTest.cpp | 1 - 23 files changed, 1250 insertions(+), 222 deletions(-) create mode 100644 gentest/fixtures/CSSLayoutAbsolutePositionTest.html create mode 100644 gentest/fixtures/CSSLayoutAlignContentTest.html create mode 100644 gentest/fixtures/CSSLayoutAlignItemsTest.html create mode 100644 gentest/fixtures/CSSLayoutAlignSelfTest.html create mode 100644 gentest/fixtures/CSSLayoutBorderTest.html create mode 100644 gentest/fixtures/CSSLayoutFlexDirectionTest.html create mode 100644 gentest/fixtures/CSSLayoutFlexTest.html create mode 100644 gentest/fixtures/CSSLayoutFlexWrapTest.html create mode 100644 gentest/fixtures/CSSLayoutJustifyContentTest.html create mode 100644 gentest/fixtures/CSSLayoutMarginTest.html create mode 100644 gentest/fixtures/CSSLayoutMinMaxDimensionTest.html create mode 100644 gentest/fixtures/CSSLayoutPaddingTest.html create mode 100644 gentest/gentest-cpp.js create mode 100644 gentest/gentest-cs.js create mode 100644 gentest/gentest-java.js create mode 100644 gentest/gentest.rb delete mode 100755 gentest/gentest.sh 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 + + +