Skip to content

Commit

Permalink
[#82] Improved test coverage and javadocs
Browse files Browse the repository at this point in the history
  • Loading branch information
Tobias Stamann committed Mar 18, 2024
1 parent 6774d81 commit e69f5b8
Show file tree
Hide file tree
Showing 6 changed files with 257 additions and 45 deletions.
214 changes: 172 additions & 42 deletions cute/src/main/java/io/toolisticon/cute/CuteApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import javax.tools.StandardLocation;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -1242,41 +1243,58 @@ static DoCustomAssertions myCommand(CompilerTestBB backingBean) {
// Endgame
// --------------------------------------------------------------------

/**
* The compilation outcome.
* Allows custom assertions for compiler messages, generated files and provides classloader.
*/
public static class CompilationOutcome {

private final CompilationResult compilationResult;

private final CuteClassLoader cuteClassLoader;

CompilationOutcome(CompilationResult compilationResult) {
this.compilationResult = compilationResult;
this.cuteClassLoader = new CuteClassLoaderImpl(compilationResult.getCompileTestFileManager());
}

/**
* Checks if compilation was successful.
* @return true if compilation was successful, otherwise false;
*/
public boolean compilationWasSuccessful() {
return this.compilationResult.getCompilationSucceeded();
}

/**
* Gets a list of all compiler messages.
* @return A list of all compiler messages or an empty list if there are none.
*/
public List<CompilerMessage> getCompilerMessages() {
return this.compilationResult.getDiagnostics().getDiagnostics().stream().map(CompilerMessage::new).collect(Collectors.toList());
}

/**
* Provides access to the FileManager.
* @return the FileManager
*/
public FileManager getFileManager () {
return new FileManager(compilationResult.getCompileTestFileManager());
}

/**
* Provides access to the ClassLoader of generated Classes.
* @return the ClassLoader for generated Classes
*/
public CuteClassLoader getClassLoader() {
return new CuteClassLoaderImpl(compilationResult.getCompileTestFileManager());
}

public List<FileObjectWrapper> getFileObjects() {
return this.compilationResult.getCompileTestFileManager().getGeneratedFileObjects().stream().map(FileObjectWrapper::new).collect(Collectors.toList());
}

public List<JavaFileObjectWrapper> getJavaFileObjects() {
return this.compilationResult.getCompileTestFileManager().getGeneratedJavaFileObjects().stream().map(JavaFileObjectWrapper::new).collect(Collectors.toList());
return cuteClassLoader;
}


}

/**
* Represents one single compiler message.
*/
public static class CompilerMessage {

Diagnostic<? extends JavaFileObject> diagnostic;
Expand All @@ -1285,41 +1303,77 @@ public static class CompilerMessage {
this.diagnostic = diagnostic;
}


/**
* Gets the kind of the compiler message.
* @return the kind
*/
public Diagnostic.Kind getKind() {
return diagnostic.getKind();
}

/**
* Gets the compiler message string.
* Uses Locale.English per default.
* @return the message string
*/
public String getMessage() {
return getMessage(Locale.ENGLISH);
}

/**
* Gets the compiler message string.
* @param locale the locale to use
* @return the message string
*/
public String getMessage(Locale locale) {
return diagnostic.getMessage(locale);
}

/**
* Allows checking for column number the compiler message is related to.
* @return the column number of the compiler message
*/
public long getColumnNumber() {
return diagnostic.getColumnNumber();
}

/**
* Allows checking for line number the compiler message is related to.
* @return the line number of the compiler message.
*/
public long getLineNumber() {
return diagnostic.getLineNumber();
}

/**
* Gets the source file name the compiler message is related with.
* @return The source file name
*/
public String getSource() {
return ((FileObject) diagnostic.getSource()).getName();
}


}

/**
* The wrapped file manager used during compilation.
* Allows read access to both (Java)FileObjects.
*/
public static class FileManager {

private final CompileTestFileManager compileTestFileManager;

public FileManager(CompileTestFileManager compileTestFileManager) {
FileManager(CompileTestFileManager compileTestFileManager) {
this.compileTestFileManager = compileTestFileManager;
}

/**
* Gets specific generated source file by className.
* @param className the fully qualified class name to look for
* @return An Optional containing the source file or just an empty Optional if the source file can't be found.
*/
public Optional<JavaFileObjectWrapper> getGeneratedSourceFile(String className){

for (JavaFileObjectWrapper javaFileObjectWrapper : getJavaFileObjects().stream().filter(e -> (e.getKind() == JavaFileObject.Kind.SOURCE)).collect(Collectors.toList())) {
Expand All @@ -1331,6 +1385,11 @@ public Optional<JavaFileObjectWrapper> getGeneratedSourceFile(String className){
return Optional.empty();
}

/**
* Gets specific generated resource file by path.
* @param path the path of the resource file.
* @return An Optional containing the resource file or just an empty Optional if the resource file can't be found.
*/
public Optional<FileObjectWrapper> getGeneratedResourceFile(String path){

for (FileObjectWrapper fileObjectWrapper : getFileObjects()) {
Expand All @@ -1342,102 +1401,173 @@ public Optional<FileObjectWrapper> getGeneratedResourceFile(String path){
return Optional.empty();
}

/**
* Gets all Resource files (FileObjects).
* @return All resource files
*/
public List<FileObjectWrapper> getFileObjects() {
return compileTestFileManager.getGeneratedFileObjects().stream().map(FileObjectWrapper::new).collect(Collectors.toList());
}

/**
* Gets all java related source or class files(JavaFileObjects).
* @return All java source and class files
*/

public List<JavaFileObjectWrapper> getJavaFileObjects() {
return compileTestFileManager.getGeneratedJavaFileObjects().stream().map(JavaFileObjectWrapper::new).collect(Collectors.toList());
}
}

public static class JavaFileObjectWrapper {
public static abstract class AbstractFileObjectWrapper {

private final CompileTestFileManager.AbstractInMemoryOutputFileObject fileObject;

public AbstractFileObjectWrapper(CompileTestFileManager.AbstractInMemoryOutputFileObject fileObject) {
this.fileObject = fileObject;
}

public String getName(){
return fileObject.getName();
}

/**
* Gets the content as a byte array.
* @return the content as a byte array
*/
public byte[] getContentAsByteArray() {
return fileObject.getContent();
}

/**
* Gets the content as a string.
* Encoding errors will be ignored
* @return the content as a string
*/
public String getContent(){
return fileObject.getCharContent(true).toString();
}


}



/**
* Provides read only access to JavaFileObjects.
*/
public static class JavaFileObjectWrapper extends AbstractFileObjectWrapper{
final CompileTestFileManager.InMemoryOutputJavaFileObject javaFileObject;

public JavaFileObjectWrapper(CompileTestFileManager.InMemoryOutputJavaFileObject javaFileObject) {
JavaFileObjectWrapper(CompileTestFileManager.InMemoryOutputJavaFileObject javaFileObject) {
super(javaFileObject);
this.javaFileObject = javaFileObject;

}

/**
* Gets the fully qualified class name.
* @return the fully qualified class name
*/
public String getClassName() {
return javaFileObject.getClassName();
}

/**
* Gets the kind of the JavaFileObject.
* @return the kind of the JavaFileObject
*/
public JavaFileObject.Kind getKind(){
return javaFileObject.getKind();
}

/**
* Gets the nesting kind of the JavaFileObject.
* @return the nesting kind of the JavaFileObject.
*/
public NestingKind getNestingKind(){
return javaFileObject.getNestingKind();
}

/**
* Gets the location to which the JavaFileObject was written to.
* @return the location
*/
public JavaFileManager.Location getLocation() {
return javaFileObject.getLocation();
}

public String getName(){
return javaFileObject.getName();
}

public byte[] getContentAsByteArray() {
return javaFileObject.getContent();
}

public String getContent(){
return javaFileObject.getCharContent(true).toString();
}



}

public static class FileObjectWrapper {
public static class FileObjectWrapper extends AbstractFileObjectWrapper{
final CompileTestFileManager.InMemoryOutputFileObject fileObject;

public FileObjectWrapper(CompileTestFileManager.InMemoryOutputFileObject fileObject) {
super(fileObject);
this.fileObject = fileObject;
}

/**
* Gets the location to which the JavaFileObject was written to.
* @return the location
*/
public JavaFileManager.Location getLocation() {
return fileObject.getLocation();
}

/**
* The package name of file object
* @return the package name
*/
public String getPackageName() {
return fileObject.getPackageName();
}

/**
* The name of the file relative to the package name,
* @return name of the file
*/
public String getRelativeName() {
return fileObject.getRelativeName();
}

public String getName(){
return fileObject.getName();
}

public byte[] getContentAsByteArray() {
return fileObject.getContent();
}

public String getContent(){
return fileObject.getCharContent(true).toString();
}



}



/**
* The endgame interface to provide custom assertions.
*/
public interface DoCustomAssertions {

/**
* This method can be used to execute custom assertions.
* @param customAssertion the custom assertions to do (use lambda!)
*/
void executeCustomAssertions(CustomAssertion customAssertion);

}

/**
* Endgame interface to allow custom assertions.
* This can be used in case you want to do assertions not provided by Cutes fluent api
* or if you just like to do manual assertions.
* Custom assertions can be defined via a lambda.
* By doing this it's possible to wrap assertions and to provide debug output in case of failing assertions or exceptions.
*/
public interface CustomAssertion {
void executeCustomAssertions(CompilationOutcome compilationOutcome);
/**
* The method used to provide custom assertions. Usually this will be used via lambda.
* @param compilationOutcome the compiler outcome.
*/
void executeCustomAssertions(CompilationOutcome compilationOutcome) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, ClassNotFoundException;
}

/**
* The implementation for custom annotations.
*/
private static class DoCustomAssertionsImpl implements DoCustomAssertions {

private final CompilationResult compilationResult;
Expand All @@ -1456,8 +1586,8 @@ public void executeCustomAssertions(CustomAssertion customAssertion) {
customAssertion.executeCustomAssertions(new CompilationOutcome(compilationResult));
} catch (Throwable e) {
FailingAssertionException failingAssertionException = new FailingAssertionException(e.getMessage(), e.getCause());
// will throw an AssertionError
AssertionSpiServiceLocator.locate().fail(e.getMessage() + "\n" + DebugOutputGenerator.getDebugOutput(compilationResult, compileTestConfiguration, failingAssertionException));
throw e;
}

}
Expand Down
Loading

0 comments on commit e69f5b8

Please sign in to comment.