/*******************************************************************************
* Copyright (c) 2017 itemis AG and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Matthias Wienand (itemis AG) - initial API and implementation
* Tamas Miklossy (itemis AG) - initial API and implementation
*
*******************************************************************************/
package org.eclipse.gef.dot.tests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import org.eclipse.emf.common.util.EList;
import org.eclipse.gef.dot.internal.language.DotHtmlLabelInjectorProvider;
import org.eclipse.gef.dot.internal.language.htmllabel.HtmlContent;
import org.eclipse.gef.dot.internal.language.htmllabel.HtmlLabel;
import org.eclipse.gef.dot.internal.language.htmllabel.HtmlTag;
import org.eclipse.gef.dot.internal.language.htmllabel.HtmllabelPackage;
import org.eclipse.xtext.junit4.InjectWith;
import org.eclipse.xtext.junit4.XtextRunner;
import org.eclipse.xtext.junit4.util.ParseHelper;
import org.eclipse.xtext.junit4.validation.ValidationTestHelper;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.google.inject.Inject;
@RunWith(XtextRunner.class)
@InjectWith(DotHtmlLabelInjectorProvider.class)
public class DotHtmlLabelTests {
@Inject
private ParseHelper<HtmlLabel> parseHelper;
@Inject
private ValidationTestHelper validationTestHelper;
/*
************************************************************************************************************
* Test cases for valid DOT Html like labels
************************************************************************************************************
*/
@Test
public void test_tag_case_insensitivity() throws Throwable {
parse(DotTestHtmlLabels.MIXED_LOWER_CASE_AND_UPPER_CASE);
}
@Test
public void test_comment() throws Throwable {
parse(DotTestHtmlLabels.COMMENT);
}
@Test
public void test_comment_with_hyphen() throws Throwable {
parse(DotTestHtmlLabels.COMMENT_WITH_HYPHEN);
}
@Test
public void test_comment_with_nested_tags() throws Throwable {
parse(DotTestHtmlLabels.COMMENT_WITH_NESTED_TAG);
}
@Test
public void test_comment_with_open_tag() throws Throwable {
parse(DotTestHtmlLabels.COMMENT_WITH_OPEN_TAG);
}
@Test
public void test_comment_with_close_tag() throws Throwable {
parse(DotTestHtmlLabels.COMMENT_WITH_CLOSE_TAG);
}
@Test(timeout = 2000)
public void test_tag_with_attribute() {
parse(DotTestHtmlLabels.TAG_WITH_ATTRIBUTE);
}
@Test
public void test_font_tag_with_point_size_attribute() {
parse(DotTestHtmlLabels.FONT_TAG_WITH_POINT_SIZE_ATTRIBUTE);
}
@Test
public void test_font_tag_contains_table_tag() {
parse(DotTestHtmlLabels.FONT_TAG_CONTAINS_TABLE_TAG);
}
@Test
public void test_nesting() throws Throwable {
HtmlLabel htmlLabel = parse(DotTestHtmlLabels.NESTED_TAGS);
EList<HtmlContent> parts = htmlLabel.getParts();
assertEquals(1, parts.size());
// check base table
HtmlTag baseTable = parts.get(0).getTag();
assertNotNull(baseTable);
EList<HtmlContent> baseTableChildren = baseTable.getChildren();
assertEquals(5, baseTableChildren.size());
HtmlTag baseTr1 = baseTableChildren.get(1).getTag();
assertNotNull(baseTr1);
assertEquals("tr", baseTr1.getName());
assertEquals(baseTable, baseTr1.eContainer().eContainer());
assertEquals("first", baseTr1.getChildren().get(0).getTag()
.getChildren().get(0).getText());
HtmlTag baseTr2 = baseTableChildren.get(3).getTag();
assertNotNull(baseTr2);
assertEquals("tr", baseTr2.getName());
assertEquals(baseTable, baseTr2.eContainer().eContainer());
// check nested table
HtmlTag nestedTable = baseTr2.getChildren().get(0).getTag()
.getChildren().get(0).getTag();
assertEquals("table", nestedTable.getName());
assertEquals("second",
nestedTable.getChildren().get(0).getTag().getChildren().get(0)
.getTag().getChildren().get(0).getTag().getChildren()
.get(0).getText());
}
@Test
public void test_nesting2() {
parse(DotTestHtmlLabels.NESTED_TAGS2);
}
@Test
public void test_self_closing_tags() {
parse(DotTestHtmlLabels.SELF_CLOSING_TAGS);
}
/*
************************************************************************************************************
* Test cases for invalid DOT Html like labels
************************************************************************************************************
*/
@Test
public void test_tag_wrongly_closed() throws Exception {
String text = "<test>string</B>";
HtmlLabel htmlLabel = parseHelper.parse(text);
validationTestHelper.assertError(htmlLabel,
HtmllabelPackage.eINSTANCE.getHtmlTag(), null,
"Tag '<test>' is not closed (expected '</test>' but got '</B>').");
validationTestHelper.assertError(htmlLabel,
HtmllabelPackage.eINSTANCE.getHtmlTag(), null,
"Tag '<test>' is not supported.");
// verify that these are the only reported issues
Assert.assertEquals(2, validationTestHelper.validate(htmlLabel).size());
}
@Test
public void test_unknown_parent() throws Exception {
String text = "<foo><tr></tr></foo>";
HtmlLabel htmlLabel = parseHelper.parse(text);
validationTestHelper.assertError(htmlLabel,
HtmllabelPackage.eINSTANCE.getHtmlTag(), null,
"Tag '<foo>' is not supported.");
validationTestHelper.assertError(htmlLabel,
HtmllabelPackage.eINSTANCE.getHtmlTag(), null,
"Tag '<tr>' is not allowed inside '<foo>', but only inside '<TABLE>'.");
// verify that these are the only reported issues
Assert.assertEquals(2, validationTestHelper.validate(htmlLabel).size());
}
@Test
public void test_invalid_parent1() throws Exception {
String text = "<tr></tr>";
HtmlLabel htmlLabel = parseHelper.parse(text);
validationTestHelper.assertError(htmlLabel,
HtmllabelPackage.eINSTANCE.getHtmlTag(), null,
"Tag '<tr>' is not allowed inside '<ROOT>', but only inside '<TABLE>'.");
// verify that this is the only reported issue
Assert.assertEquals(1, validationTestHelper.validate(htmlLabel).size());
}
@Test
public void test_invalid_parent2() throws Exception {
String text = "<table><U></U></table>";
HtmlLabel htmlLabel = parseHelper.parse(text);
validationTestHelper.assertError(htmlLabel,
HtmllabelPackage.eINSTANCE.getHtmlTag(), null,
"Tag '<U>' is not allowed inside '<table>', but only inside '<TD>', '<SUB>', '<B>', '<S>', '<ROOT>', '<U>', '<I>', '<FONT>', '<O>', '<SUP>'.");
// verify that this is the only reported issue
Assert.assertEquals(1, validationTestHelper.validate(htmlLabel).size());
}
@Test
public void test_invalid_attribute_in_valid_tag() throws Exception {
String text = "<table foo=\"bar\"></table>";
HtmlLabel htmlLabel = parseHelper.parse(text);
validationTestHelper.assertError(htmlLabel,
HtmllabelPackage.eINSTANCE.getHtmlAttr(), null,
"Attribute 'foo' is not allowed inside '<table>'.");
// verify that this is the only reported issue
Assert.assertEquals(1, validationTestHelper.validate(htmlLabel).size());
}
@Test
public void test_invalid_attribute_in_invalid_tag() throws Exception {
String text = "<foo bar=\"baz\"></foo>";
HtmlLabel htmlLabel = parseHelper.parse(text);
validationTestHelper.assertError(htmlLabel,
HtmllabelPackage.eINSTANCE.getHtmlTag(), null,
"Tag '<foo>' is not supported.");
validationTestHelper.assertError(htmlLabel,
HtmllabelPackage.eINSTANCE.getHtmlAttr(), null,
"Attribute 'bar' is not allowed inside '<foo>'.");
// verify that these are the only reported issues
Assert.assertEquals(2, validationTestHelper.validate(htmlLabel).size());
}
@Test
public void test_string_literal_is_not_allowed() {
// <BR>string</BR> is not allowed
testStringLiteral("<BR>string</BR>", "BR");
// <TABLE>string</TABLE> is not allowed
testStringLiteral("<TABLE>string</TABLE>", "TABLE");
// <HR>string</HR> is not allowed
testStringLiteral("<TABLE><HR>string</HR></TABLE>", "HR");
// <TR>string</TR> is not allowed
testStringLiteral("<TABLE><TR>string</TR></TABLE>", "TR");
// <VR>string</VR> is not allowed
testStringLiteral("<TABLE><TR><VR>string</VR></TR></TABLE>", "VR");
// <IMG>string</IMG> is not allowed
testStringLiteral("<TABLE><TR><TD><IMG>string</IMG></TD></TR></TABLE>",
"IMG");
}
@Test
public void test_self_closing_is_not_allowed() {
testSelfClosingTag("<FONT/>"); // <FONT/> is not allowed
testSelfClosingTag("<I/>"); // <I/> is not allowed
testSelfClosingTag("<B/>"); // <B/> is not allowed
testSelfClosingTag("<U/>"); // <U/> is not allowed
testSelfClosingTag("<O/>"); // <O/> is not allowed
testSelfClosingTag("<SUB/>"); // <SUB/> is not allowed
testSelfClosingTag("<SUP/>"); // <SUP/> is not allowed
testSelfClosingTag("<S/>"); // <S/> is not allowed
testSelfClosingTag("<TABLE/>"); // <TABLE/> is not allowed
// <TR/> is not allowed
testSelfClosingTag("<TABLE><TR/></TABLE>", "<TR/>");
// <TD/> is not allowed
testSelfClosingTag("<TABLE><TR><TD/></TR></TABLE>", "<TD/>");
}
private void testStringLiteral(String... text) {
String tagName = text.length > 1 ? text[1] : text[0];
verify(text[0],
"Tag '<" + tagName + ">' cannot contain a string literal.");
}
private void testSelfClosingTag(String... text) {
String tagName = text.length > 1 ? text[1] : text[0];
verify(text[0], "Tag '" + tagName + "' cannot be self closing.");
}
/*
* Verify that parsing the given text raises a validation error with the
* given message.
*/
private void verify(String text, String message) {
HtmlLabel htmlLabel = null;
try {
htmlLabel = parseHelper.parse(text);
} catch (Exception e) {
e.printStackTrace();
fail();
}
validationTestHelper.assertError(htmlLabel,
HtmllabelPackage.eINSTANCE.getHtmlTag(), null, message);
// verify that this is the only reported issue
Assert.assertEquals(1, validationTestHelper.validate(htmlLabel).size());
}
private HtmlLabel parse(String text) {
try {
HtmlLabel ast = parseHelper.parse(text);
assertNotNull(ast);
validationTestHelper.assertNoErrors(ast);
return ast;
} catch (Exception e) {
e.printStackTrace();
fail();
}
return null;
}
}