/*
 * test-driven-detectors4findbugs. Copyright (c) 2011 youDevise, Ltd.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * 
 * 
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
 * Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package com.youdevise.fbplugins.tdd4fb;

import static com.youdevise.fbplugins.tdd4fb.TestingBugReporter.tddBugReporter;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

import org.hamcrest.Matcher;
import org.junit.Test;
import org.mockito.ArgumentMatcher;

import edu.umd.cs.findbugs.BugReporter;
import edu.umd.cs.findbugs.Detector;
import edu.umd.cs.findbugs.Detector2;
import edu.umd.cs.findbugs.ba.ClassContext;
import edu.umd.cs.findbugs.classfile.ClassDescriptor;


public class DetectorRunnerTest {

	private final Detector detector = mock(Detector.class);
	private final Detector2 detector2 = mock(Detector2.class);
    private final BugReporter bugReporter = tddBugReporter();

    
    @Test public void runDetectorOnClassVisitsDetectorWithClassContextOfSpecifiedClass() throws Exception {
		new DetectorRunner().runDetectorOnClass(detector, DetectorRunner.class, bugReporter);

		verify(detector).visitClassContext(argThat(isClassContextFor("DetectorRunner")));
	}

	@Test public void runDetector2OnClassVisitsDetectorWithClassContextOfSpecifiedClass() throws Exception {
		new DetectorRunner().runDetectorOnClass(detector2, DetectorRunner.class, bugReporter);

		verify(detector2).visitClass(argThat(isClassDescriptorFor("DetectorRunner")));
	}
	

	public static ArgumentMatcher<ClassContext> isClassContextFor(final String simpleClassName) {
		return new ArgumentMatcher<ClassContext>() {
			@Override public boolean matches(Object argument) {
				if (!(argument instanceof ClassContext)) {
					return false;
				} else {
					return ((ClassContext) argument).getClassDescriptor().getSimpleName().equals(simpleClassName);
				}
			}

		};
	}

	private Matcher<ClassDescriptor> isClassDescriptorFor(final String simpleClassName) {
		return new ArgumentMatcher<ClassDescriptor>() {
			@Override public boolean matches(Object argument) {
				if (!(argument instanceof ClassDescriptor)) {
					return false;
				} else {
					return ((ClassDescriptor) argument).getSimpleName().equals(simpleClassName);
				}
			}
		};
	}
	


}


@@ -1255,24 +1255,158 @@
 ugReporter;%0A
+import static org.hamcrest.MatcherAssert.assertThat;%0Aimport static org.hamcrest.Matchers.is;%0Aimport static org.hamcrest.Matchers.not;%0A
 import stati
@@ -1545,24 +1545,114 @@
 st.Matcher;%0A
+import org.hamcrest.MatcherAssert;%0Aimport org.hamcrest.Matchers;%0Aimport org.junit.Ignore;%0A
 import org.j
@@ -1889,23 +1889,251 @@
 ugs.
-classfile.Class
+ba.XClass;%0Aimport edu.umd.cs.findbugs.ba.XFactory;%0Aimport edu.umd.cs.findbugs.ba.XMethod;%0Aimport edu.umd.cs.findbugs.classfile.ClassDescriptor;%0Aimport edu.umd.cs.findbugs.classfile.DescriptorFactory;%0Aimport edu.umd.cs.findbugs.classfile.Method
 Desc
@@ -3704,13 +3704,1020 @@
 %7D;%0A%09%7D%0A%09%0A
+    @Ignore @Test %0A    public void canRetrieveXClassInfoForAnApplicationClass() throws Exception %7B%0A        BugReporter bugReporter = DetectorAssert.bugReporterForTesting();%0A        MyDetector myDetector = new MyDetector();%0A        DetectorAssert.assertNoBugsReported(SomeClassOfMine.class, myDetector, bugReporter);%0A        %0A        assertThat(myDetector.xMethod.getClass().getSimpleName(), is(not(%22UnresolvedXMethod%22)));%0A    %7D%0A    %0A    public static class SomeClassOfMine %7B%0A        public synchronized void aMethod() %7B%7D%0A    %7D%0A    %0A    public static final class MyDetector implements Detector %7B%0A%0A        private XMethod xMethod;%0A%0A        public void report() %7B %7D%0A%0A        public void visitClassContext(ClassContext classContext) %7B%0A            xMethod = XFactory.createXMethod(DescriptorFactory.instance().getMethodDescriptor(%0A                %22com/youdevise/fbplugins/tdd4fb/DetectorRunnerTest$SomeClassOfMine%22, %0A                %22aMethod%22, %0A                %22()V;%22, %0A                false));%0A        %7D%0A%0A%0A    %7D
 %0A%0A%7D%0A%0A

Add failing test for issue #16.