/* * Copyright (C) 2011 Laurent Caillette * * This program 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. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.novelang.treemangling; import java.util.Arrays; import java.util.Map; import com.google.common.collect.ImmutableMap; import org.junit.Assert; import org.junit.Test; import static org.novelang.parser.NodeKind.*; import static org.novelang.parser.antlr.TreeFixture.tree; import org.novelang.common.SyntacticTree; import org.novelang.common.tree.RobustPath; import org.novelang.common.tree.Treepath; import org.novelang.designator.FragmentIdentifier; import org.novelang.logger.Logger; import org.novelang.logger.LoggerFactory; import org.novelang.parser.antlr.TreeFixture; import org.novelang.treemangling.designator.DesignatorTools; import org.novelang.treemangling.designator.FragmentMapper; /** * Tests for * {@link DesignatorInterpreter#enrich(Treepath, FragmentMapper)} * which modifies identifier stuff in a {@code Treepath}. * * @author Laurent Caillette */ public class DesignatorInterpreterEnrichmentTest { @Test public void enrichNothing() { verifyEnrich( tree( NOVELLA ), tree( NOVELLA ), new FragmentMapperBuilder().build() ) ; } @Test public void enrichWithSimpleAbsoluteIdentifier() { final SyntacticTree levelTree = tree( _LEVEL, tree( ABSOLUTE_IDENTIFIER, tree( "L0" ) ) ) ; final SyntacticTree partTree = tree( NOVELLA, levelTree ) ; final Treepath< SyntacticTree > levelTreepath = Treepath.create( partTree, 0 ) ; verifyEnrich( tree( NOVELLA, tree( _LEVEL, tree( _EXPLICIT_IDENTIFIER, "L0" ) ) ), partTree, new FragmentMapperBuilder(). addPure( new FragmentIdentifier( "L0" ), RobustPath.create( levelTreepath, DesignatorTools.IDENTIFIER_TREE_FILTER ) ).build() ) ; } /** * The {@link DesignatorInterpreter#enrich(Treepath, FragmentMapper)} method adds and removes * trees so it introduces an index shift. * By calling this method two times we check proper handling of index shift. */ @Test public void enrichTwoTimesToCheckResistanceToIndexShift() { final SyntacticTree levelTree0 = tree( _LEVEL, tree( ABSOLUTE_IDENTIFIER, tree( "L0" ) ) ) ; final SyntacticTree levelTree1 = tree( _LEVEL, tree( ABSOLUTE_IDENTIFIER, tree( "L1" ) ) ) ; final SyntacticTree partTree = tree( NOVELLA, levelTree0, levelTree1 ) ; final RobustPath< SyntacticTree > path0 = RobustPath.create( Treepath.create( partTree, 0 ), DesignatorTools.IDENTIFIER_TREE_FILTER ) ; final RobustPath< SyntacticTree > path1 = RobustPath.create( Treepath.create( partTree, 1 ), DesignatorTools.IDENTIFIER_TREE_FILTER ) ; verifyEnrich( tree( NOVELLA, tree( _LEVEL, tree( _EXPLICIT_IDENTIFIER, "L0" ) ), tree( _LEVEL, tree( _EXPLICIT_IDENTIFIER, "L1" ) ) ), partTree, new FragmentMapperBuilder(). addPure(new FragmentIdentifier( "L0" ), path0). addPure(new FragmentIdentifier( "L1" ), path1). build() ) ; } @Test public void enrichWithSimpleImplicitIdentifier() { final SyntacticTree levelTree = tree( _LEVEL ) ; final SyntacticTree partTree = tree( NOVELLA, levelTree ) ; final Treepath< SyntacticTree > levelTreepath = Treepath.create( partTree, 0 ) ; final FragmentMapper< RobustPath< SyntacticTree > > mapper = new FragmentMapperBuilder(). addDerived( new FragmentIdentifier( "L0" ), RobustPath.create( levelTreepath, DesignatorTools.IDENTIFIER_TREE_FILTER ) ).build() ; verifyEnrich( tree( NOVELLA, tree( _LEVEL, tree( _IMPLICIT_IDENTIFIER, "L0" ) ) ), partTree, mapper ) ; } @Test public void beSureOfWhatHappensWithArrayComparison() { final int[] array1 = { 0, 1, 2, 3 } ; final int[] array2 = { 0, 1, 2, 3 } ; Assert.assertTrue( Arrays.equals( array1, array2 ) ); } // ======= // Fixture // ======= private static final Logger LOGGER = LoggerFactory.getLogger( DesignatorInterpreterEnrichmentTest.class ) ; private static class FragmentMapperBuilder { private final ImmutableMap.Builder< FragmentIdentifier, RobustPath< SyntacticTree > > pureIdentifierMapBuilder = new ImmutableMap.Builder< FragmentIdentifier, RobustPath< SyntacticTree > >() ; private final ImmutableMap.Builder< FragmentIdentifier, RobustPath< SyntacticTree > > derivedIdentifierMapBuilder = new ImmutableMap.Builder< FragmentIdentifier, RobustPath< SyntacticTree > >() ; public FragmentMapperBuilder addPure( final FragmentIdentifier key, final RobustPath< SyntacticTree > value ) { pureIdentifierMapBuilder.put( key, value ) ; return this ; } public FragmentMapperBuilder addDerived( final FragmentIdentifier key, final RobustPath< SyntacticTree > value ) { derivedIdentifierMapBuilder.put( key, value ) ; return this ; } public FragmentMapper< RobustPath< SyntacticTree > > build() { final Map< FragmentIdentifier, RobustPath< SyntacticTree > > pure = pureIdentifierMapBuilder.build() ; final Map< FragmentIdentifier, RobustPath< SyntacticTree > > derived = derivedIdentifierMapBuilder.build() ; return new FragmentMapper< RobustPath< SyntacticTree > >() { @Override public Map< FragmentIdentifier, RobustPath< SyntacticTree > > getPureIdentifierMap() { return pure ; } @Override public Map< FragmentIdentifier, RobustPath< SyntacticTree > > getDerivedIdentifierMap() { return derived ; } } ; } } private static void verifyEnrich( final SyntacticTree expectedTree, final SyntacticTree originalTree, final FragmentMapper< RobustPath< SyntacticTree > > fragmentMapper ) { LOGGER.info( "Flat tree: ", TreeFixture.asString( originalTree ) ) ; LOGGER.info( "Expected tree: ", TreeFixture.asString( expectedTree ) ) ; final Treepath< SyntacticTree > expectedTreepath = Treepath.create( expectedTree ) ; final Treepath< SyntacticTree > originalTreepath = Treepath.create( originalTree ) ; final Treepath< SyntacticTree > rehierarchized = DesignatorInterpreterAccessor.enrich( DesignatorTools.TRAVERSAL.first( originalTreepath ), // originalTreepath, fragmentMapper ) ; TreeFixture.assertEqualsNoSeparators( expectedTreepath.getTreeAtEnd(), rehierarchized.getTreeAtEnd() ) ; } private abstract static class DesignatorInterpreterAccessor extends DesignatorInterpreter { /** * Just make the compiler happy. */ private DesignatorInterpreterAccessor() { super( null ) ; } public static Treepath< SyntacticTree > enrich( final Treepath< SyntacticTree > treepath, final FragmentMapper< RobustPath< SyntacticTree > > mapper ) { return DesignatorInterpreter.enrich( treepath, mapper ) ; } } }