[grammar comparison] enhanced grammar comparator to ignore single & multi line comments, added corresponding tests, moved test helper methods & classes into new helper class

Signed-off-by: Christian Schneider <christian.schneider@itemis.de>
This commit is contained in:
Christian Schneider 2015-11-19 13:08:18 +01:00
parent 3507f30bba
commit 4dc072dee7
2 changed files with 241 additions and 30 deletions

View file

@ -7,11 +7,8 @@
*******************************************************************************/
package org.eclipse.xtext.generator.parser
import org.eclipse.xtext.generator.parser.antlr.AntlrGrammarComparator
import org.junit.Test
import static org.junit.Assert.*
/**
* Contributes unit tests for {@link AntlrGrammarComparator}.
*
@ -19,14 +16,8 @@ import static org.junit.Assert.*
*/
class AntlrGrammarComparatorTest {
AntlrGrammarComparator comparator = new AntlrGrammarComparator
private extension AntlrGrammarComparatorTestHelper = new AntlrGrammarComparatorTestHelper();
TestErrorHandler errorHandler = new TestErrorHandler
private def compare(CharSequence grammar, CharSequence grammarReference) {
comparator.compareGrammars(grammar, grammarReference, errorHandler);
}
/**
* The pattern of "\"" is not expected to occur in ANTLR grammar,
* so I use it for testing the unmatched token check.
@ -324,28 +315,157 @@ class AntlrGrammarComparatorTest {
testee.compare(expected)
}
private static class TestErrorHandler implements AntlrGrammarComparator.IErrorHandler {
@Test
def void sLCommentIgnoring01() {
val testee = '''
A: 'A'
// rule B
B: 'B'
'''
override handleMismatch(String match, String matchReference, AntlrGrammarComparator.ErrorContext context) {
fail('''
Inputs differs at token «match» (line «context.testedGrammar.lineNumber»), expected token «
matchReference» (line «context.referenceGrammar.lineNumber» ).
''')
}
val expected = '''
A: 'A'
B: 'B'
'''
override handleInvalidGeneratedGrammarFile(AntlrGrammarComparator.ErrorContext context) {
fail('''
Noticed an unmatched character sequence in 'testee' in/before line «context.testedGrammar.lineNumber».
''')
}
testee.compare(expected)
}
@Test
def void sLCommentIgnoring01b() {
val testee = '''
A: 'A'
B: 'B'
'''
override handleInvalidReferenceGrammarFile(AntlrGrammarComparator.ErrorContext context) {
fail('''
Noticed an unmatched character sequence in 'expected' in/before line «context.referenceGrammar.lineNumber».
''')
}
val expected = '''
A: 'A'
// rule B
B: 'B'
'''
testee.compare(expected)
}
@Test
def void mismatchWithSLComment01() {
val testee = '''
A: 'A'
B: 'B'
'''
val expected = '''
A: 'A'
// rule B
B: 'C'
'''
testee.compareAndExpectMismatchInLines(expected, 3, 4)
}
@Test(expected = AssertionError)
def void mismatchWithSLComment01b() {
val testee = '''
A: 'A'
B: 'B'
'''
val expected = '''
A: 'A'
// rule B
B: 'C'
'''
// expected to fail because of wrong 'lineNoTestee'
testee.compareAndExpectMismatchInLines(expected, 4, 4)
}
@Test
def void mLCommentIgnoring01() {
val testee = '''
A: 'A'
/*
* rule B
*/
B: 'B'
'''
val expected = '''
A: 'A'
B: 'B'
'''
testee.compare(expected)
}
@Test
def void mLCommentIgnoring01b() {
val testee = '''
A: 'A'
B: 'B'
'''
val expected = '''
A: 'A'
/*
* rule B
*/
B: 'B'
'''
testee.compare(expected)
}
@Test
def void mismatchWithMLComment01() {
val testee = '''
A: 'A'
B: 'B'
'''
val expected = '''
A: 'A'
/*
* rule B
*/
B: 'C'
'''
testee.compareAndExpectMismatchInLines(expected, 3, 6)
}
@Test(expected = AssertionError)
def void mismatchWithMLComment01b() {
val testee = '''
A: 'A'
B: 'B'
'''
val expected = '''
A: 'A'
/*
* rule B
*/
B: 'C'
'''
// expected to fail because of wrong 'lineNoExpected'
testee.compareAndExpectMismatchInLines(expected, 3, 5)
}
}

View file

@ -0,0 +1,91 @@
/*******************************************************************************
* Copyright (c) 2015 itemis AG (http://www.itemis.eu) 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
*******************************************************************************/
package org.eclipse.xtext.generator.parser
import org.eclipse.xtext.generator.parser.antlr.AntlrGrammarComparator
/**
* @author Christian Schneider - Initial contribution and API
*/
class AntlrGrammarComparatorTestHelper {
private val AntlrGrammarComparator comparator = new AntlrGrammarComparator
private val TestErrorHandler errorHandler = new TestErrorHandler
def compare(CharSequence grammar, CharSequence grammarReference) {
comparator.compareGrammars(grammar, grammarReference, errorHandler);
}
/**
* This method delegates to 'compare(..., ...)' and expects a {@link ComparisonError} reporting a mismatch
* in the given line numbers. If so the error is dropped. If the error reports different line numbers
* the error is re-thrown indicating a failure in the test. If no error occurs in 'compare(..., ...)'
* this test is supposed to fail.
*/
def compareAndExpectMismatchInLines(String testee, String expected, int lineNoTestee, int lineNoExpected) {
try {
testee.compare(expected)
} catch (ComparisonError e) {
if (lineNoTestee == e.lineNoTestee && lineNoExpected == e.lineNoExpected) {
return
} else {
throw e;
}
}
fail('''Expected mismatch in lines «lineNoTestee»/«lineNoExpected».''')
}
private def static fail(String msg) {
throw new ComparisonError(msg);
}
private def static fail(int lineNoTestee, int lineNoExpected, String msg) {
throw new ComparisonError(lineNoTestee, lineNoExpected, msg);
}
static class ComparisonError extends AssertionError {
private val int lineNoTestee
private val int lineNoExpected
new(String msg) {
super(msg)
this.lineNoTestee = -1
this.lineNoExpected = -1
}
new(int lineNoTestee, int lineNoExpected, String msg) {
super(msg)
this.lineNoTestee = lineNoTestee
this.lineNoExpected = lineNoExpected
}
}
private static class TestErrorHandler implements AntlrGrammarComparator.IErrorHandler {
override handleMismatch(String match, String matchReference, AntlrGrammarComparator.ErrorContext context) {
fail(context.testedGrammar.lineNumber, context.referenceGrammar.lineNumber, '''
Inputs differs at token «match» (line «context.testedGrammar.lineNumber»), expected token «
matchReference» (line «context.referenceGrammar.lineNumber»).
''')
}
override handleInvalidGeneratedGrammarFile(AntlrGrammarComparator.ErrorContext context) {
fail('''
Noticed an unmatched character sequence in 'testee' in/before line «context.testedGrammar.lineNumber».
''')
}
override handleInvalidReferenceGrammarFile(AntlrGrammarComparator.ErrorContext context) {
fail('''
Noticed an unmatched character sequence in 'expected' in/before line «context.referenceGrammar.lineNumber».
''')
}
}
}