blob: 8197c4ce813c0f4ef873db92132c0f77594e15af [file] [log] [blame]
/*
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.royale.compiler.internal.codegen.js.royale;
import org.apache.royale.compiler.driver.IBackend;
import org.apache.royale.compiler.internal.driver.js.goog.JSGoogConfiguration;
import org.apache.royale.compiler.internal.driver.js.royale.RoyaleBackend;
import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
import org.apache.royale.compiler.internal.test.ASTestBase;
import org.apache.royale.compiler.tree.as.IFunctionNode;
import org.junit.Test;
public class TestRoyaleJSX extends ASTestBase
{
@Override
public void setUp()
{
backend = createBackend();
project = new RoyaleJSProject(workspace, backend);
project.config = new JSGoogConfiguration();
super.setUp();
}
@Test
public void testJSXMetadataWithoutXMLLiterals()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n}");
}
@Test
public void testSimpleSelfClosingHTMLTag()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div/>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null);\n}");
}
@Test
public void testSimpleSelfClosingHTMLTagWithTrailingSpace()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div />}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null);\n}");
}
@Test
public void testSelfClosingHTMLTagWithAttribute()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div id=\"foo\"/>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', { 'id': 'foo' });\n}");
}
@Test
public void testSelfClosingHTMLTagWithAttributeAfterNewLine()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div\nid=\"foo\"/>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', { 'id': 'foo' });\n}");
}
@Test
public void testSelfClosingHTMLTagWithAttributeAfterCarriageReturnNewLine()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div\r\nid=\"foo\"/>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', { 'id': 'foo' });\n}");
}
@Test
public void testSelfClosingHTMLTagWithAttributeAfterTab()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div\tid=\"foo\"/>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', { 'id': 'foo' });\n}");
}
@Test
public void testSelfClosingHTMLTagWithMultipleAttributes()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div id=\"foo\" className=\"bar\"/>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', { 'id': 'foo', 'className': 'bar' });\n}");
}
@Test
public void testSelfClosingHTMLTagWithSingleQuoteAttribute()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div id=\'foo\'/>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', { 'id': 'foo' });\n}");
}
@Test
public void testSelfClosingHTMLTagWithSingleQuoteInAttribute()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div id=\"'\"/>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', { 'id': '\\\'' });\n}");
}
@Test
public void testSelfClosingHTMLTagWithDashInAttributeName()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div data-prop=\"foo\"/>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', { 'data-prop': 'foo' });\n}");
}
@Test
public void testSelfClosingHTMLTagWithSpaceInAttribute()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div className=\"foo bar\"/>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', { 'className': 'foo bar' });\n}");
}
@Test
public void testSelfClosingHTMLTagWithSpaceInSingleQuoteAttribute()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div className=\'foo bar\'/>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', { 'className': 'foo bar' });\n}");
}
@Test
public void testSelfClosingHTMLTagWithAttributeContainingLiteral()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div id={2}/>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', { 'id': 2 });\n}");
}
@Test
public void testSelfClosingHTMLTagWithAttributeContainingExpression()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div id={2 + 2}/>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', { 'id': 2 + 2 });\n}");
}
@Test
public void testSimpleOpenAndCloseHTMLTag()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div></div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null);\n}");
}
@Test
public void testOpenAndCloseHTMLTagWithChildText()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div>Foo</div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null, 'Foo');\n}");
}
@Test
public void testOpenAndCloseHTMLTagWithChildTextOnNewLine()
{
//in JSX, new lines are removed
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div>\nFoo\n</div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null, 'Foo');\n}");
}
@Test
public void testOpenAndCloseHTMLTagWithChildTextWithMultipleSpacesBetween()
{
//in JSX, spaces are only removed after a new line, so these are kept!
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div>Foo bar</div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null, 'Foo bar');\n}");
}
@Test
public void testOpenAndCloseHTMLTagWithChildTextWithMultipleSpacesBeforeAndAfter()
{
//in JSX, spaces are only removed after a new line, so these are kept!
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div> Foo </div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null, ' Foo ');\n}");
}
@Test
public void testOpenAndCloseHTMLTagWithChildTextOnNewLineCRLF()
{
//in JSX, new lines are removed
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div>\r\nFoo\r\n</div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null, 'Foo');\n}");
}
@Test
public void testOpenAndCloseHTMLTagWithChildTextOnNewLineWithTabIndent()
{
//in JSX, whitespace is removed after a new line, so the tab isn't kept
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div>\n\tFoo\n</div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null, 'Foo');\n}");
}
@Test
public void testOpenAndCloseHTMLTagWithChildTextOnNewLineWithSpaceIndent()
{
//in JSX, whitespace is removed after a new line, so the spaces aren't kept
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div>\n Foo\n</div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null, 'Foo');\n}");
}
@Test
public void testOpenAndCloseHTMLTagWithChildBracesContainingLiteral()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div>{2}</div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null, 2);\n}");
}
@Test
public void testOpenAndCloseHTMLTagWithChildBracesContainingExpression()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div>{2 + 2}</div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null, 2 + 2);\n}");
}
@Test
public void testOpenAndCloseHTMLTagWithChildTextAndBraces()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div>Foo {2}</div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null, 'Foo ', 2);\n}");
}
@Test
public void testOpenAndCloseHTMLTagWithChildBracesAndText()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div>{2} Foo</div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null, 2, ' Foo');\n}");
}
@Test
public void testOpenAndCloseHTMLTagWithAttribute()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div id=\"foo\"></div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', { 'id': 'foo' });\n}");
}
@Test
public void testOpenAndCloseHTMLTagWithMultipleAttributes()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div id=\"foo\" className=\"bar\"></div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', { 'id': 'foo', 'className': 'bar' });\n}");
}
@Test
public void testOpenAndCloseHTMLTagWithAttributeAndChildText()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div id=\"foo\">Foo</div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', { 'id': 'foo' }, 'Foo');\n}");
}
@Test
public void testNestedHTMLTags()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div><button/></div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null,\n React.createElement('button', null));\n}");
}
@Test
public void testNestedHTMLTagsWithWhitespace()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div> \t<button/> \t </div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null,\n React.createElement('button', null));\n}");
}
@Test
public void testNestedHTMLTagsWithWhitespaceAndText()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div>\t<button/> Hello</div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null,\n React.createElement('button', null), ' Hello');\n}");
}
@Test
public void testNestedHTMLTagsWithChildBracesWhitespaceAndText()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div>\t<button/> Hello {2}</div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null,\n React.createElement('button', null), ' Hello ', 2);\n}");
}
@Test
public void testNestedHTMLTagsWithChildBracesWhitespaceAndText2()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div>\t<button></button> Hello {2}</div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null,\n React.createElement('button', null), ' Hello ', 2);\n}");
}
@Test
public void testNestedHTMLTagsWithChildBracesAndWhitespace()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div>\t<button/> {2}</div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null,\n React.createElement('button', null), ' ', 2);\n}");
}
@Test
public void testNestedHTMLTagsOnDifferentLines()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div>\n<button/>\n</div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null,\n React.createElement('button', null));\n}");
}
@Test
public void testNestedHTMLTagsOnDifferentLinesWithCRLF()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div>\r\n\t<button/>\r\n</div>}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement('div', null,\n React.createElement('button', null));\n}");
}
@Test
public void testImportedClass()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {\n import custom.TestImplementation;\n return <TestImplementation/>;\n}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement(custom.TestImplementation, null);\n}");
}
@Test
public void tesClassWithAttribute()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {\n import custom.TestImplementation;\n return <TestImplementation id=\"hello\"/>;\n}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement(custom.TestImplementation, { id: 'hello' });\n}");
}
@Test
public void tesClassWithRef()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {\n import custom.TestImplementation;\n return <TestImplementation ref=\"hello\"/>;\n}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement(custom.TestImplementation, { 'ref': 'hello' });\n}");
}
@Test
public void tesClassWithKey()
{
IFunctionNode node = getMethod("[JSX]\nfunction foo() {\n import custom.TestImplementation;\n return <TestImplementation key=\"hello\"/>;\n}");
asBlockWalker.visitFunction(node);
assertOut("RoyaleTest_A.prototype.foo = function() {\n return React.createElement(custom.TestImplementation, { 'key': 'hello' });\n}");
}
@Override
protected IBackend createBackend()
{
return new RoyaleBackend();
}
}