/**
* Copyright (C) 2012-2017 the original author 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 ninja.lifecycle;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.Provides;
import com.google.inject.Singleton;
public class LifecycleSupportTest {
@Before
public void setUp() {
MockSingletonService.started = 0;
MockService.started = 0;
}
@Test
public void serviceShouldNotBeStartedBeforeLifecycleServiceIsStarted() {
createInjector().getInstance(MockService.class);
assertThat(MockService.started, equalTo(0));
}
@Test
public void serviceShouldBeStartedWhenLifecycleServiceIsStarted() {
Injector injector = createInjector();
injector.getInstance(MockService.class);
start(injector);
assertThat(MockService.started, equalTo(1));
}
@Test
public void serviceShouldBeStartedIfAccessedAfterLifecycleServiceIsStarted() {
Injector injector = createInjector();
start(injector);
injector.getInstance(MockService.class);
assertThat(MockService.started, equalTo(1));
}
@Test
public void serviceShouldBeStartedIfExplicitlyBoundAndSingleton() {
Injector injector = createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(MockSingletonService.class);
}
});
start(injector);
assertThat(MockSingletonService.started, equalTo(1));
}
@Test
public void serviceShouldBeStartedIfExplicitlyBoundAsSingleton() {
Injector injector = createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(MockService.class).toInstance(new MockService());
}
});
start(injector);
assertThat(MockService.started, equalTo(1));
}
@Test
public void serviceShouldNotBeStartedIfExplicitlyBoundAndNotSingleton() {
Injector injector = createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(MockService.class);
}
});
start(injector);
assertThat(MockService.started, equalTo(0));
}
@Test
public void singletonServiceShouldNotBeStartedTwice() {
Injector injector = createInjector();
injector.getInstance(MockSingletonService.class);
injector.getInstance(MockSingletonService.class);
start(injector);
assertThat(MockSingletonService.started, equalTo(1));
}
@Test
public void nonSingletonServicesShouldBeInstantiatedForEachInstance() {
Injector injector = createInjector();
injector.getInstance(MockService.class);
injector.getInstance(MockService.class);
start(injector);
assertThat(MockService.started, equalTo(2));
}
@Test
public void disposablesShouldBeDisposedOf() {
Injector injector = createInjector();
injector.getInstance(MockService.class);
start(injector);
stop(injector);
assertThat(MockService.disposed, equalTo(1));
}
@Test
public void providedSingletonStartableShouldBeStarted() {
Injector injector = createInjector(new AbstractModule() {
@Override
protected void configure() {
}
@Provides
@Singleton
public MockSingletonService provide() {
return new MockSingletonService();
}
});
start(injector);
assertThat(MockSingletonService.started, equalTo(1));
}
@Test
public void providedSingletonDisposableShouldBeDisposed() {
Injector injector = createInjector(new AbstractModule() {
@Override
protected void configure() {
}
@Provides
@Singleton
public MockSingletonService provide() {
return new MockSingletonService();
}
});
start(injector);
stop(injector);
assertThat(MockSingletonService.disposed, equalTo(1));
}
private Injector createInjector(Module... modules) {
List<Module> ms = new ArrayList<Module>(Arrays.asList(modules));
ms.add(LifecycleSupport.getModule());
return Guice.createInjector(ms);
}
private void start(Injector injector) {
injector.getInstance(LifecycleService.class).start();
}
private void stop(Injector injector) {
injector.getInstance(LifecycleService.class).stop();
}
@Singleton
public static class MockSingletonService {
static int started;
static int disposed;
@Start
public void start() {
started++;
}
@Dispose
public void dispose() {
disposed++;
}
}
public static class MockService {
static int started;
static int disposed;
@Start
public void start() {
started++;
}
@Dispose
public void dispose() {
disposed++;
}
}
}