patterncsharpMinor
Unit test code for Antlr Grammar
Viewed 0 times
antlrgrammarfortestcodeunit
Problem
I'm working on a grammar for the Visual Basic for Applications (VBA) programming language. I've discovered a way to make assertions about how a parse tree should be generated by using the Antlr
My method is this:
What I'm thinking though, is that I may be a little too prescriptive in the final step. As an example, I'm working through the valid identifier use cases in my unit tests:
```
public class ModuleStatementTests
{
private readonly List ambiguousIdentifiers = new List()
{
"Access",
"Alias",
"Append",
"Base",
"Binary",
"ClassInit",
"ClassTerm",
"CLngLng",
"Compare",
"Database",
"DefLngLng",
"Error",
"Explicit",
"Lib",
"Line",
"LongLong",
"Mid",
"MidB",
"Module",
"Object",
"Output",
"Property",
"PtrSafe",
"Random",
"Read",
"Reset",
"Step",
"Text",
"Width"
};
[Fact]
public void CanParseAmbiguousIdentifierInVariableDeclaration()
{
const string variableDeclarationTemplate = "Dim {0} As String";
const string expectedVariableDeclaration =
"(variableDeclaration Dim (variableDclList (variableDcl (untypedVariableDcl (identifier {0}) (asClause (asType As (typeSpec (typeExpression (builtInType (reservedTypeIdentifier String))))))))))";
CanParseAllAmbiguousIdentifiers(variableDeclarationTemplate, expectedVariableDeclaration, p => p.variableDeclaration());
}
private void CanParseAllAmbiguousIdentifiers(string sourceTemplate, string expectedOutputTemplate, Func rule)
{
foreach (var id in ambiguousIdentifiers)
{
var source = string.
ToStringTree method.My method is this:
- Create a parser and give it a code snippet.
- Obtain the parse tree result and turn it into a string using
ToStringTree.
- Perform a string comparison ignoring whitespace.
What I'm thinking though, is that I may be a little too prescriptive in the final step. As an example, I'm working through the valid identifier use cases in my unit tests:
```
public class ModuleStatementTests
{
private readonly List ambiguousIdentifiers = new List()
{
"Access",
"Alias",
"Append",
"Base",
"Binary",
"ClassInit",
"ClassTerm",
"CLngLng",
"Compare",
"Database",
"DefLngLng",
"Error",
"Explicit",
"Lib",
"Line",
"LongLong",
"Mid",
"MidB",
"Module",
"Object",
"Output",
"Property",
"PtrSafe",
"Random",
"Read",
"Reset",
"Step",
"Text",
"Width"
};
[Fact]
public void CanParseAmbiguousIdentifierInVariableDeclaration()
{
const string variableDeclarationTemplate = "Dim {0} As String";
const string expectedVariableDeclaration =
"(variableDeclaration Dim (variableDclList (variableDcl (untypedVariableDcl (identifier {0}) (asClause (asType As (typeSpec (typeExpression (builtInType (reservedTypeIdentifier String))))))))))";
CanParseAllAmbiguousIdentifiers(variableDeclarationTemplate, expectedVariableDeclaration, p => p.variableDeclaration());
}
private void CanParseAllAmbiguousIdentifiers(string sourceTemplate, string expectedOutputTemplate, Func rule)
{
foreach (var id in ambiguousIdentifiers)
{
var source = string.
Solution
I wanted to post an idea I had to address my concern over the brittleness of my unit test(s). I realised that since I am performing a string comparison, that I could use Regular Expressions. Then I can ignore parts of the parse tree string that are not interesting. So I have this as a potential solution:
[Fact]
public void CanParseAmbiguousIdentifierInVariableDeclaration()
{
const string variableDeclarationTemplate = "Dim {0} As String";
const string regexTemplate = @"(\(variableDeclaration.*\(identifier {0}\).*\))";
CanParseAllAmbiguousIdentifiersRegex(variableDeclarationTemplate, regexTemplate,
p => p.variableDeclaration());
}
private void CanParseAllAmbiguousIdentifiersRegex(string sourceTemplate, string regexTemplate, Func rule)
{
foreach (var id in ambiguousIdentifiers)
{
var source = string.Format(sourceTemplate, id);
var regex = string.Format(regexTemplate, id);
CanParseSourceRegex(source, regex, rule);
}
}
private static void CanParseSourceRegex(string source, string regex, Func rule)
{
var parser = VbaCompilerHelper.BuildVbaParser(source);
var result = rule(parser);
Assert.Null(result.exception);
Assert.True(Regex.IsMatch(result.ToStringTree(parser), regex));
}Code Snippets
[Fact]
public void CanParseAmbiguousIdentifierInVariableDeclaration()
{
const string variableDeclarationTemplate = "Dim {0} As String";
const string regexTemplate = @"(\(variableDeclaration.*\(identifier {0}\).*\))";
CanParseAllAmbiguousIdentifiersRegex(variableDeclarationTemplate, regexTemplate,
p => p.variableDeclaration());
}
private void CanParseAllAmbiguousIdentifiersRegex(string sourceTemplate, string regexTemplate, Func<VbaParser, ParserRuleContext> rule)
{
foreach (var id in ambiguousIdentifiers)
{
var source = string.Format(sourceTemplate, id);
var regex = string.Format(regexTemplate, id);
CanParseSourceRegex(source, regex, rule);
}
}
private static void CanParseSourceRegex(string source, string regex, Func<VbaParser, ParserRuleContext> rule)
{
var parser = VbaCompilerHelper.BuildVbaParser(source);
var result = rule(parser);
Assert.Null(result.exception);
Assert.True(Regex.IsMatch(result.ToStringTree(parser), regex));
}Context
StackExchange Code Review Q#97293, answer score: 3
Revisions (0)
No revisions yet.