/* * 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.parser.antlr; import com.google.common.base.Joiner; import org.antlr.runtime.RecognitionException; import org.junit.Assert; import org.junit.Test; import static org.novelang.parser.antlr.AntlrTestHelper.BREAK; import org.novelang.common.Problem; import org.novelang.logger.Logger; import org.novelang.logger.LoggerFactory; /** * Get sure that delimiters problems are correctly reported. * * @author Laurent Caillette */ public class DelimiterProblemTest { @Test public void symmetricalOk() throws RecognitionException { final String text = "( z )" ; process( text ); } @Test public void nonSymmetricalOk() throws RecognitionException { final String text = "-- z --" ; process( text ) ; } @Test public void nonSymmetricalUnclosedAlone() throws RecognitionException { final String text = "y -- z" ; process( text, problem( 1, 2, "'--'" ) ) ; } @Test public void symmetricalUnclosedAlone() throws RecognitionException { final String text = "( z" ; process( text, problem( 1, 0, "'('" ) ) ; } @Test public void nonSymmetricalUnclosedInsideSymmetrical() throws RecognitionException { final String text = "( w " + BREAK + "x -- y" + BREAK + "z )" ; process( text, problem( 2, 2, "'--'" ) ) ; } @Test public void symmetricalUnclosedInsideNonSymmetrical() throws RecognitionException { final String text = "-- w " + BREAK + "x ( y" + BREAK + "z --" ; process( text, problem( 2, 2, "'('" ) ) ; } @Test public void twoSymmetricalUnclosedInsideNonSymmetrical() throws RecognitionException { final String text = "-- u " + BREAK + "v ( w" + BREAK + "x [ y" + BREAK + "z --" ; process( text, problem( 2, 2, "'('" ), problem( 3, 2, "[" ) ) ; } @Test public void boundarySwitch() throws RecognitionException { final String text = "( s " + BREAK + "t -- u" + BREAK + "v )" + BREAK + BREAK + "// w " + BREAK + "x [ y" + BREAK + "z //" + BREAK ; process( text, problem( 2, 2, "'--'" ), problem( 6, 2, "'['" ) ) ; } // ======= // Fixture // ======= private static final Logger LOGGER = LoggerFactory.getLogger( DelimiterProblemTest.class ) ; private static void process( final String text, final ProblemSignature... signatures ) { LOGGER.info( BREAK + text ) ; final DelegatingPartParser parser = AntlrTestHelper.createPartParser( text ) ; parser.parse() ; final Iterable< Problem > problems = parser.getProblems() ; LOGGER.debug( "Faulty blocks: ", problems.iterator().hasNext() ? "\n " + Joiner.on( "\n " ).join( problems ) : "none." ) ; if( signatures.length == 0 ) { Assert.assertFalse( problems.iterator().hasNext() ); } else { for( final ProblemSignature signature : signatures ) { Assert.assertTrue( "Got: " + problems, signature.in( problems ) ) ; } } } private static ProblemSignature problem( final int line, final int column, final String messageFragment ) { return new ProblemSignature( line, column, messageFragment ) ; } private static class ProblemSignature { private final int line ; private final int column ; private final String messageElement ; private ProblemSignature( final int line, final int column, final String messageElement ) { this.line = line; this.column = column; this.messageElement = messageElement; } private boolean in( final Problem problem ) { return problem.getLocation().getLine() == line && problem.getLocation().getColumn() == column && problem.getMessage().contains( messageElement ) ; } private boolean in( final Iterable< Problem > problems ) { for( final Problem problem : problems ) { if( in( problem ) ) { return true ; } } return false ; } } }