/** * Copyright 2004-2016 Riccardo Solmi. All rights reserved. * This file is part of the Whole Platform. * * The Whole Platform is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The Whole Platform is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>. */ package org.whole.lang.grammars.util; import java.io.InputStream; import java.nio.charset.Charset; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; import org.whole.lang.codebase.StreamPersistenceProvider; import org.whole.lang.commons.factories.CommonsEntityAdapterFactory; import org.whole.lang.grammars.codebase.GrammarsRegistry; import org.whole.lang.grammars.codebase.XmlGrammar; import org.whole.lang.grammars.factories.GrammarsEntityFactory; import org.whole.lang.grammars.model.DataTerminal; import org.whole.lang.grammars.model.Format; import org.whole.lang.grammars.model.Grammar; import org.whole.lang.grammars.model.LiteralTerminal; import org.whole.lang.grammars.model.Name; import org.whole.lang.grammars.model.NonTerminal; import org.whole.lang.grammars.model.Pattern; import org.whole.lang.grammars.model.Production; import org.whole.lang.grammars.model.Productions; import org.whole.lang.grammars.model.Repeat; import org.whole.lang.grammars.model.Rule; import org.whole.lang.grammars.model.TargetLanguage; import org.whole.lang.grammars.reflect.GrammarsEntityDescriptorEnum; import org.whole.lang.grammars.reflect.GrammarsFeatureDescriptorEnum; import org.whole.lang.matchers.Matcher; import org.whole.lang.model.IEntity; import org.whole.lang.models.factories.ModelsEntityFactory; import org.whole.lang.models.model.ComponentModifierEnum; import org.whole.lang.models.model.EntityModifierEnum; import org.whole.lang.models.model.FeatureModifierEnum; import org.whole.lang.models.model.Model; import org.whole.lang.models.reflect.ModelsEntityDescriptorEnum; import org.whole.lang.operations.InterpreterOperation; import org.whole.lang.operations.NormalizerOperation; import org.whole.lang.reflect.ReflectionFactory; import org.whole.lang.util.DataTypeUtils; import org.whole.lang.util.StringUtils; import org.whole.lang.xml.codebase.XmlSourcePersistenceKit; import org.whole.lang.xml.factories.XmlEntityFactory; import org.whole.lang.xml.model.Element; import org.whole.test.KnownFailingTests; import org.whole.test.SlowTests; /** * @author Riccardo Solmi */ @Category(SlowTests.class) public class GrammarsUtilsTest { private String testGrammarURI; private String xmlGrammarURI; @BeforeClass public static void deployWholePlatform() { // ReflectionFactory.deployWholePlatform(); } @Before public void setUp() throws Exception { ReflectionFactory.deployWholePlatform(); //TODO fix and remove workaround Grammar testGrammar1 = new TestGrammar1().create(); testGrammarURI = testGrammar1.getUri().getValue(); if (!GrammarsRegistry.instance().containsGrammar(testGrammarURI)) //TODO fix and remove workaround InterpreterOperation.interpret(testGrammar1); Grammar xmlGrammar = new XmlGrammar().create(); xmlGrammarURI = xmlGrammar.getUri().getValue(); if (!GrammarsRegistry.instance().containsGrammar(xmlGrammarURI)) //TODO fix and remove workaround InterpreterOperation.interpret(xmlGrammar); } @After public void tearDown() { // Grammar g; // if (testGrammarURI != null && (g = GrammarsRegistry.instance().getGrammar(testGrammarURI)) != null) // GrammarsRegistry.instance().removeGrammar(g); // if (xmlGrammarURI != null && (g = GrammarsRegistry.instance().getGrammar(xmlGrammarURI)) != null) // GrammarsRegistry.instance().removeGrammar(g); } @Test public void testNormalizer() throws Exception { Grammar testGrammar = NormalizerOperation.normalize(new TestGrammar().create()); Grammar testGrammarNormalized = new TestGrammarNormalized().create(); Assert.assertTrue(Matcher.match(testGrammarNormalized, testGrammar)); } @Test public void testParseSingleLiteral() { IEntity result = GrammarsUtils.parse( "a literal terminal", testGrammarURI, "SingleLiteral"); Assert.assertNotNull(result); Assert.assertEquals(result.wGetEntityDescriptor().getName(), "SingleLiteral"); } @Test public void testParseSinglePatternLiteral() { IEntity result = GrammarsUtils.parse( "a1b2C3de", testGrammarURI, "SinglePatternLiteral"); Assert.assertNotNull(result); Assert.assertEquals(result.wGetEntityDescriptor().getName(), "SinglePatternLiteral"); } @Test public void testParseLiteralSequence() { IEntity result = GrammarsUtils.parse( "BEGINA666,12,23,34END", testGrammarURI, "LiteralSequence"); Assert.assertNotNull(result); Assert.assertEquals(result.wGetEntityDescriptor().getName(), "LiteralSequence"); } @Test public void testParseSingleData() { IEntity result = GrammarsUtils.parse( "a string", testGrammarURI, "SingleData"); Assert.assertNotNull(result); Assert.assertEquals(result.wGetEntityDescriptor().getName(), "SingleData"); Assert.assertEquals(result.wStringValue(), "a string"); } @Test public void testParseDataSequence() { IEntity result = GrammarsUtils.parse( "(A125,732)", testGrammarURI, "DataSequence"); Assert.assertNotNull(result); Assert.assertEquals(result.wGetEntityDescriptor().getName(), "DataSequence"); Assert.assertEquals(result.wGet(0).wStringValue(), "A"); Assert.assertEquals(DataTypeUtils.getAsPersistenceString(result.wGet(1)), "125"); Assert.assertEquals(DataTypeUtils.getAsPersistenceString(result.wGet(2)), "732"); } @Test public void testParseDataSequenceWithDatatypes() { IEntity result = GrammarsUtils.parse( "(A125,732)", testGrammarURI, "DataSequenceWithDataTypes"); Assert.assertNotNull(result); Assert.assertEquals(result.wGetEntityDescriptor().getName(), "DataSequenceWithDataTypes"); Assert.assertEquals(result.wGet(0).wCharValue(), 'A'); Assert.assertEquals(result.wGet(1).wIntValue(), 125); Assert.assertEquals(result.wGet(2).wIntValue(), 732); } @Test public void testParseOptionalLiteral() { IEntity result1 = GrammarsUtils.parse( "an optional literal terminal", testGrammarURI, "OptionalLiteral"); Assert.assertNotNull(result1); Assert.assertEquals(result1.wGetEntityDescriptor().getName(), "OptionalLiteral"); IEntity result2 = GrammarsUtils.parse( "a literal terminal", testGrammarURI, "OptionalLiteral"); Assert.assertNotNull(result2); Assert.assertEquals(result2.wGetEntityDescriptor().getName(), "OptionalLiteral"); } @Test public void testParseUnparseOptionalConcatenate() { String source = "an optional concatenate"; IEntity result1 = GrammarsUtils.parse(source, testGrammarURI, "OptionalConcatenate"); Assert.assertNotNull(result1); Assert.assertEquals(result1.wGetEntityDescriptor().getName(), "OptionalConcatenate"); StringBuilder sb = new StringBuilder(); GrammarsUtils.unparse(result1, sb, testGrammarURI); Assert.assertEquals(source, sb.toString()); IEntity result2 = GrammarsUtils.parse("a concatenate", testGrammarURI, "OptionalConcatenate"); Assert.assertNotNull(result2); Assert.assertEquals(result2.wGetEntityDescriptor().getName(), "OptionalConcatenate"); sb.setLength(0); GrammarsUtils.unparse(result2, sb, testGrammarURI); Assert.assertEquals(source, sb.toString()); } @Test public void testParseRepeatedLiteral() { IEntity result; try { result = GrammarsUtils.parse("Message: .", testGrammarURI, "RepeatedLiteral"); Assert.fail(); } catch (Exception e) { } result = GrammarsUtils.parse("Message: bla.", testGrammarURI, "RepeatedLiteral"); Assert.assertNotNull(result); Assert.assertEquals(result.wGetEntityDescriptor().getName(), "RepeatedLiteral"); result = GrammarsUtils.parse( "Message: bla bla bla.", testGrammarURI, "RepeatedLiteral"); Assert.assertNotNull(result); Assert.assertEquals(result.wGetEntityDescriptor().getName(), "RepeatedLiteral"); try { result = GrammarsUtils.parse("Message: bla bla bla bla.", testGrammarURI, "RepeatedLiteral"); Assert.fail(); } catch (Exception e) { } } @Test public void testParseRepeatedOptionalLiteral() { IEntity result = GrammarsUtils.parse( "Message: .", testGrammarURI, "RepeatedOptionalLiteral"); Assert.assertNotNull(result); Assert.assertEquals(result.wGetEntityDescriptor().getName(), "RepeatedOptionalLiteral"); result = GrammarsUtils.parse( "Message: bla.", testGrammarURI, "RepeatedOptionalLiteral"); Assert.assertNotNull(result); Assert.assertEquals(result.wGetEntityDescriptor().getName(), "RepeatedOptionalLiteral"); result = GrammarsUtils.parse( "Message: bla bla bla.", testGrammarURI, "RepeatedOptionalLiteral"); Assert.assertNotNull(result); Assert.assertEquals(result.wGetEntityDescriptor().getName(), "RepeatedOptionalLiteral"); try { result = GrammarsUtils.parse( "Message: bla bla bla bla.", testGrammarURI, "RepeatedOptionalLiteral"); Assert.fail(); } catch (Exception e) { } } @Test public void testUnparseXmlElement() { XmlEntityFactory xf = XmlEntityFactory.instance; Element e = xf.createElement( xf.createQualifiedName( xf.createNameSpace("ns"), xf.createName("tag")), xf.createAttributes( xf.createAttribute(xf.createName("attr"), xf.createValue("val")), xf.createAttribute(xf.createName("attr2"), xf.createValue("val2"))), xf.createCharData("test")); StringBuilder sb = new StringBuilder(); GrammarsUtils.unparse(e, sb, xmlGrammarURI); Assert.assertEquals("<ns:tag attr=\"val\" attr2=\"val2\">test</ns:tag>", sb.toString()); } @Category(KnownFailingTests.class) @Test public void testUnparseXmlDocument() throws Exception { IEntity xmlDocument = XmlSourcePersistenceKit.instance().readModel( new StreamPersistenceProvider(getClass().getResourceAsStream("sample.xwl"))); StringBuilder sb = new StringBuilder(); GrammarsUtils.unparse(xmlDocument, sb, xmlGrammarURI); Assert.assertEquals("FIXME encoding and indentation", sb.toString()); } @Category(KnownFailingTests.class) @Test public void testParseXmlDocument() throws Exception { InputStream is = getClass().getResourceAsStream("smallSample.xwl"); IEntity xmlDocument = XmlSourcePersistenceKit.instance().readModel( new StreamPersistenceProvider(is)); is.close(); is = getClass().getResourceAsStream("smallSample.xwl"); String source = StringUtils.readAsString(is, Charset.defaultCharset().name()); is.close(); IEntity xmlDocumentUsingGrammar = GrammarsUtils.parse(source, xmlGrammarURI); Assert.assertTrue(Matcher.match(xmlDocument, xmlDocumentUsingGrammar)); } @Test public void testParseRepeatedUnboundedLiteral() { IEntity result = GrammarsUtils.parse( "Message: .", testGrammarURI, "RepeatedUnboundedLiteral"); Assert.assertNotNull(result); Assert.assertEquals(result.wGetEntityDescriptor().getName(), "RepeatedUnboundedLiteral"); result = GrammarsUtils.parse( "Message: bla.", testGrammarURI, "RepeatedUnboundedLiteral"); Assert.assertNotNull(result); Assert.assertEquals(result.wGetEntityDescriptor().getName(), "RepeatedUnboundedLiteral"); result = GrammarsUtils.parse( "Message: bla bla bla bla bla.", testGrammarURI, "RepeatedUnboundedLiteral"); Assert.assertNotNull(result); Assert.assertEquals(result.wGetEntityDescriptor().getName(), "RepeatedUnboundedLiteral"); } @Test public void testParseChooseLiteral() { IEntity result = GrammarsUtils.parse( "My dog is sleeping.", testGrammarURI, "ChooseLiteral"); Assert.assertNotNull(result); Assert.assertEquals(result.wGetEntityDescriptor().getName(), "ChooseLiteral"); result = GrammarsUtils.parse( "My cat is sleeping.", testGrammarURI, "ChooseLiteral"); Assert.assertNotNull(result); Assert.assertEquals(result.wGetEntityDescriptor().getName(), "ChooseLiteral"); try { result = GrammarsUtils.parse( "My mouse is sleeping.", testGrammarURI, "ChooseLiteral"); Assert.fail(); } catch (Exception e) { } } private String getCSVData() { return "a string, an int, a char, a double\n"+ "abcdefg,123,a,123.45\n"+ //TODO add spaces after commas "defghilm,45,b,789.1"; } @Test public void testParseCSVSimple() { IEntity result = GrammarsUtils.parse(getCSVData(), testGrammarURI, "CSVSimple"); Assert.assertNotNull(result); Assert.assertEquals(result.wGetEntityDescriptor().getName(), "CSVSimple"); } @Test public void testGrammarToModelMapping() { Model m = new XmlModel().create(); Grammar g = new XmlGrammar().create(); Model m1 = GrammarsUtils.deriveModel(g, true); Assert.assertTrue(Matcher.match(m, m1)); } public Grammar createGrammar(Name name, TargetLanguage targetLanguage, Productions lexicalStructure, Productions phraseStructure) { GrammarsEntityFactory gf = GrammarsEntityFactory.instance; return gf.buildGrammar() .set(GrammarsFeatureDescriptorEnum.name, name) .set(GrammarsFeatureDescriptorEnum.targetLanguage, targetLanguage) .set(GrammarsFeatureDescriptorEnum.lexicalStructure, lexicalStructure) .set(GrammarsFeatureDescriptorEnum.phraseStructure, phraseStructure) .getResult(); } public LiteralTerminal createLiteralTerminal(String value) { GrammarsEntityFactory gf = GrammarsEntityFactory.instance; return gf.buildLiteralTerminal().set(GrammarsFeatureDescriptorEnum.literal, value).getResult(); } public Production createProduction(NonTerminal name, Rule rule) { GrammarsEntityFactory gf = GrammarsEntityFactory.instance; return gf.create(GrammarsEntityDescriptorEnum.Production, name, rule); } public Repeat createRepeat(Rule rule) { GrammarsEntityFactory gf = GrammarsEntityFactory.instance; return gf.buildRepeat().set(GrammarsFeatureDescriptorEnum.rule, rule).getResult(); } public DataTerminal createDataTerminal(Pattern pattern, Format format) { GrammarsEntityFactory gf = GrammarsEntityFactory.instance; return gf.buildDataTerminal().set(GrammarsFeatureDescriptorEnum.pattern, pattern).set(GrammarsFeatureDescriptorEnum.format, format).getResult(); } public Grammar buildGrammar() { GrammarsEntityFactory gf = GrammarsEntityFactory.instance; Production data1 = createProduction( gf.createNonTerminal("MyDataNT1"), gf.createAs( createDataTerminal( gf.createRegExp(".*"), gf.createFormat("%s")), gf.createName("MyDataEntity1"))); Production data2 = createProduction( gf.createNonTerminal("MyDataNT2"), gf.createAs( gf.createConcatenate( createLiteralTerminal("BEFORE_DELIMITER"), createDataTerminal( gf.createRegExp(".*"), gf.createFormat("%s")), createLiteralTerminal("AFTER_DELIMITER")), gf.createName("MyDataEntity2"))); Production enum1 = createProduction( gf.createNonTerminal("MyEnumNT1"), gf.createAs( gf.createChoose( gf.createAs(createLiteralTerminal("L1"), gf.createName("V1")), createLiteralTerminal("V2"), gf.createAs(createLiteralTerminal("L3"), gf.createName("V3"))), gf.createName("MyEnumEntity1"))); Production composite1 = createProduction( gf.createNonTerminal("MyCompositeNT1"), gf.createAs( createRepeat(gf.createNonTerminal("MyComponentNT")), gf.createName("MyCompositeEntity1"))); Production composite2 = createProduction( gf.createNonTerminal("MyCompositeNT2"), gf.createAs( gf.createConcatenate( createLiteralTerminal("BEFORE_DELIMITER"), gf.createRepeat( gf.createSize(0), gf.createUnbounded(), createLiteralTerminal(","),//FIXME gf.createFormat(", "))), gf.createNonTerminal("MyComponentNT")), createLiteralTerminal("AFTER_DELIMITER")), gf.createName("MyCompositeEntity2"))); Production simple1 = createProduction( gf.createNonTerminal("MySimpleNT1"), gf.createAs( gf.createConcatenate( gf.createAs(gf.createNonTerminal("MyEnumNT1"), gf.createName("feature1")), gf.createAs(gf.createNonTerminal("MyDataNT1"), gf.createName("feature2"))), gf.createName("MySimpleEntity1"))); Production simple2 = createProduction( gf.createNonTerminal("MySimpleNT2"), gf.createAs( gf.createConcatenate( createLiteralTerminal("BEFORE_DELIMITER"), gf.createAs(gf.createNonTerminal("MyEnumNT1"), gf.createName("feature1")), gf.createOptional( gf.createConcatenate( createLiteralTerminal("FEATURE_DELIMITER"), gf.createAs(gf.createNonTerminal("MyDataNT1"), gf.createName("feature2")))), createLiteralTerminal("AFTER_DELIMITER")), gf.createName("MySimpleEntity2"))); Production abstract1 = createProduction( gf.createNonTerminal("MyComponentNT"), gf.createAs( gf.createChoose( gf.createNonTerminal("MySimpleEntity1"), gf.createNonTerminal("MyDataNT1")), gf.createName("MyAbstractEntity1"))); Production abstract2 = createProduction( gf.createNonTerminal("MyComponentNT2"), gf.createAs( gf.createConcatenate( gf.createAs(gf.createNonTerminal("MyEnumNT1"), gf.createName("inheritedFeature1")), gf.createAs(gf.createNonTerminal("MyDataNT1"), gf.createName("inheritedFeature2")), gf.createChoose( gf.createNonTerminal("MySimpleEntity1"), gf.createNonTerminal("MySimpleEntity2"))), gf.createName("MyAbstractEntity2"))); return createGrammar( gf.createName("MyGrammar"), gf.createURI("MyLanguage"), gf.createProductions(), gf.createProductions(simple1, simple2, abstract1, abstract2, composite1, composite2, enum1, data1, data2)); } public Model buildModel() { ModelsEntityFactory mf = ModelsEntityFactory.instance; return mf.createModel( mf.createSimpleName("MyLanguage"), mf.createTypeRelations(), mf.createModelDeclarations( mf.createSimpleEntity( mf.createEntityModifiers(), mf.createSimpleName("MySimpleEntity1"), mf.createTypes( mf.createSimpleName("MyAbstractEntity1"), mf.createSimpleName("MyAbstractEntity2")), mf.createFeatures( mf.createFeature( mf.createFeatureModifiers(), mf.createSimpleName("MyEnumEntity1"), mf.createSimpleName("feature1"), CommonsEntityAdapterFactory.createResolver(ModelsEntityDescriptorEnum.SimpleName)), mf.createFeature( mf.createFeatureModifiers(), mf.createSimpleName("MyDataEntity1"), mf.createSimpleName("feature2"), CommonsEntityAdapterFactory.createResolver(ModelsEntityDescriptorEnum.SimpleName)))), mf.createSimpleEntity( mf.createEntityModifiers(), mf.createSimpleName("MySimpleEntity2"), mf.createTypes(mf.createSimpleName("MyAbstractEntity2")), mf.createFeatures( mf.createFeature( mf.createFeatureModifiers(), mf.createSimpleName("MyEnumEntity1"), mf.createSimpleName("feature1"), CommonsEntityAdapterFactory.createResolver(ModelsEntityDescriptorEnum.SimpleName)), mf.createFeature( mf.createFeatureModifiers( mf.createFeatureModifier(FeatureModifierEnum.optional)), mf.createSimpleName("MyDataEntity1"), mf.createSimpleName("feature2"), CommonsEntityAdapterFactory.createResolver(ModelsEntityDescriptorEnum.SimpleName)))), mf.createSimpleEntity( mf.createEntityModifiers(mf.createEntityModifier(EntityModifierEnum._abstract)), mf.createSimpleName("MyAbstractEntity1"), mf.createTypes(), mf.createFeatures()), mf.createSimpleEntity( mf.createEntityModifiers(mf.createEntityModifier(EntityModifierEnum._abstract)), mf.createSimpleName("MyAbstractEntity2"), mf.createTypes(), mf.createFeatures( mf.createFeature( mf.createFeatureModifiers(), mf.createSimpleName("MyEnumEntity1"), mf.createSimpleName("inheritedFeature1"), CommonsEntityAdapterFactory.createResolver(ModelsEntityDescriptorEnum.SimpleName)), mf.createFeature( mf.createFeatureModifiers(), mf.createSimpleName("MyDataEntity1"), mf.createSimpleName("inheritedFeature2"), CommonsEntityAdapterFactory.createResolver(ModelsEntityDescriptorEnum.SimpleName)))), mf.createCompositeEntity( mf.createEntityModifiers(), mf.createSimpleName("MyCompositeEntity1"), mf.createTypes(), mf.createComponentModifiers(mf.createComponentModifier(ComponentModifierEnum.ordered)), mf.createSimpleName("MyAbstractEntity1")), mf.createCompositeEntity( mf.createEntityModifiers(), mf.createSimpleName("MyCompositeEntity2"), mf.createTypes(), mf.createComponentModifiers(mf.createComponentModifier(ComponentModifierEnum.unique)), mf.createSimpleName("MyAbstractEntity1")), mf.createEnumEntity( mf.createEntityModifiers(), mf.createSimpleName("MyEnumEntity1"), mf.createTypes(), mf.createEnumValues( mf.createEnumValue("V1"), mf.createEnumValue("V2"), mf.createEnumValue("V3"))), mf.createDataEntity( mf.createEntityModifiers(), mf.createSimpleName("MyDataEntity1"), mf.createTypes(mf.createSimpleName("MyAbstractEntity1")), mf.createDataType("string")), mf.createDataEntity( mf.createEntityModifiers(), mf.createSimpleName("MyDataEntity2"), mf.createTypes(), mf.createDataType("string")) ), mf.createNamespace("org.whole.lang"), mf.createVersion(""), mf.createURI("http://lang.whole.org/MyLanguage")); } }