package com.googlecode.jslint4java.maven;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.junit.matchers.JUnitMatchers.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

import org.codehaus.plexus.util.IOUtil;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import com.googlecode.jslint4java.JSLintResult.ResultBuilder;
import com.googlecode.jslint4java.formatter.JSLintResultFormatter;
import com.googlecode.jslint4java.formatter.JSLintXmlFormatter;

public class ReportWriterImplTest {

    private static final String REPORT_XML = "report.xml";

    @Rule
    public TemporaryFolder tmpf = new TemporaryFolder();

    private final JSLintResultFormatter formatter = new JSLintXmlFormatter();

    private ReportWriterImpl createReportWriter(String filename) {
        return new ReportWriterImpl(new File(tmpf.getRoot(), filename), formatter);
    }

    @Test
    public void createsNonEmptyFile() {
        ReportWriterImpl rw = createReportWriter(REPORT_XML);
        rw.open();
        rw.close();
        assertThat(rw.getReportFile().exists(), is(true));
        assertThat(rw.getReportFile().length(), is(not(0L)));
    }

    @Test
    public void makesParentDirectory() {
        // issue 65: ensure we make *all* intervening directories.
        File parent = new File(new File(tmpf.getRoot(), "some"), "dir");
        ReportWriter rw = new ReportWriterImpl(new File(parent, REPORT_XML), formatter);
        rw.open();
        rw.close();
        assertThat(parent.exists(), is(true));
    }

    /**
     * issue 65: If we configure an invalid report xml, we should blow up with a
     * {@link RuntimeException} (wrapping a
     * {@link FileNotFoundException}). Instead, we're blowing up with an
     * {@link NullPointerException}when we try to close().
     */
    @Test
    public void closeDoesntHideFileNotFoundExceptionWithNullPointerException() throws IOException {
        // This is guaranteed to fail as it's a file not a directory.
        File f  = tmpf.newFile("bob");
        ReportWriter rw = new ReportWriterImpl(new File(f, REPORT_XML), formatter);
        try {
            rw.open();
        } catch (RuntimeException e) {
            // Check we've got the correctly wrapped exception.
            assertThat(e.getCause(), is(FileNotFoundException.class));
        } finally {
            // This shouldn't blow up with an NPE.
            rw.close();
        }
    }

    private String readFile(File reportFile) throws FileNotFoundException, IOException {
        InputStreamReader reader = null;
        try {
            reader = new InputStreamReader(new FileInputStream(reportFile),
                    Charset.forName("UTF-8"));
            return IOUtil.toString(reader);
        } finally {
            IOUtil.close(reader);
        }
    }

    @Test
    public void reportContentsSanity() throws Exception {
        ReportWriterImpl rw = createReportWriter(REPORT_XML);
        rw.open();
        // Create a result with no problems.
        rw.report(new ResultBuilder("foo.js").build());
        rw.close();
        String report = readFile(rw.getReportFile());
        assertThat(report, containsString("<jslint>"));
        assertThat(report, containsString("<file name='foo.js'>"));
        assertThat(report, containsString("</jslint>"));
    }
}

@@ -406,313 +406,1534 @@
 org.
-junit.Rule;%0Aimport org.junit.Test;%0Aimport org.junit.rules.TemporaryFolder;%0A%0Aimport com.googlecode.jslint4java.JSLintResult.ResultBuilder;%0Aimport com.googlecode.jslint4java.formatter.JSLintResultFormatter;%0Aimport com.googlecode.jslint4java.formatter.JSLintXmlFormatter;%0A%0Apublic class ReportWriterImplTest %7B
+hamcrest.BaseMatcher;%0Aimport org.hamcrest.Description;%0Aimport org.hamcrest.Matcher;%0Aimport org.junit.Rule;%0Aimport org.junit.Test;%0Aimport org.junit.rules.ExpectedException;%0Aimport org.junit.rules.TemporaryFolder;%0A%0Aimport com.google.common.base.Throwables;%0Aimport com.googlecode.jslint4java.JSLintResult.ResultBuilder;%0Aimport com.googlecode.jslint4java.formatter.JSLintResultFormatter;%0Aimport com.googlecode.jslint4java.formatter.JSLintXmlFormatter;%0A%0Apublic class ReportWriterImplTest %7B%0A%0A    /** An hamcrest matcher implementation. */%0A    private static class RootCauseMatcher extends BaseMatcher%3CClass%3C? extends Exception%3E%3E %7B%0A        private final Class%3C? extends Exception%3E expectedRootCause;%0A%0A        // TODO: should we take a Matcher instead?%0A        private RootCauseMatcher(Class%3C? extends Exception%3E clazz) %7B%0A            this.expectedRootCause = clazz;%0A        %7D%0A%0A        public boolean matches(Object obj) %7B%0A            if (!(obj instanceof Throwable)) %7B%0A                // Not an exception%0A                return false;%0A            %7D%0A            Throwable e = (Throwable) obj;%0A            Throwable rootCause = Throwables.getRootCause(e);%0A            return rootCause.getClass().equals(expectedRootCause);%0A        %7D%0A%0A        public void describeTo(Description desc) %7B%0A            desc.appendText(%22an exception with root cause %22 + expectedRootCause.getName());%0A        %7D%0A    %7D%0A%0A    private static Matcher%3CClass%3C? extends Exception%3E%3E rootCause(Class%3C? extends Exception%3E e) %7B%0A        return new RootCauseMatcher(e);%0A    %7D
 %0A%0A  
@@ -2054,24 +2054,99 @@
 yFolder();%0A%0A
+    @Rule%0A    public ExpectedException kaboom = ExpectedException.none();%0A%0A
     private 
@@ -3397,32 +3397,143 @@
 s IOException %7B%0A
+        kaboom.expect(RuntimeException.class);%0A        kaboom.expect(rootCause(FileNotFoundException.class));%0A%0A
         // This 
@@ -3750,182 +3750,8 @@
 ();%0A
-        %7D catch (RuntimeException e) %7B%0A            // Check we've got the correctly wrapped exception.%0A            assertThat(e.getCause(), is(FileNotFoundException.class));%0A
     

Switch to ExpectedException.