/* * Copyright (C) 2014-2017 the original authors or authors. * * 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 io.sarl.util.tests.eventdispatching; import static org.junit.Assert.*; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.UUID; import javax.inject.Inject; import com.google.common.collect.Collections2; import org.eclipse.xtext.xbase.lib.Procedures.Procedure1; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import io.sarl.eventdispatching.BehaviorGuardEvaluator; import io.sarl.eventdispatching.BehaviorGuardEvaluatorRegistry; import io.sarl.lang.annotation.PerceptGuardEvaluator; import io.sarl.lang.core.Agent; import io.sarl.lang.core.Behavior; import io.sarl.lang.core.Event; import io.sarl.lang.core.EventListener; import io.sarl.tests.api.AbstractSarlTest; import io.sarl.tests.api.Nullable; /** * @author $Author: sgalland$ * @version $Name$ $Revision$ $Date$ * @mavengroupid $GroupId$ * @mavenartifactid $ArtifactId$ */ @RunWith(Suite.class) @SuiteClasses({ BehaviorGuardEvaluatorRegistryTest.NotConcurrentRegistryTest.class, BehaviorGuardEvaluatorRegistryTest.ConcurrentRegistryTest.class, }) @SuppressWarnings("all") public class BehaviorGuardEvaluatorRegistryTest { public static abstract class AbstractBehaviorGuardEvaluatorRegistryTest extends AbstractSarlTest { @Inject private ReflectExtensions reflect; @Nullable private BehaviorGuardEvaluatorRegistry registry; @Nullable private MyAgent agent; protected abstract BehaviorGuardEvaluatorRegistry createRegistry(); @Before public void setUp() throws Exception { this.agent = new MyAgent(); this.registry = createRegistry(); } private Collection<String> transform(Iterable<BehaviorGuardEvaluator> iterable) { final List<String> result = new ArrayList<>(); for (final BehaviorGuardEvaluator evaluator : iterable) { result.add(evaluator.toString()); } return result; } @Test public void getBehaviorGuardEvaluators_noRegister_event() { Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluators(new Event() { }); assertFalse(evaluators.iterator().hasNext()); } @Test public void getBehaviorGuardEvaluators_myEvent() { Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluators(new MyEvent()); assertFalse(evaluators.iterator().hasNext()); } @Test public void getBehaviorGuardEvaluators_register_event() { this.registry.register(this.agent); Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluators(new Event() { }); assertContains(transform(evaluators), "$perception$guard$evaluator1"); } @Test public void getBehaviorGuardEvaluators_register_myEvent() { this.registry.register(this.agent); Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluators(new MyEvent()); assertContains(transform(evaluators), "$perception$guard$evaluator1", "$perception$guard$evaluator2"); } @Test public void getBehaviorGuardEvaluators_register_event_withValidFilter() { this.registry.register(this.agent, (event) -> true); Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluators(new Event() { }); assertContains(transform(evaluators), "$perception$guard$evaluator1"); } @Test public void getBehaviorGuardEvaluators_register_myEvent_withValidFilter() { this.registry.register(this.agent, (event) -> true); Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluators(new MyEvent()); assertContains(transform(evaluators), "$perception$guard$evaluator1", "$perception$guard$evaluator2"); } @Test public void getBehaviorGuardEvaluators_register_event_withInvalidFilter() { this.registry.register(this.agent, (event) -> false); Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluators(new Event() { }); assertFalse(evaluators.iterator().hasNext()); } @Test public void getBehaviorGuardEvaluators_register_myEvent_withInvalidFilter() { this.registry.register(this.agent, (event) -> false); Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluators(new MyEvent()); assertFalse(evaluators.iterator().hasNext()); } @Test public void unregister() { this.registry.register(this.agent); this.registry.unregister(this.agent); Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluators(new Event() { }); assertFalse(evaluators.iterator().hasNext()); } @Test public void unregisterAll() { this.registry.register(this.agent); this.registry.register(new MyAgent2()); this.registry.register(new MyAgent2()); this.registry.unregisterAll(); Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluators(new Event() { }); assertFalse(evaluators.iterator().hasNext()); } @Test public void unregisterAll_withCallback() { Object subscriber1 = new MyAgent2(); Object subscriber2 = new MyAgent2(); this.registry.register(this.agent); this.registry.register(subscriber1); this.registry.register(subscriber2); Procedure1<Object> callback = Mockito.mock(Procedure1.class); this.registry.unregisterAll(callback); Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluators(new Event() { }); assertFalse(evaluators.iterator().hasNext()); ArgumentCaptor<Object> argument = ArgumentCaptor.forClass(Object.class); Mockito.verify(callback, Mockito.times(3)).apply(argument.capture()); assertContains(argument.getAllValues(), this.agent, subscriber1, subscriber2); } @Test public void getBehaviorGuardEvaluatorsFor_noRegister_event() { Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluatorsFor(new Event() { }, new Object()); assertFalse(evaluators.iterator().hasNext()); } @Test public void getBehaviorGuardEvaluatorsFor_noRegister_event_otherRegistered() { this.registry.register(this.agent); Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluatorsFor(new Event() { }, new Object()); assertFalse(evaluators.iterator().hasNext()); } @Test public void getBehaviorGuardEvaluatorsFor_register_event() { this.registry.register(this.agent); Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluatorsFor(new Event() { }, this.agent); assertContains(transform(evaluators), "$perception$guard$evaluator1"); } @Test public void getBehaviorGuardEvaluatorsFor_register_myEvent() { this.registry.register(this.agent); Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluatorsFor(new MyEvent(), this.agent); assertContains(transform(evaluators), "$perception$guard$evaluator1", "$perception$guard$evaluator2"); } @Test public void getBehaviorGuardEvaluatorsFor_register_event_withValidFilter() { this.registry.register(this.agent, (event) -> true); Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluatorsFor(new Event() { }, this.agent); assertContains(transform(evaluators), "$perception$guard$evaluator1"); } @Test public void getBehaviorGuardEvaluatorsFor_register_myEvent_withValidFilter() { this.registry.register(this.agent, (event) -> true); Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluatorsFor(new MyEvent(), this.agent); assertContains(transform(evaluators), "$perception$guard$evaluator1", "$perception$guard$evaluator2"); } @Test public void getBehaviorGuardEvaluatorsFor_register_event_withInvalidFilter() { this.registry.register(this.agent, (event) -> false); Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluatorsFor(new Event() { }, this.agent); assertContains(transform(evaluators), "$perception$guard$evaluator1"); } @Test public void getBehaviorGuardEvaluatorsFor_register_myEvent_withInvalidFilter() { this.registry.register(this.agent, (event) -> false); Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluatorsFor(new MyEvent(), this.agent); assertContains(transform(evaluators), "$perception$guard$evaluator1", "$perception$guard$evaluator2"); } @Test public void getBehaviorGuardEvaluatorsFor_twoRegisteredAgents_myEvent_01() { Object otherAgent = new MyAgent(); this.registry.register(this.agent); this.registry.register(otherAgent); Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluatorsFor(new MyEvent(), this.agent); assertContains(transform(evaluators), "$perception$guard$evaluator1", "$perception$guard$evaluator2"); } @Test public void getBehaviorGuardEvaluatorsFor_twoRegisteredAgents_myEvent_02() { Object otherAgent = new MyAgent(); this.registry.register(otherAgent); this.registry.register(this.agent); Iterable<BehaviorGuardEvaluator> evaluators = this.registry.getBehaviorGuardEvaluatorsFor(new MyEvent(), this.agent); assertContains(transform(evaluators), "$perception$guard$evaluator1", "$perception$guard$evaluator2"); } @Test public void register_withCallBack_01() { Procedure1<Object> callback = Mockito.mock(Procedure1.class); this.registry.register(this.agent, callback); ArgumentCaptor<Object> argument = ArgumentCaptor.forClass(Object.class); Mockito.verify(callback, Mockito.only()).apply(argument.capture()); assertSame(this.agent, argument.getValue()); } @Test public void register_withCallBack_02() { Procedure1<Object> callback = Mockito.mock(Procedure1.class); this.registry.register(this.agent, callback); this.registry.register(this.agent, callback); ArgumentCaptor<Object> argument = ArgumentCaptor.forClass(Object.class); Mockito.verify(callback, Mockito.only()).apply(argument.capture()); assertSame(this.agent, argument.getValue()); } @Test public void unregister_withCallBack_01() { Procedure1<Object> callback = Mockito.mock(Procedure1.class); this.registry.register(this.agent); this.registry.unregister(this.agent, callback); ArgumentCaptor<Object> argument = ArgumentCaptor.forClass(Object.class); Mockito.verify(callback, Mockito.only()).apply(argument.capture()); assertSame(this.agent, argument.getValue()); } @Test(expected = IllegalArgumentException.class) public void unregister_withCallBack_02() { Procedure1<Object> callback = Mockito.mock(Procedure1.class); this.registry.register(this.agent); this.registry.unregister(this.agent, callback); this.registry.unregister(this.agent, callback); } @Test public void hasRegisteredEventListener() { assertFalse(this.registry.hasRegisteredEventListener(Object.class)); // FakeEventListener eventListener = Mockito.mock(FakeEventListener.class); this.registry.register(eventListener); // assertTrue(this.registry.hasRegisteredEventListener(Object.class)); assertTrue(this.registry.hasRegisteredEventListener(FakeEventListener.class)); assertFalse(this.registry.hasRegisteredEventListener(EventListener.class)); } @Test public void getRegisteredEventListeners() { Collection<Object> collection; // collection = new ArrayList<>(); assertEquals(0, this.registry.getRegisteredEventListeners(Object.class, collection)); assertContains(collection); // FakeEventListener eventListener = Mockito.mock(FakeEventListener.class); this.registry.register(eventListener); // collection = new ArrayList<>(); assertEquals(1, this.registry.getRegisteredEventListeners(Object.class, collection)); assertContains(collection, eventListener); // collection = new ArrayList<>(); assertEquals(1, this.registry.getRegisteredEventListeners(FakeEventListener.class, collection)); assertContains(collection, eventListener); // collection = new ArrayList<>(); assertEquals(0, this.registry.getRegisteredEventListeners(EventListener.class, collection)); assertContains(collection); } /** * @author $Author: sgalland$ * @version $FullVersion$ * @mavengroupid $GroupId$ * @mavenartifactid $ArtifactId$ */ public static class FakeEventListener { @PerceptGuardEvaluator public void handler(Event event, Collection<Runnable> handlers) { // } } } public static class ConcurrentRegistryTest extends AbstractBehaviorGuardEvaluatorRegistryTest { @Override protected BehaviorGuardEvaluatorRegistry createRegistry() { return new BehaviorGuardEvaluatorRegistry(true); } } public static class NotConcurrentRegistryTest extends AbstractBehaviorGuardEvaluatorRegistryTest { @Override protected BehaviorGuardEvaluatorRegistry createRegistry() { return new BehaviorGuardEvaluatorRegistry(false); } } public static class MyEvent extends Event { public int n; } public static class MyAgent extends Agent { public MyAgent() { super(null, UUID.randomUUID(), UUID.randomUUID()); } @PerceptGuardEvaluator private void $perception$guard$evaluator1(Event event, Collection<Runnable> runners) { runners.add(() -> $perception$guard$callback1(event, event)); } private void $perception$guard$callback1(Event occurrence, Event it) { } @PerceptGuardEvaluator private void $perception$guard$evaluator2(MyEvent event, Collection<Runnable> runners) { if (event.n < 0) { runners.add(() -> $perception$guard$callback2(event, event)); } } private void $perception$guard$callback2(MyEvent occurrence, MyEvent it) { } } public static class MyAgent2 extends Agent { public MyAgent2() { super(null, UUID.randomUUID(), UUID.randomUUID()); } @PerceptGuardEvaluator private void $perception$guard$evaluator1(Event event, Collection<Runnable> runners) { runners.add(() -> $perception$guard$callback1(event, event)); } private void $perception$guard$callback1(Event occurrence, Event it) { } @PerceptGuardEvaluator private void $perception$guard$evaluator2(MyEvent event, Collection<Runnable> runners) { runners.add(() -> $perception$guard$callback2(event, event)); } private void $perception$guard$callback2(MyEvent occurrence, MyEvent it) { } } }