Skip to content

Commit

Permalink
Merge pull request #9 from rhit-westeraj/DES-20
Browse files Browse the repository at this point in the history
DES-20
  • Loading branch information
FaceFTW authored Apr 23, 2022
2 parents 39e044b + a3e43e7 commit bc77268
Show file tree
Hide file tree
Showing 154 changed files with 1,601 additions and 2,276 deletions.
4 changes: 2 additions & 2 deletions .classpath
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src">
<classpathentry kind="src" output="target/classes" path="src/main">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
Expand All @@ -16,7 +16,7 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="test">
<classpathentry kind="src" output="target/test-classes" path="src/test">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
Expand Down
27 changes: 22 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@
</repository>
</repositories>
<build>
<sourceDirectory>${basedir}/src</sourceDirectory>
<testSourceDirectory>${basedir}/test</testSourceDirectory>
<sourceDirectory>src</sourceDirectory>
<testSourceDirectory>src/test</testSourceDirectory>
<resources></resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<excludes>
<exclude>test/*.java</exclude>
</excludes>
<source>1.8</source>
<target>1.8</target>
</configuration>
Expand All @@ -36,6 +40,13 @@
<groupId>org.pitest</groupId>
<artifactId>pitest-maven</artifactId>
<version>1.7.4</version>
<dependencies>
<dependency>
<groupId>org.pitest</groupId>
<artifactId>pitest-junit5-plugin</artifactId>
<version>0.14</version>
</dependency>
</dependencies>
<configuration>
<targetClasses>
<param>domain.*</param>
Expand Down Expand Up @@ -66,9 +77,15 @@
<version>9.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand Down
1 change: 0 additions & 1 deletion src/main/LinterMain.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
package main;

import java.io.File;
import java.nio.file.Files;
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class PresentationLayer {
// The following represent flags that the wrapper can pass
// to the presentation layer to do various things.
// We have a max of 32 different options, but shouldn't be a problem
public static final int HELP_FLAG = 0x01; //Placeholder flag for Wrapper to use for help
public static final int HELP_FLAG = 0x01; // Placeholder flag for Wrapper to use for help
public static final int VERBOSE_FLAG = 0x02; // Increases Verbosity of Output (Specific details)

// Use the upper bits for analyzer toggles;
Expand Down Expand Up @@ -99,12 +99,12 @@ public void vomitOutput(PrintStream stream) {
int errNum = 0;
int warnNum = 0;
int patternNum = 0;

// TODO Polymorphically implement the return type switches (that should have
// been the solution the whole time)

for (ReturnType returnType : linterReturns) {
stream.format("Linter Name - %s\n", returnType.analyzerName);
stream.println("======================================================================");
for (LinterError error : returnType.errorsCaught) {
stream.format("Class Name - %s\n", error.className);
stream.format("Method Name - %s\n", error.methodName);

String errType = "";
switch (error.type) {
Expand All @@ -130,9 +130,16 @@ public void vomitOutput(PrintStream stream) {
default:
throw new IllegalArgumentException("Error, We somehow got an unexpected enum value!");
}
stream.format("Type - %s\n", errType);
stream.format("Message - %s\n", error.message);
stream.println();
if ((flags & VERBOSE_FLAG) == VERBOSE_FLAG) {
stream.format("Linter Name - %s\n", returnType.analyzerName);
stream.println("======================================================================");
stream.format("Class Name - %s\n", error.className);
stream.format("Method Name - %s\n", error.methodName);
stream.format("Type - %s\n", errType);
stream.format("Message - %s\n", error.message);
stream.println();
}

}

}
Expand Down
25 changes: 25 additions & 0 deletions src/test/AnalyzerFixture.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import java.io.IOException;

import org.junit.jupiter.api.BeforeEach;

import datasource.ASMParser;
import domain.DomainAnalyzer;

public abstract class AnalyzerFixture<T extends DomainAnalyzer> {

protected ASMParser parser;
protected T analyzer;

protected void populateParserData(String[] testDataClasses) {
try {
parser = new ASMParser(testDataClasses);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}


@BeforeEach
protected abstract void initAnalyzerUUT();
}
206 changes: 206 additions & 0 deletions src/test/CodeToInterfaceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

import datasource.ASMParser;
import domain.ErrType;
import domain.LinterError;
import domain.ReturnType;
import domain.analyzer.CodeToInterfaceAnalyzer;

public class CodeToInterfaceTest {
private final String[] ourClass = { "example/code2interface/Code2InterfaceTest" };

// Analyzer Class
private CodeToInterfaceAnalyzer analyzer;

// Instantiate the Analyzer Class
public void setUpOurClass() {
try {
this.analyzer = new CodeToInterfaceAnalyzer(new ASMParser(ourClass));
} catch (IOException e) {
e.printStackTrace();
System.err.println("Error reading from class files specified in arguments!");
System.exit(1);
}
}

// Given no classes, all fields within the analyzer should be blank, and return
// no errors.
@Test
public void testFieldsGivenNoClasses() {
try {
this.analyzer = new CodeToInterfaceAnalyzer(new ASMParser(new String[0]));
} catch (IOException e) {
e.printStackTrace();
System.err.println("Error reading from class files specified in arguments!");
System.exit(1);
}

ReturnType returned = this.analyzer.getFeedback(new String[0]);

// Analyzer entries are null
assertEquals(new HashMap<>(), this.analyzer.getFieldNames());
assertEquals(new HashMap<>(), this.analyzer.getFieldTypes());
assertEquals(new HashMap<>(), this.analyzer.getMethodVarNames());
assertEquals(new HashMap<>(), this.analyzer.getMethodVarTypes());
assertEquals(new HashMap<>(), this.analyzer.getPossibleInterfaces());

assertEquals(new ArrayList<>(), returned.errorsCaught);
}

@Test
public void testFieldsGivenClasses() {
setUpOurClass();
ReturnType returned = this.analyzer.getFeedback(ourClass);

assertNotEquals(new HashMap<>(), this.analyzer.getFieldNames());
assertNotEquals(new HashMap<>(), this.analyzer.getFieldTypes());
assertNotEquals(new HashMap<>(), this.analyzer.getMethodVarNames());
assertNotEquals(new HashMap<>(), this.analyzer.getMethodVarTypes());
assertNotEquals(new HashMap<>(), this.analyzer.getPossibleInterfaces());

assertNotEquals(new ArrayList<>(), returned.errorsCaught);
}

@ParameterizedTest
@ValueSource(strings = {"Field fieldListTest should be of type List<>, not ArrayList<>",
"Field fieldMapTest should be of type Map<>, not HashMap<>",
"Field fieldSetTest should be of type Set<>, not HashSet<>"})
public void testReturnedCollectionFields(String errorMessage) {
setUpOurClass();
ReturnType returned = this.analyzer.getFeedback(ourClass);

assertTrue(returned.errorsCaught.size() > 0);
List<LinterError> errors = returned.errorsCaught;

boolean found = false;
LinterError foundErr = null;
for (LinterError err : errors) {
if (err.message.compareTo(errorMessage) == 0) {
found = true;
foundErr = err;
}
}
assertTrue(found);
assertEquals(ourClass[0], foundErr.className);
assertNull(foundErr.methodName);
assertEquals(ErrType.ERROR, foundErr.type);
}

// Tri4,5 called a Triangle method, and should not throw an error.
// Tri6 already a Shape (even if a Triangle object), so it should not throw an
// error.
@ParameterizedTest
@ValueSource(strings = {"Possible Interface for triangleTest: example/code2interface/Shape",
"Possible Interface for triangleTest: example/code2interface/Triangle",
"Potential Interface for tri4: example/code2interface/Shape",
"Potential Interface for tri5: example/code2interface/Shape",
"Potential Interface for tri6: example/code2interface/Shape"})
public void testNonError(String errorMessage) {
setUpOurClass();
ReturnType returned = this.analyzer.getFeedback(ourClass);

assertTrue(returned.errorsCaught.size() > 0);
List<LinterError> errors = returned.errorsCaught;

boolean found = false;
LinterError foundErr = null;
for (LinterError err : errors) {
if (err.message.compareTo(errorMessage) == 0) {
found = true;
foundErr = err;
}
}
assertFalse(found);
}

// Tests that tri1, tri3 will detect being type Shape
// Tri3 is called by two Shape methods, getArea and compareShape
@ParameterizedTest
@ValueSource(strings = {"Potential Interface for tri1: example/code2interface/Shape",
"Potential Interface for tri1: example/code2interface/Shape",
"Potential Interface for tri3: example/code2interface/Shape"})
public void testMethodVarOfTypeWarnings(String errorMessage) {
setUpOurClass();
ReturnType returned = this.analyzer.getFeedback(ourClass);

assertTrue(returned.errorsCaught.size() > 0);
List<LinterError> errors = returned.errorsCaught;

boolean found = false;
LinterError foundErr = null;
for (LinterError err : errors) {
if (err.message.compareTo(errorMessage) == 0) {
found = true;
foundErr = err;
}
}
assertTrue(found);
assertEquals(ourClass[0], foundErr.className);
assertEquals("testFunc", foundErr.methodName);
assertEquals(ErrType.WARNING, foundErr.type);
}

@ParameterizedTest
@ValueSource(strings = {"Local Variable testList should be of type List<>, not ArrayList<>",
"Local Variable mapTest should be of type Map<>, not HashMap<>",
"Local Variable setTest should be of type Set<>, not HashSet<>"})
public void testMethodVarCollections(String errorMessage) {
setUpOurClass();
ReturnType returned = this.analyzer.getFeedback(ourClass);

assertTrue(returned.errorsCaught.size() > 0);
List<LinterError> errors = returned.errorsCaught;

boolean found = false;
LinterError foundErr = null;
for (LinterError err : errors) {
if (err.message.compareTo(errorMessage) == 0) {
found = true;
foundErr = err;
}
}
assertTrue(found);
assertEquals(ourClass[0], foundErr.className);
assertEquals("anotherFunc", foundErr.methodName);
assertEquals(ErrType.ERROR, foundErr.type);
}

@Test
public void testFindShortcutExits() {
setUpOurClass();
this.analyzer.getRelevantData(ourClass);

// Variable Does Not Exist
assertFalse(this.analyzer.findShortCut(ourClass[0], "testFunc", "tri7"));
assertTrue(this.analyzer.findShortCut(ourClass[0], "anotherFunc", "testList"));
assertTrue(this.analyzer.findShortCut(ourClass[0], "anotherFunc", "mapTest"));
assertTrue(this.analyzer.findShortCut(ourClass[0], "anotherFunc", "setTest"));
}

@Test
public void testClassImplementsOwnMethod() {
setUpOurClass();
this.analyzer.getRelevantData(ourClass);

// Variable Does Not Exist
assertFalse(this.analyzer.findShortCut(ourClass[0], "testFunc", "tri7"));
assertTrue(this.analyzer.findShortCut(ourClass[0], "anotherFunc", "testList"));
assertTrue(this.analyzer.findShortCut(ourClass[0], "anotherFunc", "mapTest"));
assertTrue(this.analyzer.findShortCut(ourClass[0], "anotherFunc", "setTest"));
}

}
Loading

0 comments on commit bc77268

Please sign in to comment.