package com.googlecode.jslint4java;

import static org.junit.Assert.assertTrue;

import java.util.concurrent.atomic.AtomicReference;

import org.junit.Test;

/**
 * Check that JSLint can safely be used in multiple threads.
 *
 * @see <a href="http://code.google.com/p/jslint4java/issues/detail?id=47">issue 47</a>
 */
public class JSLintThreadSafetyTest {

    private static final String JS = "var a = 'lint this'";

    @Test
    public void canRunSameInstanceInMultipleThreads() throws Exception {
        final JSLint lint = new JSLintBuilder().fromDefault();
        final AtomicReference<Exception> kaboom = new AtomicReference<Exception>();

        // Check that the first one works.
        lint.lint("foo1", JS);

        Thread t = new Thread(new Runnable() {
            public void run() {
                try {
                    // Now check it still works in a different thread.
                    lint.lint("foo2", JS);
                } catch (Exception e) {
                    kaboom.set(e);
                }
            }
        });
        t.start();
        t.join();

        if (kaboom.get() == null) {
            assertTrue("LGTM", true);
        } else {
            // Wrap so that this test gets mentioned in the stack trace.
            throw new RuntimeException(kaboom.get());
        }
    }

    @Test
    public void canBuildInDifferentThread() throws Exception {
        final JSLintBuilder builder = new JSLintBuilder();
        final AtomicReference<Exception> kaboom = new AtomicReference<Exception>();
        Thread t = new Thread(new Runnable() {
            public void run() {
                try {
                    JSLint lint = builder.fromDefault();
                    lint.lint("blort.js", JS);
                } catch (Exception e) {
                    kaboom.set(e);
                }
            }
        });
        t.start();
        t.join();

        if (kaboom.get() == null) {
            assertTrue("LGTM", true);
        } else {
            // Wrap for stack trace.
            throw new RuntimeException(kaboom.get());
        }
    }

}

@@ -560,92 +560,8 @@
 t();
-%0A        final AtomicReference%3CException%3E kaboom = new AtomicReference%3CException%3E();
 %0A%0A  
@@ -641,37 +641,29 @@
         
-Thread t = new Thread
+assertNoRaise
 (new Run
@@ -708,34 +708,8 @@
 ) %7B%0A
-                try %7B%0A    
     
@@ -779,36 +779,32 @@
                 
-    
 lint.lint(%22foo2%22
@@ -818,37 +818,106 @@
             
-    %7D catch (
+%7D%0A        %7D);%0A    %7D%0A%0A    @Test%0A    public void canBuildInDifferentThread() throws 
 Exception e)
@@ -905,35 +905,32 @@
 throws Exception
- e)
  %7B%0A             
@@ -928,52 +928,129 @@
     
-            kaboom.set(e);%0A                %7D
+final JSLintBuilder builder = new JSLintBuilder();%0A        assertNoRaise(new Runnable() %7B%0A            public void run() %7B
 %0A   
@@ -1059,429 +1059,312 @@
     
-   %7D%0A
        
- %7D);%0A        t.start();%0A        t.join();%0A%0A        if (kaboom.get() == null) %7B%0A            assertTrue(%22LGTM%22, true);%0A        %7D else %7B%0A            // Wrap so that this test gets mentioned in the stack trace.%0A            throw new RuntimeException(kaboom.get());
+JSLint lint = builder.fromDefault();%0A                lint.lint(%22blort.js%22, JS);%0A            %7D%0A        %7D);%0A    %7D%0A%0A    /**%0A     * Run %3Ci%3Er%3C/i%3E in a separate thread, and verify that it raises no exceptions.
 %0A     
-   %7D
+*/
 %0A    
-%7D%0A%0A    @Test%0A    public void canBuildInDifferentThread() throws Exception %7B%0A        final JSLintBuilder builder = new JSLintBuilder();
+private static void assertNoRaise(final Runnable r) throws InterruptedException %7B
 %0A   
@@ -1569,89 +1569,14 @@
     
-JSLint lint = builder.fromDefault();%0A                    lint.lint(%22blort.js%22, JS
+r.run(
 );%0A 

Refactor thread safety tests.