package nebula.lang; import static nebula.lang.Reference.ByVal; import static nebula.lang.Reference.Inline; import java.math.BigDecimal; import java.util.List; import junit.framework.TestCase; import nebula.data.Entity; import nebula.data.impl.EditableEntity; import org.antlr.runtime.ANTLRStringStream; import org.antlr.runtime.CommonTokenStream; import org.antlr.runtime.RecognitionException; import util.InheritHashMap; public class NebulaParser_BasicTest extends TestCase { TypeLoaderForTest compiler; @Override protected void setUp() throws Exception { compiler = new TypeLoaderForTest(new SystemTypeLoader()); } private TypeImp parseType(String text) { try { NebulaLexer lexer = new NebulaLexer(new ANTLRStringStream(text)); CommonTokenStream tokens = new CommonTokenStream(lexer); NebulaParser parser = new NebulaParser(tokens, compiler); TypeImp type = parser.typeDefinition(); assertEquals(0, parser.getNumberOfSyntaxErrors()); return type; } catch (RecognitionException e) { fail(e.toString()); return null; } } public void testTypeDefinition() { //@formatter:off String text = "" + "type Person { " + " 姓名 Name;" + " 姓名2 Name\n" + "};"; //@formatter:on TypeImp type = parseType(text); assertEquals("Person", type.getName()); assertEquals(2, type.getFields().size()); Field f = type.getFields().get(0); assertEquals("姓名", f.name); assertEquals(ByVal, f.refer); assertFalse(f.isNullable()); } public void testTypeKeyUnique() { //@formatter:off String text = "" + "type Person { " + " 姓名 Name;" + " 姓名2 Name\n" + "};"; //@formatter:on TypeImp type = parseType(text); assertEquals(false, type.getFields().get(0).isKey()); assertEquals(false, type.getFields().get(0).isUnique()); assertEquals(false, type.getFields().get(1).isKey()); assertEquals(false, type.getFields().get(1).isUnique()); //@formatter:off text = "" + "type Person { " + " !姓名 Name;" + " 姓名2 Name\n" + "};"; //@formatter:on type = parseType(text); assertEquals(true, type.getFields().get(0).isKey()); assertEquals(true, type.getFields().get(0).isUnique()); assertEquals(false, type.getFields().get(1).isKey()); assertEquals(false, type.getFields().get(1).isUnique()); //@formatter:off text = "" + "type Person { " + " !!姓名 Name;" + " 姓名2 Name\n" + "};"; //@formatter:on type = parseType(text); assertEquals(true, type.getFields().get(0).isKey()); assertEquals(true, type.getFields().get(0).isUnique()); assertEquals(false, type.getFields().get(1).isKey()); assertEquals(false, type.getFields().get(1).isUnique()); //@formatter:off text = "" + "type Person { " + " !!姓名 Name;" + " !姓名2 Name\n" + "};"; //@formatter:on type = parseType(text); assertEquals(true, type.getFields().get(0).isKey()); assertEquals(true, type.getFields().get(0).isUnique()); assertEquals(false, type.getFields().get(1).isKey()); assertEquals(true, type.getFields().get(1).isUnique()); //@formatter:off text = "" + "type Person { " + " !姓名 Name;" + " !姓名2 Name\n" + "};"; //@formatter:on type = parseType(text); assertEquals(true, type.getFields().get(0).isKey()); assertEquals(true, type.getFields().get(0).isUnique()); assertEquals(false, type.getFields().get(1).isKey()); assertEquals(true, type.getFields().get(1).isUnique()); } private Field parseField(String text) { try { NebulaLexer lexer = new NebulaLexer(new ANTLRStringStream(text)); CommonTokenStream tokens = new CommonTokenStream(lexer); NebulaParser parser = new NebulaParser(tokens, compiler); TypeImp type = new TypeImp(compiler, "Test"); Field field; field = new Field(type, "Name"); field.type = parser.resolveType("Name"); type.fields.add(field); field = new Field(type, "Age"); field.type = parser.resolveType("Age"); type.fields.add(field); parser.currentType = type; field = parser.fieldDefinition(type); parser.exitTopType(); return field; } catch (RecognitionException e) { fail(e.toString()); return null; } } public void testFieldDefinition() { String text = "!Name;"; Field v = parseField(text); assertEquals("Name", v.name); assertEquals(true, v.isUnique()); } public void testFieldDefinition_subType() { String text = "!Detail{Name;Age Height;};"; Field f = parseField(text); assertEquals("Detail", f.name); assertEquals("Test$Detail", f.type.getName()); assertEquals(Inline, f.refer); assertEquals("Name", f.type.getFields().get(0).name); assertEquals("Name", f.type.getFields().get(0).type.getName()); assertEquals("Age", f.type.getFields().get(1).name); assertEquals("Height", f.type.getFields().get(1).type.getName()); } public void testFieldDefinition_default() { assertEquals(1014L * 1024L, parseField("!MyAge Age := 1014 * 1024;").exprAsm.eval(null, null, null)); assertEquals("test", parseField("!MyAge Age := \"test\";").exprAsm.eval(null, null, null)); assertEquals("test", parseField("!Name := ```test``` ;").exprAsm.eval(null, null, null)); assertEquals("# Title\n## firstline\ntest content", parseField("!Name := ```\n# Title\n## firstline\ntest content``` ;").exprAsm.eval(null, null, null)); assertEquals(new BigDecimal("1.3"), parseField("!MyAge Age := 1.3;").exprAsm.eval(null, null, null)); assertEquals(4 > 5, parseField("!MyAge Age := 4 > 5;").exprAsm.eval(null, null, null)); } public void testFieldDefinition_derived() { Entity e = new EditableEntity(); long Age = 15; String name = "wangshilian"; e.put("Name", name); e.put("Age", Age); assertEquals(Age, parseField("!MyAge Age = this.Age;").exprAsm.eval(null, null, e)); assertEquals(Age + 10 * 1000, parseField("!MyAge Age = this.Age + 10 * 1000;").exprAsm.eval(null, null, e)); assertEquals(name, parseField("!MyAge Name = this.Name;").exprAsm.eval(null, null, e)); } public void testFieldDefinition_quicktype() { Field f = parseField(" Max-Age;"); assertEquals("MaxAge", f.name); } public void testFieldImportance_Importance() { assertEquals(true, parseField("!!Name;").isKey()); assertEquals(true, parseField("!!Name;").isUnique()); assertEquals(true, parseField("!Name;").isUnique()); assertEquals(true, parseField("*Name;").isCore()); assertEquals(true, parseField("#Name;").isRequired()); assertEquals(true, parseField("?Name;").isNullable()); assertEquals(true, parseField("!Name;").isUnique()); } private NebulaParser.arrayDefinition_return parseArray(String text) { try { NebulaLexer lexer = new NebulaLexer(new ANTLRStringStream(text)); CommonTokenStream tokens = new CommonTokenStream(lexer); NebulaParser parser = new NebulaParser(tokens, compiler); NebulaParser.arrayDefinition_return v = parser.arrayDefinition(); assertEquals(0, parser.getNumberOfSyntaxErrors()); return v; } catch (RecognitionException e) { fail(e.toString()); return null; } } public void testArrayDefinition() { NebulaParser.arrayDefinition_return v = parseArray("[]"); assertEquals(null, v.from); assertEquals(null, v.to); v = parseArray("[1]"); assertEquals("1", v.from); assertEquals(null, v.to); v = parseArray("[1..]"); assertEquals("1", v.from); assertEquals(null, v.to); v = parseArray("[1..10]"); assertEquals("1", v.from); assertEquals("10", v.to); v = parseArray("[..10]"); assertEquals(null, v.from); assertEquals("10", v.to); } private InheritHashMap parseAnnotation(String text) { try { InheritHashMap attrs = new InheritHashMap(); NebulaLexer lexer = new NebulaLexer(new ANTLRStringStream(text)); CommonTokenStream tokens = new CommonTokenStream(lexer); NebulaParser parser = new NebulaParser(tokens, compiler); parser.annotationItemDefinition(attrs); assertEquals(0, parser.getNumberOfSyntaxErrors()); return attrs; } catch (RecognitionException e) { fail(e.toString()); return null; } } public void testAnnotation() { assertEquals("MaxLength", parseAnnotation("MaxLength").get("MaxLength")); assertEquals("X", parseAnnotation("MaxLength(\"X\")").get("MaxLength")); assertEquals(new BigDecimal("1.1"), parseAnnotation("MaxLength(1.1) ").get("MaxLength")); } public void testTypeAliases() { assertEquals("Person", parseType("type Person {Name;};").getDisplayName()); assertEquals("员工", parseType("type Person|员工 {Name;};").getDisplayName()); assertEquals("Person", parseType("type Person|zh:员工 {Name;};").getDisplayName()); assertEquals("员工", parseType("type Person|zh:员工 {Name;};").nameAlias.get("zh")); } public void testFieldAliases() { assertEquals("年龄", parseField("Age;").getDisplayName()); assertEquals("Age", parseField("Age Age;").getDisplayName()); assertEquals("年龄Local", parseField("Age|年龄Local Age;").getDisplayName()); assertEquals("临时 Age", parseField("临时-Age;").getDisplayName()); assertEquals("临时 Age", parseField("临时-Age Age;").getDisplayName()); assertEquals("永久年龄", parseField("临时-Age|永久年龄 Age;").getDisplayName()); assertEquals("Name", parseField("Name|zh:姓名|\"zh-tw\":台湾姓名;").getDisplayName()); assertEquals("姓名", parseField("Name|zh:姓名|\"zh-tw\":台湾姓名;").nameAlias.get("zh-cn")); assertEquals("台湾姓名", parseField("Name|zh:姓名|\"zh-tw\":台湾姓名;").nameAlias.get("zh-tw")); assertEquals("姓名", parseField("Name|zh:姓名|\"zh-tw\":台湾姓名;").nameAlias.get("zh")); } private Expr<?> parseCst(String text) { try { NebulaLexer lexer = new NebulaLexer(new ANTLRStringStream(text)); CommonTokenStream tokens = new CommonTokenStream(lexer); NebulaParser parser = new NebulaParser(tokens, compiler); Expr<?> expr = parser.constExpr(); assertEquals(0, parser.getNumberOfSyntaxErrors()); return expr; } catch (RecognitionException e) { fail(e.toString()); return null; } } public void testConstExpr() { assertEquals(String.valueOf(1234L), parseCst("1234").toString()); assertEquals(String.valueOf(new BigDecimal("1.1")), parseCst("1.1").toString()); assertEquals(String.valueOf("1.1"), parseCst("\"1.1\"").toString()); assertEquals(String.valueOf("QWEQWEQWEWQE"), parseCst("\"QWEQWEQWEWQE\"").toString()); assertEquals(String.valueOf("QWEQWEQWEWQE"), parseCst("\'QWEQWEQWEWQE\'").toString()); assertEquals(String.valueOf(""), parseCst("``````").toString()); assertEquals(String.valueOf("1234567890"), parseCst("```1234567890```").toString()); assertEquals(String.valueOf("12345\n67890"), parseCst("```12345\n67890```").toString()); assertEquals(String.valueOf("12345\n67890"), parseCst("```\n12345\n67890```").toString()); assertEquals(String.valueOf("12345\n67890"), parseCst("```\r\n12345\n67890```").toString()); assertEquals("12:23:00", parseCst("12:23:00").toString()); assertEquals("2006-11-23 12:23:00.234", parseCst("2006-11-23 12:23:00.234").toString()); assertEquals("2006-11-23 12:23:00", parseCst("2006-11-23 12:23:00").toString()); assertEquals("2006-11-23", parseCst("2006-11-23").toString()); } public void testNestTypeAliasDefinition() { //@formatter:off String text = "" + "type Person|zh:员工 { " + " Name|zh:姓名;" + " Detail |zh:明细{" + " Name;" + " Age;" + " };" + " Detail2 {" + " Name;" + " Age;" + " };" + "};"; //@formatter:on TypeImp type = parseType(text); assertEquals("Person", type.getName()); assertEquals("员工", type.getNameAlias().get("zh")); assertEquals(3, type.getFields().size()); int i = 0; assertEquals("Name", type.getFields().get(i).name); assertEquals(true, type.getFields().get(i).isRequired()); assertEquals("姓名", type.getFields().get(i).nameAlias.get("zh")); i++; assertEquals("Detail", type.getFields().get(i).name); assertEquals(Inline, type.getFields().get(i).refer); assertEquals("明细", type.getFields().get(i).nameAlias.get("zh")); assertEquals("明细", type.getFields().get(i).type.getNameAlias().get("zh")); i++; assertEquals("Detail2", type.getFields().get(i).name); assertEquals(Inline, type.getFields().get(i).refer); assertEquals("Detail2", type.getFields().get(i).nameAlias.getDefault()); } public void testProgramDefinition() { try { //@formatter:off String text = "" + "type Person|zh:员工 { " + " Name|zh:姓名;" + " Detail |zh:明细{" + " Name;" + " Age;" + " };" + "};"; //@formatter:on NebulaLexer lexer = new NebulaLexer(new ANTLRStringStream(text)); CommonTokenStream tokens = new CommonTokenStream(lexer); NebulaParser parser = new NebulaParser(tokens, compiler); List<TypeImp> types = parser.programDefinition(); Type type = types.get(0); assertEquals("Person", type.getName()); assertEquals("员工", type.getNameAlias().get("zh")); assertEquals(2, type.getFields().size()); int i = 0; assertEquals("Name", type.getFields().get(i).name); assertEquals(true, type.getFields().get(i).isRequired()); assertEquals("姓名", type.getFields().get(i).nameAlias.get("zh")); i++; assertEquals("Detail", type.getFields().get(i).getName()); assertEquals("明细", type.getFields().get(i).nameAlias.get("zh")); assertEquals("明细", type.getFields().get(i).type.getNameAlias().get("zh")); type = types.get(1); assertEquals("Person$Detail", type.getName()); assertEquals("明细", type.getNameAlias().get("zh")); } catch (RecognitionException e) { fail(e.toString()); } } }