Skip to content
Snippets Groups Projects
Tester.java 6.88 KiB
Newer Older
Adam Blank's avatar
Adam Blank committed
import java.util.Scanner;
import java.io.File;

import java.nio.file.Files; 
import java.nio.file.FileSystems; 
import java.io.*;
import java.net.URI;
import java.util.Arrays;

import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject.Kind;

public class Tester {
    public static void cleanup() throws IOException {
        Files.deleteIfExists(FileSystems.getDefault().getPath("DirectRun.class"));
        Files.deleteIfExists(FileSystems.getDefault().getPath("OnMySourceCodeGENERATOR.class"));
    }
    public static void main(String args[]) throws IOException {
        /* Delete all existing .class files to makes sure we're working fresh. */
        cleanup();
               
        /* Create a new compiler. */
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
       
        /* Read in the student OnMySourceCodeGENERATOR.java file */
        String OnMySourceCodeGENERATOR = new Scanner(new File("OnMySourceCodeGENERATOR.java")).useDelimiter("\\Z").next();
       
        /* Create a file for the student code. */
        JavaFileObject studentCode = new JavaSourceFromString("OnMySourceCodeGENERATOR", OnMySourceCodeGENERATOR);
       
        /* Read in the P.input file; so, we know what function we're computing. */
        String P = new Scanner(new File("P.input")).useDelimiter("\\Z").next();
       
        /* Create the DirectRun class to test the output. */
        StringWriter writer = new StringWriter();
        PrintWriter out = new PrintWriter(writer);
        out.println("public class DirectRun {");
        out.println(P);
        out.println("}");
        out.close();
        JavaFileObject directRun = new JavaSourceFromString("DirectRun", writer.toString());
 
        ByteArrayOutputStream baos;    
        Iterable<? extends JavaFileObject> compilationUnits;
        CompilationTask task; 
        boolean compilationSuccess;
       

        /* Compile the student code */
        compilationUnits = Arrays.asList(studentCode);
        task = compiler.getTask(null, null, null, null, null, compilationUnits);
        compilationSuccess = task.call();

        /* Redirect output; so, we can capture the generated code. */
        baos = new ByteArrayOutputStream();
        System.setOut(new PrintStream(baos));
        
        /* Run the student code if we can; otherwise, exit. */
        if (compilationSuccess == false) {
            System.err.println("Your OnMySourceCodeGENERATOR.java file failed to compile!");
            cleanup();
            System.exit(1);
        }
        else {
            try {
                Class.forName("OnMySourceCodeGENERATOR").getDeclaredMethod("OnMySourceCodeGENERATOR", String.class).invoke(null, P);
            } catch (Exception e) {
                System.err.println("Something weird went wrong running your code.  This should never happen.  Come to office hours?\n" + e);
                cleanup();
                System.exit(1);
            }
        }
        String POnMySourceCode = baos.toString();
        System.err.println(POnMySourceCode);
        JavaFileObject POMSC = new JavaSourceFromString("POnMySourceCode", POnMySourceCode);
 
        /* Compile the POnMySourceCode code */
        compilationUnits = Arrays.asList(POMSC);
        task = compiler.getTask(null, null, null, null, null, compilationUnits);
        compilationSuccess = task.call();
        
        /* Run the student code if we can; otherwise, exit. */
        if (compilationSuccess == false) {
            System.err.println("POnMySourceCode (the code generated by OnMySourceCodeGENERATOR) is not valid Java code!");
            cleanup();
            System.exit(1);
        } 
 
        /* Compile the DirectRun code */
        compilationUnits = Arrays.asList(directRun);
        task = compiler.getTask(null, null, null, null, null, compilationUnits);
        compilationSuccess = task.call();

        /* Redirect output; so, we can capture the correct answer. */
        baos = new ByteArrayOutputStream();
        System.setOut(new PrintStream(baos));
        
        /* Run the student code if we can; otherwise, exit. */
        if (compilationSuccess == false) {
            System.err.println("P.input is not valid Java code!");
            cleanup();
            System.exit(1);
        }
        else {
            try {
                Class.forName("DirectRun").getDeclaredMethod("P", String.class).invoke(null, POnMySourceCode);
            } catch (Exception e) {
                System.err.println("Something weird went wrong running DirectRun.  This should never happen.  Come to office hours?\n" + e);
                cleanup();
                System.exit(1);
            }
        }
        String correctBytes = baos.toString();

        cleanup();

        /* Redirect output; so, we can capture the student's answer. */
        baos = new ByteArrayOutputStream();
        System.setOut(new PrintStream(baos));
        try {
            Class.forName("POnMySourceCode").getDeclaredMethod("main", new Class[] { String[].class }).invoke(null, new Object[] { null });
        } catch (Exception e) {
            System.err.println("Something weird went wrong running POnMySourceCode.  This should never happen.  Come to office hours?\n" + e);
            cleanup();
            System.exit(1);
        }
        String studentBytes = baos.toString();

        
        System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
        String BARRIER = "";
        for (int i=0; i < 80; i++) {
            BARRIER += "-";
        }

        System.out.println(BARRIER);
        System.out.println("Your Output Was:");
        System.out.println(BARRIER);
        System.out.println("<" + studentBytes + ">");
        System.out.println(BARRIER);
        
        System.out.println();
        
        System.out.println(BARRIER);
        System.out.println("The Correct Output Was:");
        System.out.println(BARRIER);
        System.out.println("<" + correctBytes + ">");
        System.out.println(BARRIER);

        cleanup();

        if (studentBytes.equals(correctBytes)) {
            System.out.println("Yay!  They match!  You might want to try another P.input function to make sure it's actually working.");
            cleanup();
            System.exit(0);
        }
        else {
            System.out.println("Nope.  They are different somewhere.  Try again.");
            cleanup();
            System.exit(1);
        } 
    }
}

class JavaSourceFromString extends SimpleJavaFileObject {
    final String code;
    public JavaSourceFromString(String name, String code) {
        super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension), Kind.SOURCE);
        this.code = code;
    }

    @Override
    public CharSequence getCharContent(boolean ignoreEncodingErrors) {
        return code;
    }
}