package com.xtremelabs.robolectric.bytecode;

import org.junit.Assert;
import org.junit.Test;

import com.xtremelabs.robolectric.bytecode.AndroidTranslator;
import com.xtremelabs.robolectric.bytecode.ClassCache;

public class ClassCacheTest {


    @Test
    public void fixForCorberturaAndSonarCodeCoverage() throws InterruptedException {
        final ClassCache classCache = new ClassCache("target/test.txt", AndroidTranslator.CACHE_VERSION);
        
        // Substitute this LOCK with your monitor (could be you object you are
        // testing etc.)
        Thread locker = new Thread() {
            @Override
            public void run() {
                synchronized (classCache) {
                    try {
                        Thread.sleep(Long.MAX_VALUE);
                    } catch (InterruptedException e) {
                        System.out.println("Interrupted.");
                        return;
                    }
                }
            }
        };

        locker.start();

        TestThreadIsWriting attempt = new TestThreadIsWriting(classCache);
        
        try {
            attempt.start();
            int timeToWait = 500;
            long before = System.currentTimeMillis();
            attempt.join(timeToWait, 0);
            long after = System.currentTimeMillis();
            Assert.assertEquals(false, attempt.ready);
            Assert.assertEquals(1, (after - before) / timeToWait);

        } finally {
            
        }
    }

    @Test
    public void fixForCorberturaAndSonarCodeCoverageTheOtherWayAround() throws InterruptedException {
        final ClassCache classCache = new ClassCache("target/test.txt", AndroidTranslator.CACHE_VERSION);
        
        // Substitute this LOCK with your monitor (could be you object you are
        // testing etc.)
        Thread locker = new Thread() {
            @Override
            public void run() {
                synchronized (classCache) {
                    try {
                        Thread.sleep(Long.MAX_VALUE);
                    } catch (InterruptedException e) {
                        System.out.println("Interrupted.");
                        return;
                    }
                }
            }
        };

        locker.start();

        TestThreadSaveAllClassesToCache attempt = new TestThreadSaveAllClassesToCache(classCache);
        
        try {
            attempt.start();
            int timeToWait = 500;
            long before = System.currentTimeMillis();
            attempt.join(timeToWait, 0);
            long after = System.currentTimeMillis();
            Assert.assertEquals(false, attempt.ready);
            Assert.assertEquals(1, (after - before) / timeToWait);
                        
        } finally {
            
        }
    }

    class TestThreadIsWriting extends  Thread {
        public boolean ready = false;
        final ClassCache classCache;
        
        
        public TestThreadIsWriting(ClassCache classCache) {
            super();
            this.classCache = classCache;
        }


        @Override
        public void run() {
            classCache.isWriting();
            ready = true;
        }
    };

    class TestThreadSaveAllClassesToCache extends  Thread {
        public boolean ready = false;
        final ClassCache classCache;
        
        
        public TestThreadSaveAllClassesToCache(ClassCache classCache) {
            super();
            this.classCache = classCache;
        }


        @Override
        public void run() {
            classCache.saveAllClassesToCache(null, null);
            ready = true;
        }
    };

}

@@ -1157,58 +1157,101 @@
     
-attempt.start();%0D%0A            int timeToWait = 500
+int timeToWait = 500;%0D%0A            locker.join(timeToWait, 0);%0D%0A%0D%0A            attempt.start()
 ;%0D%0A 
@@ -1520,24 +1520,55 @@
 meToWait);%0D%0A
+            locker.interrupt();
 %0D%0A        %7D 
@@ -2561,58 +2561,101 @@
     
-attempt.start();%0D%0A            int timeToWait = 500
+int timeToWait = 500;%0D%0A            locker.join(timeToWait, 0);%0D%0A%0D%0A            attempt.start()
 ;%0D%0A 
@@ -2920,32 +2920,65 @@
 / timeToWait);%0D%0A
+            locker.interrupt();%0D%0A
                 

handle and cleanup threads correctly within the unit test