/* * Copyright 2012 Jason Miller * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jj.script.api; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.*; import static org.mockito.BDDMockito.*; import static jj.script.api.ServerEventScriptResult.*; import java.lang.reflect.Method; import jj.event.Listener; import jj.event.Subscriber; import jj.execution.MockTaskRunner; import jj.execution.TaskRunner; import jj.script.CurrentScriptEnvironment; import jj.script.ScriptEnvironment; import jj.script.ScriptEnvironmentDied; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.mozilla.javascript.Callable; import com.google.inject.Injector; /** * fairly ugly test. but hey! code generation is ugly * @author jason * */ @RunWith(MockitoJUnitRunner.class) public class ServerEventScriptBridgeTest { @Mock CurrentScriptEnvironment env; @Mock Injector injector; @InjectMocks ServerEventScriptBridge sesb; @Mock ScriptEnvironment<?> se; @Mock Callable callable1; @Mock Callable callable2; MockTaskRunner taskRunner; @Mock ServerEventCallableInvoker seci; @Mock ScriptEnvironmentDied sed; @SuppressWarnings("unchecked") @Before public void before() { taskRunner = new MockTaskRunner(); willReturn(se).given(env).current(); // this is really just to return something // javac seems to only like this method. annoying! given(injector.getInstance((Class<? extends ServerEventCallableInvoker>)any(Class.class))).willAnswer(i -> seci); } @Test public void testBasicFlow() throws Exception { assertThat(sesb.subscribe("not an event", callable1), is(NotAnEventClass)); assertThat(sesb.subscribe("jj.script.ScriptEnvironmentDied", callable1), is(Success)); // check that the instance is set up verify(seci).invocationInstances(se, callable1); assertThat(sesb.subscribe("jj.script.ScriptEnvironmentDied", callable1), is(AlreadyBound)); assertThat(sesb.unsubscribe("jj.script.ScriptEnvironmentDied", callable1), is(Success)); verify(seci).kill(); assertThat(sesb.unsubscribe("jj.script.ScriptEnvironmentDied", callable1), is(NotBound)); // in a different method for organization purposes but // we call it from here because we have affirmatively // generated the class we care about at this point testGeneratedClass(); } private void testGeneratedClass() throws Exception { @SuppressWarnings("unchecked") Class<? extends ServerEventCallableInvoker> generated = (Class<? extends ServerEventCallableInvoker>) Class.forName("jj.script.api.GeneratedInvokerFor$$jj_script_ScriptEnvironmentDied"); assertThat(generated.getAnnotation(Subscriber.class), is(notNullValue())); Method bridge = generated.getDeclaredMethod("invocationBridge", ScriptEnvironmentDied.class); assertThat(bridge.getAnnotation(Listener.class), is(notNullValue())); // and now we can test the actual instance ServerEventCallableInvoker instance = generated .getConstructor(TaskRunner.class) .newInstance(taskRunner); instance.invocationInstances(se, callable1); bridge.invoke(instance, sed); taskRunner.runFirstTask(); verify(se).execute(callable1, sed); instance.kill(); bridge.invoke(instance, sed); assertThat(taskRunner.tasks, is(empty())); } @Test public void testMultipleCallables() throws Exception { assertThat(sesb.subscribe("jj.script.ScriptEnvironmentDied", callable1), is(Success)); assertThat(sesb.subscribe("jj.script.ScriptEnvironmentDied", callable2), is(Success)); assertThat(sesb.subscribe("jj.script.ScriptEnvironmentDied", callable1), is(AlreadyBound)); assertThat(sesb.subscribe("jj.script.ScriptEnvironmentDied", callable2), is(AlreadyBound)); assertThat(sesb.unsubscribe("jj.script.ScriptEnvironmentDied", callable1), is(Success)); assertThat(sesb.unsubscribe("jj.script.ScriptEnvironmentDied", callable2), is(Success)); assertThat(sesb.unsubscribe("jj.script.ScriptEnvironmentDied", callable1), is(NotBound)); assertThat(sesb.unsubscribe("jj.script.ScriptEnvironmentDied", callable2), is(NotBound)); assertThat(sesb.subscribe("jj.script.ScriptEnvironmentDied", callable1), is(Success)); assertThat(sesb.subscribe("jj.script.ScriptEnvironmentDied", callable2), is(Success)); } }