package jplag.java17;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import jplag.StrippedProgram;
import jplag.java17.grammar.Java7Lexer;
import jplag.java17.grammar.Java7Parser;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
public class ParserTest {
private static File srcTestResources;
@BeforeClass
public static void getPaths() {
srcTestResources = new File(System.getProperty("user.dir"), "src/test/resources");
}
/**
* Parses a (useless) class that uses all the fancy Java 7 syntax features
* that I was able to find so far. The output is not compared to anything.
* This test should only assure that we have covered all new features with
* the grammar.
*
* @throws IOException
*/
@Test
public void testTheNewFancyJava7Features() throws IOException {
File file = new File(srcTestResources, "Java7FeatureTest.java");
FileInputStream fis = new FileInputStream(file);
ANTLRInputStream input = new ANTLRInputStream(fis);
Java7Lexer lexer = new Java7Lexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
Java7Parser parser = new Java7Parser(tokens);
parser.compilationUnit();
}
@Ignore
public void j7Template() throws IOException {
File file = new File(srcTestResources, "J7StringSwitch.java");
String expected = ""// @formatter:off
+ "********\n"; // @formatter:on
String tokens = parseWithJ7Parser(file, false);
assertEquals(expected, tokens);
}
/**
* added for ticket #58
*/
@Test
public void emptyFileOnlyComments() throws IOException {
compareWithParser15(new File(srcTestResources, "EmptyFileOnlyComments.java"));
}
@Test
public void emptyFile() throws IOException {
compareWithParser15(new File(srcTestResources, "EmptyFile.java"));
}
@Test
public void j7StringSwitchTest() throws IOException {
File file = new File(srcTestResources, "J7StringSwitch.java");
String expected ="" // @formatter:off
+"CLASS{ \n"
+"VOID \n"
+"METHOD{ \n"
+"SWITCH{ \n"
+"CASE \n"
+"BREAK \n"
+"CASE \n"
+"CASE \n"
+"BREAK \n"
+"CASE \n"
+"BREAK \n"
+"}SWITCH \n"
+"}METHOD \n"
+"}CLASS \n"
+ "********\n"; // @formatter:on
String tokens = parseWithJ7Parser(file, false);
assertEquals(expected, tokens);
}
@Test
public void j7TryCatchTest() throws IOException {
File file = new File(srcTestResources, "J7TryCatch.java");
String expected ="IMPORT \n" // @formatter:off
+"IMPORT \n"
+"IMPORT \n"
+"CLASS{ \n"
+"VOID \n"
+"METHOD{ \n"
+"TRY{ \n"
+"CATCH{ \n"
+"}CATCH \n"
+"FINALLY \n"
+"}METHOD \n"
+"VOID \n"
+"METHOD{ \n"
+"TRY{ \n"
+"TRY_RES \n"
+"NEWCLASS\n"
+"APPLY \n"
+"CATCH{ \n"
+"}CATCH \n"
+"}METHOD \n"
+"VOID \n"
+"METHOD{ \n"
+"TRY{ \n"
+"TRY_RES \n"
+"NEWCLASS\n"
+"TRY_RES \n"
+"NEWCLASS\n"
+"APPLY \n"
+"CATCH{ \n"
+"}CATCH \n"
+"}METHOD \n"
+"VOID \n"
+"METHOD{ \n"
+"TRY{ \n"
+"APPLY \n"
+"CATCH{ \n"
+"}CATCH \n"
+"}METHOD \n"
+"VOID \n"
+"METHOD{ \n"
+"TRY{ \n"
+"APPLY \n"
+"CATCH{ \n"
+"}CATCH \n"
+"CATCH{ \n"
+"}CATCH \n"
+"}METHOD \n"
+"}CLASS \n"
+"********\n";// @formatter:on
String tokens = parseWithJ7Parser(file, false);
assertEquals(expected, tokens);
}
@Test
public void compArray() throws IOException {
compareWithParser15(new File(srcTestResources, "ArrayTest.java"));
}
@Test
public void compSimpleClass() throws IOException {
compareWithParser15(new File(srcTestResources, "SimpleClass.java"));
}
@Test
public void compEnum() {
compareWithParser15(new File(srcTestResources, "EnumTest.java"));
}
@Test
public void compGeneric() {
compareWithParser15(new File(srcTestResources, "GenericPocket.java"));
}
@Test
public void compInnerClass() {
compareWithParser15(new File(srcTestResources, "InnerClass.java"));
}
@Test
public void compAnonymousClass() {
compareWithParser15(new File(srcTestResources, "AnonymousClass.java"));
}
@Test
public void compAnnotations_Usage() {
compareWithParser15(new File(srcTestResources, "AnnotationText.java"));
}
@Test
public void compAnnotations_PackageUsage() {
compareWithParser15(new File(srcTestResources, "package-info.java"));
}
@Test
public void compAnnotations_Definition() {
compareWithParser15(new File(srcTestResources, "OptimizeAnnotation.java"));
}
@Test
public void j7Generics() throws IOException {
File file = new File(srcTestResources, "J7Generics.java");
String expected = ""// @formatter:off
+ "CLASS{ \n"
+ "VOID \n"
+ "METHOD{ \n"
+ "GENERIC \n"
+ "VARDEF \n"
+ "ASSIGN \n"
+ "GENERIC \n"
+ "NEWCLASS\n"
+ "}METHOD \n"
+ "}CLASS \n"
+ "********\n"; // @formatter:on
String tokens = parseWithJ7Parser(file, false);
assertEquals(expected, tokens);
}
@Test
public void assureBackwardsCompatibility2() throws IOException {
compareWithParser15(new File(srcTestResources, "ExceptionTwo.java"));
}
@Test
public void assureBackwardsCompatibility3() throws IOException {
compareWithParser15(new File(srcTestResources, "ExceptionThree.java"));
}
@Test
public void assureBackwardsCompatibility4() throws IOException {
compareWithParser15(new File(srcTestResources, "Kalender.java"));
}
/**
* Compare results (token sequence) with Java 1.5 parser (without method
* separators ; if you know why they exist, PLEASE tell us or document at
* https://svn.ipd.kit.edu/trac/jplag/wiki/Server/Frontends/Java-1.5)
*
* @param javaFile
* @throws IOException
*/
private void compareWithParser15(File javaFile) {
if (!javaFile.exists()) {
fail("Test not implemented - cannot find file >" + javaFile + "<");
}
String newTokens = parseWithJ7Parser(javaFile, true);
String oldTokens = parseWithJ5Parser(javaFile);
// compare token sequence?
Assert.assertEquals(oldTokens, newTokens);
}
private String parseWithJ5Parser(File javaFile) {
// parse with old parser
jplag.java15.Parser oldParser = new jplag.java15.Parser(false);
oldParser.setProgram(new StrippedProgram());
jplag.Structure oldStruct = oldParser.parse(javaFile.getParentFile(), new String[] { javaFile.getName() });
String oldTokens = buildTokenString(oldStruct, true);
return oldTokens;
}
/**
* assumes that the token types have not changed from java 1.5 to Java 1.7
* (meaning the integer values are the same but Java 1.7 has more than Java
* 1.5)
*
* @see jplag.java17.JavaToken
*
* @param oldStruct
* @param withDetails
* @return
*/
private String buildTokenString(jplag.Structure oldStruct, boolean withDetails) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < oldStruct.size(); i++) {
sb.append(jplag.java17.JavaToken.type2string(oldStruct.tokens[i].type));
if (withDetails) {
sb.append(" L:" + oldStruct.tokens[i].getLine()
+ " C:" + oldStruct.tokens[i].getLine()
+ " l:" + oldStruct.tokens[i].getLine());
}
sb.append("\n");
}
String oldTokens = sb.toString();
return oldTokens;
}
private String parseWithJ7Parser(File javaFile, boolean withDetails) {
// parse with new parser
jplag.java17.Parser newParser = new Parser();
newParser.setProgram(new StrippedProgram());
jplag.Structure newStruct = newParser.parse(javaFile.getParentFile(), new String[] { javaFile.getName() });
String newTokens = buildTokenString(newStruct, withDetails);
return newTokens;
}
}