@Test
 public void should_stop_hierarchy_of_containers_on_failure() {
   StartableComponent parentComponent = new StartableComponent();
   final StartableComponent childComponent1 = new StartableComponent();
   final UnstartableComponent childComponent2 = new UnstartableComponent();
   ComponentContainer parentContainer =
       new ComponentContainer() {
         @Override
         public void doAfterStart() {
           ComponentContainer childContainer = new ComponentContainer(this);
           childContainer.add(childComponent1);
           childContainer.add(childComponent2);
           childContainer.execute();
         }
       };
   parentContainer.add(parentComponent);
   try {
     parentContainer.execute();
     fail();
   } catch (Exception e) {
     assertThat(parentComponent.started).isTrue();
     assertThat(parentComponent.stopped).isTrue();
     assertThat(childComponent1.started).isTrue();
     assertThat(childComponent1.stopped).isTrue();
   }
 }
 @Test
 public void test_add_collection() {
   ComponentContainer container = new ComponentContainer();
   container.add(Arrays.asList(ComponentWithProperty.class, SimpleComponent.class));
   assertThat(container.getComponentByType(ComponentWithProperty.class)).isNotNull();
   assertThat(container.getComponentByType(SimpleComponent.class)).isNotNull();
 }
  @Test
  public void stop_exception_should_not_hide_start_exception() {
    ComponentContainer container = new ComponentContainer();
    container.add(UnstartableComponent.class, UnstoppableComponent.class);

    thrown.expect(IllegalStateException.class);
    thrown.expectMessage("Fail to start");
    container.execute();
  }
  @Test
  public void should_sanitize_pico_exception_on_start_failure() {
    ComponentContainer container = new ComponentContainer();
    container.add(UnstartableComponent.class);

    // do not expect a PicoException
    thrown.expect(IllegalStateException.class);
    container.startComponents();
  }
  /** Method close() must be called even if the methods start() or stop() are not defined. */
  @Test
  public void should_close_components_without_lifecycle() {
    ComponentContainer container = new ComponentContainer();
    CloseableComponent component = new CloseableComponent();
    container.add(component);

    container.execute();

    assertThat(component.isClosed).isTrue();
  }
  @Test
  public void should_execute_components() {
    ComponentContainer container = new ComponentContainer();
    StartableComponent component = new StartableComponent();
    container.add(component);

    container.execute();

    assertThat(component.started).isTrue();
    assertThat(component.stopped).isTrue();
  }
  /** Method close() must be executed after stop() */
  @Test
  public void should_close_components_with_lifecycle() {
    ComponentContainer container = new ComponentContainer();
    StartableCloseableComponent component = new StartableCloseableComponent();
    container.add(component);

    container.execute();

    assertThat(component.isStopped).isTrue();
    assertThat(component.isClosed).isTrue();
    assertThat(component.isClosedAfterStop).isTrue();
  }
  @Test
  public void test_stop_failure() {
    ComponentContainer container = new ComponentContainer();
    StartableComponent startable = new StartableComponent();
    container.add(startable, UnstoppableComponent.class);

    try {
      container.execute();
      fail();
    } catch (Exception e) {
      assertThat(startable.started).isTrue();

      // container should stop the components that have already been started
      // ... but that's not the case
    }
  }
 @Test
 public void should_start_and_stop_hierarchy_of_containers() {
   StartableComponent parentComponent = new StartableComponent();
   final StartableComponent childComponent = new StartableComponent();
   ComponentContainer parentContainer =
       new ComponentContainer() {
         @Override
         public void doAfterStart() {
           ComponentContainer childContainer = new ComponentContainer(this);
           childContainer.add(childComponent);
           childContainer.execute();
         }
       };
   parentContainer.add(parentComponent);
   parentContainer.execute();
   assertThat(parentComponent.started).isTrue();
   assertThat(parentComponent.stopped).isTrue();
   assertThat(childComponent.started).isTrue();
   assertThat(childComponent.stopped).isTrue();
 }
 @Test
 public void test_add_adapter() {
   ComponentContainer container = new ComponentContainer();
   container.add(new SimpleComponentProvider());
   assertThat(container.getComponentByType(SimpleComponent.class)).isNotNull();
 }