/*
* Copyright (C) 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed 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.jboss.errai.ui.test.basic.client;
import static org.jboss.errai.ui.shared.TemplateUtil.asElement;
import org.jboss.errai.enterprise.client.cdi.AbstractErraiCDITest;
import org.jboss.errai.ioc.client.IOCUtil;
import org.jboss.errai.ioc.client.container.IOC;
import org.jboss.errai.ui.shared.TemplateUtil;
import org.jboss.errai.ui.shared.TemplateWidget;
import org.jboss.errai.ui.shared.TemplateWidgetMapper;
import org.jboss.errai.ui.test.basic.client.res.BasicComponent;
import org.jboss.errai.ui.test.basic.client.res.BasicComponentUsingDataFields;
import org.jboss.errai.ui.test.basic.client.res.LessStyledComponent;
import org.jboss.errai.ui.test.basic.client.res.LessStyledComponentAbsolute;
import org.jboss.errai.ui.test.basic.client.res.LessStyledComponentRelative;
import org.jboss.errai.ui.test.basic.client.res.LessStyledComponentWithImport;
import org.jboss.errai.ui.test.basic.client.res.NonCompositeComponent;
import org.jboss.errai.ui.test.basic.client.res.StyledComponent;
import org.jboss.errai.ui.test.basic.client.res.StyledComponentWithAbsoluteSheetPath;
import org.jboss.errai.ui.test.basic.client.res.StyledComponentWithRelativeSheetPath;
import org.jboss.errai.ui.test.basic.client.res.StyledTemplatedBean;
import org.junit.Test;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.StyleInjector;
import com.google.gwt.regexp.shared.RegExp;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.RootPanel;
public class BasicTemplateTest extends AbstractErraiCDITest {
@Override
public String getModuleName() {
return getClass().getName().replaceAll("client.*$", "Test");
}
@Override
protected void gwtTearDown() throws Exception {
super.gwtTearDown();
/*
* This acts as a reset for the LESS stylesheet tests. Without this, the tests are not independent.
*/
StyleInjector.inject(".styled {\n color: black;\n background-color: black;\n}");
}
@Test
public void testInsertAndReplace() {
BasicTemplateTestApp app = IOC.getBeanManager().lookupBean(BasicTemplateTestAppUsingDataFields.class).getInstance();
testInsertAndReplace(app);
app = IOC.getBeanManager().lookupBean(BasicTemplateTestAppUsingIds.class).getInstance();
testInsertAndReplace(app);
app = IOC.getBeanManager().lookupBean(BasicTemplateTestAppUsingStyleClasses.class).getInstance();
testInsertAndReplace(app);
}
private void testInsertAndReplace(final BasicTemplateTestApp app) {
assertNotNull(app.getComponent());
final String innerHtml = app.getComponent().getElement().getInnerHTML();
assertTrue(RegExp.compile("<h1(.)*>This will be rendered</h1>").test(innerHtml));
assertTrue(RegExp.compile("<div(.)*>This will be rendered</div>").test(innerHtml));
final RegExp buttonInnerHtmlRegExp = RegExp.compile("This will be rendered inside button", "g");
assertTrue("Did find single instance of button text.", buttonInnerHtmlRegExp.test(innerHtml));
assertTrue("Did find second instance of button text.", buttonInnerHtmlRegExp.test(innerHtml));
final Element c1 = Document.get().getElementById("c1");
assertNotNull(c1);
assertEquals("Added by component", c1.getInnerText());
assertNotNull(Document.get().getElementById("c2"));
assertNotNull(Document.get().getElementById("c3"));
assertNull(Document.get().getElementById("content"));
final Element nc1 = Document.get().getElementById("nc1");
assertNotNull(nc1);
assertEquals("Added by component", nc1.getInnerText());
assertNotNull(Document.get().getElementById("nc2"));
assertNotNull(Document.get().getElementById("nc3"));
assertNull(Document.get().getElementById("nativeContent"));
}
@Test
public void testAttributesFromTemplateOverrideComponentElement() {
BasicTemplateTestApp app = IOC.getBeanManager().lookupBean(BasicTemplateTestAppUsingDataFields.class).getInstance();
testAttributesFromTemplateOverrideComponentElement(app);
app = IOC.getBeanManager().lookupBean(BasicTemplateTestAppUsingIds.class).getInstance();
testAttributesFromTemplateOverrideComponentElement(app);
app = IOC.getBeanManager().lookupBean(BasicTemplateTestAppUsingStyleClasses.class).getInstance();
testAttributesFromTemplateOverrideComponentElement(app);
}
private void testAttributesFromTemplateOverrideComponentElement(final BasicTemplateTestApp app) {
final Element c1 = app.getComponent().getLabel().getElement();
assertTrue("Element did not contain the class name [c1]. Observed class value: " + c1.getAttribute("class"), c1.hasClassName("c1"));
assertEquals("left", c1.getAttribute("align"));
final Element c3 = app.getComponent().getTextBox().getElement();
assertEquals("address", c3.getAttribute("name"));
final Element nc1 = asElement(app.getComponent().getNativeLabel());
assertEquals("nc1", nc1.getAttribute("class"));
assertEquals("left", nc1.getAttribute("align"));
final Element nc3 = TemplateUtil.asElement(app.getComponent().getNativeTextBox());
assertEquals("address", nc3.getAttribute("name"));
}
@Test
public void testHasHTMLPreservesInnerHTML() throws Exception {
BasicTemplateTestApp app = IOC.getBeanManager().lookupBean(BasicTemplateTestAppUsingDataFields.class).getInstance();
testHasHTMLPreservesInnerHTML(app);
app = IOC.getBeanManager().lookupBean(BasicTemplateTestAppUsingIds.class).getInstance();
testHasHTMLPreservesInnerHTML(app);
app = IOC.getBeanManager().lookupBean(BasicTemplateTestAppUsingStyleClasses.class).getInstance();
testHasHTMLPreservesInnerHTML(app);
}
private void testHasHTMLPreservesInnerHTML(final BasicTemplateTestApp app) throws Exception {
final Anchor c4comp = app.getComponent().getC4();
final String c4compHtml = c4comp.getHTML();
assertTrue("Inner HTML should be preserved when component implements ",
RegExp.compile("<span(.)*>LinkHTML</span>").test(c4compHtml));
final Element c4 = c4comp.getElement();
assertEquals("blah", c4.getAttribute("href"));
assertEquals("SPAN", c4.getFirstChildElement().getTagName());
assertEquals("LinkHTML", c4.getFirstChildElement().getInnerHTML());
final Element nc4 = TemplateUtil.asElement(app.getComponent().getNc4());
final String nc4Html = nc4.getInnerHTML();
assertTrue("Inner HTML should be preserved when component implements ",
RegExp.compile("<span(.)*>LinkHTML</span>").test(nc4Html));
assertEquals("blah", nc4.getAttribute("href"));
assertEquals("SPAN", nc4.getFirstChildElement().getTagName());
assertEquals("LinkHTML", nc4.getFirstChildElement().getInnerHTML());
}
@Test
public void testHasHTMLReparentsChildElements() throws Exception {
BasicTemplateTestApp app = IOC.getBeanManager().lookupBean(BasicTemplateTestAppUsingDataFields.class).getInstance();
testHasHTMLReparentsChildElements(app);
app = IOC.getBeanManager().lookupBean(BasicTemplateTestAppUsingIds.class).getInstance();
testHasHTMLReparentsChildElements(app);
app = IOC.getBeanManager().lookupBean(BasicTemplateTestAppUsingStyleClasses.class).getInstance();
testHasHTMLReparentsChildElements(app);
}
private void testHasHTMLReparentsChildElements(final BasicTemplateTestApp app) throws Exception {
final Anchor c5 = app.getComponent().getC5();
final Image c6 = app.getComponent().getC6();
System.out.println("DUMPING: " + Document.get().getElementById("root").getInnerHTML());
assertEquals(c6.getElement(), c5.getElement().getFirstChildElement());
final org.jboss.errai.ui.test.common.client.dom.Element nc5 = app.getComponent().getNc5();
final org.jboss.errai.ui.test.common.client.dom.Element nc6 = app.getComponent().getNc6();
System.out.println("DUMPING: " + Document.get().getElementById("root").getInnerHTML());
assertEquals(TemplateUtil.asElement(nc6), TemplateUtil.asElement(nc5).getFirstChildElement());
}
@Test
public void testPrecedenceRules() throws Exception {
final PrecedenceTemplateTestApp app = IOC.getBeanManager().lookupBean(PrecedenceTemplateTestApp.class).getInstance();
assertEquals(app.getComponent().getA().getText(), "This is a");
assertEquals(app.getComponent().getB().getText(), "This is b");
assertEquals(app.getComponent().getC().getText(), "This is c");
assertEquals(app.getComponent().getE().getText(), "This is d, e, and f");
}
@Test
public void testLoadingNonCompositeTemplatedBean() throws Exception {
final NonCompositeComponent instance = IOC.getBeanManager().lookupBean(NonCompositeComponent.class).getInstance();
final TemplateWidget rootWidget = TemplateWidgetMapper.get(instance);
assertEquals("The root @DataField was not used.", rootWidget.getElement(), instance.getRoot());
assertTrue("The text @DataField was not used.", instance.getTextBox().getElement().hasParentElement());
assertTrue("The button @DataField was not used.", instance.getButton().getElement().hasParentElement());
assertTrue("The text @DataField is not a child of the root element.",
instance.getTextBox().getElement().getParentElement().equals(rootWidget.getElement()));
assertTrue("The button @DataField is not a child of the root element.",
instance.getButton().getElement().getParentElement().equals(rootWidget.getElement()));
}
@Test
public void testNonCompositeTemplateCleanup() throws Exception {
final NonCompositeComponent instance = IOC.getBeanManager().lookupBean(NonCompositeComponent.class).getInstance();
assertTrue("Non-composite templated bean should have a TemplateWidget mapping after initialization.", TemplateWidgetMapper.containsKey(instance));
final TemplateWidget templateWidget = TemplateWidgetMapper.get(instance);
assertTrue("TemplateWidget should be attached after initialization.", templateWidget.isAttached());
assertTrue("TemplateWidget should be in detach list after initialization.", RootPanel.isInDetachList(templateWidget));
IOC.getBeanManager().destroyBean(instance);
assertFalse("Non-composite templated bean should not have a TemplateWidget mapping after destruction.", TemplateWidgetMapper.containsKey(instance));
assertFalse("TemplateWidget should not be attached after destruction.", templateWidget.isAttached());
assertFalse("TemplateWidget should not be in detach list after destruction.", RootPanel.isInDetachList(templateWidget));
}
@Test
public void testCompositeTemplateCleanup() throws Exception {
final BasicComponent instance = IOC.getBeanManager().lookupBean(BasicComponentUsingDataFields.class).getInstance();
assertFalse("Composite templated beans should not have TemplateWidget mappings after initialization.", TemplateWidgetMapper.containsKey(instance));
assertTrue("Composite templated bean should be attached after initialization.", instance.isAttached());
assertTrue("Composite templated bean should be in the detach list after initialization.", RootPanel.isInDetachList(instance));
IOC.getBeanManager().destroyBean(instance);
assertFalse("Composite templated beans should not have TemplateWidget mappings after destructions.", TemplateWidgetMapper.containsKey(instance));
assertFalse("Composite templated bean should not be attached after destruction.", instance.isAttached());
assertFalse("Composite templated bean should not be in the detach list after destruction.", RootPanel.isInDetachList(instance));
}
@Test
public void testStyleSheetWithDefaultPath() throws Exception {
final StyledTemplatedBean bean = IOC.getBeanManager().lookupBean(StyledComponent.class).getInstance();
styledBeanAssertions(bean, "font-size", "100px");
}
@Test
public void testStyleSheetWithRelativePath() throws Exception {
final StyledTemplatedBean bean = IOC.getBeanManager().lookupBean(StyledComponentWithRelativeSheetPath.class).getInstance();
styledBeanAssertions(bean, "font-color", "red");
}
@Test
public void testStyleSheetWithAbsolutePath() throws Exception {
final StyledTemplatedBean bean = IOC.getBeanManager().lookupBean(StyledComponentWithAbsoluteSheetPath.class).getInstance();
styledBeanAssertions(bean, "margin", "10px");
}
@Test
public void testLessStyleSheetWithDefaultPath() throws Exception {
try {
final LessStyledComponent bean = IOCUtil.getInstance(LessStyledComponent.class);
StyleInjector.flush();
assertTrue("Element does not have correct CSS class.", bean.styled.getClassList().contains("styled"));
assertEquals("rgb(255,0,0)", getPropertyValue(bean.styled, "color").replaceAll("\\s+", ""));
} catch (final AssertionError ae) {
throw ae;
} catch (final Throwable t) {
throw new AssertionError(t);
}
}
@Test
public void testLessStyleSheetWithRelativePath() throws Exception {
try {
final LessStyledComponentRelative bean = IOCUtil.getInstance(LessStyledComponentRelative.class);
StyleInjector.flush();
assertTrue("Element does not have correct CSS class.", bean.styled.getClassList().contains("styled"));
assertEquals("rgb(255,0,0)", getPropertyValue(bean.styled, "color").replaceAll("\\s+", ""));
} catch (final AssertionError ae) {
throw ae;
} catch (final Throwable t) {
throw new AssertionError(t);
}
}
@Test
public void testLessStyleSheetWithAbsolutePath() throws Exception {
try {
final LessStyledComponentAbsolute bean = IOCUtil.getInstance(LessStyledComponentAbsolute.class);
StyleInjector.flush();
assertTrue("Element does not have correct CSS class.", bean.styled.getClassList().contains("styled"));
assertEquals("rgb(255,0,0)", getPropertyValue(bean.styled, "color").replaceAll("\\s+", ""));
} catch (final AssertionError ae) {
throw ae;
} catch (final Throwable t) {
throw new AssertionError(t);
}
}
@Test
public void testLessStyleSheetWithImportedSheet() throws Exception {
try {
final LessStyledComponentWithImport bean = IOCUtil.getInstance(LessStyledComponentWithImport.class);
StyleInjector.flush();
assertTrue("Element does not have correct CSS class.", bean.styled.getClassList().contains("styled"));
assertEquals("rgb(255,0,0)", getPropertyValue(bean.styled, "color").replaceAll("\\s+", ""));
assertEquals("rgb(0,0,255)", getPropertyValue(bean.styled, "background-color").replaceAll("\\s+", ""));
} catch (final AssertionError ae) {
throw ae;
} catch (final Throwable t) {
throw new AssertionError(t);
}
}
private void styledBeanAssertions(final StyledTemplatedBean bean, final String propertyName, final String propertyValue) {
// Need to flush so that styles are computed immediately.
StyleInjector.flush();
assertTrue("The span element did not receive the class attribute from the template.", bean.getStyled().hasClassName("styled"));
assertEquals("Style from StyledComponent.css was not applied.", propertyValue, getPropertyValue(bean.getStyled(), propertyName));
}
private static native String getPropertyValue(Object elem, String prop) /*-{
return $wnd.getComputedStyle(elem,null).getPropertyValue(prop);
}-*/;
}