content: package ro.isdc.wro.model.resource.processor.decorator;
  
  import java.io.IOException;
  import java.io.Reader;
  import java.io.StringReader;
  import java.io.StringWriter;
  import java.io.Writer;
  
  import org.junit.After;
  import org.junit.Assert;
  import org.junit.Before;
  import org.junit.Test;
  import org.mockito.Mock;
  import org.mockito.Mockito;
  import org.mockito.MockitoAnnotations;
  
  import ro.isdc.wro.config.Context;
  import ro.isdc.wro.manager.factory.BaseWroManagerFactory;
  import ro.isdc.wro.model.group.processor.InjectorBuilder;
  import ro.isdc.wro.model.resource.Resource;
  import ro.isdc.wro.model.resource.processor.MinimizeAware;
  import ro.isdc.wro.model.resource.processor.ResourcePostProcessor;
  import ro.isdc.wro.model.resource.processor.ResourcePreProcessor;
  import ro.isdc.wro.model.resource.processor.impl.js.JSMinProcessor;
  
  
  /**
   * @author Alex Objelean
   */
  public class TestMinimizeAwareProcessorDecorator {
    @Mock
    private ResourcePreProcessor mockPreProcessor;
    @Mock
    private ResourcePostProcessor mockPostProcessor;
    private Reader mockReader;
    private Writer mockWriter;
    private MinimizeAwareProcessorDecorator victim;
    /**
     * A processor which performs some sort of minimization.
     */
    private static class MinimizeAwareProcessor
        implements ResourcePreProcessor, ResourcePostProcessor, MinimizeAware {
      public void process(final Reader reader, final Writer writer)
          throws IOException {
      }
      public void process(final Resource resource, final Reader reader, final Writer writer)
          throws IOException {
      }
      public boolean isMinimize() {
        return true;
      }
    }
  
    @Before
    public void setUp() {
      Context.set(Context.standaloneContext());
      MockitoAnnotations.initMocks(this);
      mockReader = new StringReader("");
      mockWriter = new StringWriter();
    }
  
    private void initVictim() {
      InjectorBuilder.create(new BaseWroManagerFactory()).build().inject(victim);
    }
  
    @Test(expected = NullPointerException.class)
    public void cannotAcceptNullProcessor() {
      victim = new MinimizeAwareProcessorDecorator(null, true);
    }
  
    @Test(expected = IllegalArgumentException.class)
    public void cannotAcceptObjectWhichIsNotProcessor() {
      victim = new MinimizeAwareProcessorDecorator(new Object(), true);
    }
  
    @Test
    public void shouldInvokeMinimizePreProcessorWhenMinimizeIsRequired()
        throws Exception {
      final ResourcePreProcessor processor = Mockito.spy(new JSMinProcessor());
      victim = new MinimizeAwareProcessorDecorator(processor, true);
      initVictim();
      victim.process(mockReader, mockWriter);
      Mockito.verify(processor, Mockito.atLeastOnce()).process(Mockito.any(Resource.class), Mockito.any(Reader.class),
          Mockito.any(Writer.class));
    }
  
    @Test
    public void shouldNotInvokeMinimizePreProcessorWhenMinimizeIsNotRequired()
        throws Exception {
      final ResourcePreProcessor processor = Mockito.spy(new JSMinProcessor());
      victim = new MinimizeAwareProcessorDecorator(processor, false);
      initVictim();
      victim.process(mockReader, mockWriter);
      Mockito.verify(processor, Mockito.never()).process(Mockito.any(Resource.class), Mockito.any(Reader.class),
          Mockito.any(Writer.class));
    }
  
    @Test
    public void shouldInvokeMinimizePostProcessorWhenMinimizeIsRequired()
        throws Exception {
  
      final MinimizeAwareProcessor processor = Mockito.spy(new MinimizeAwareProcessor());
      victim = new MinimizeAwareProcessorDecorator(processor, true);
      initVictim();
      victim.process(mockReader, mockWriter);
      Mockito.verify(processor, Mockito.atLeastOnce()).process(Mockito.any(Resource.class), Mockito.any(Reader.class),
          Mockito.any(Writer.class));
    }
  
    @Test
    public void shouldNotInvokeMinimizePostProcessorWhenMinimizeIsNotRequired()
        throws Exception {
      final ResourcePostProcessor processor = Mockito.spy(new JSMinProcessor());
      victim = new MinimizeAwareProcessorDecorator(processor, false);
      initVictim();
      victim.process(mockReader, mockWriter);
      Mockito.verify(processor, Mockito.never()).process(Mockito.any(Reader.class), Mockito.any(Writer.class));
    }
  
    @Test
    public void shouldInvokePreProcessorWhenMinimizeIsRequired()
        throws Exception {
      victim = new MinimizeAwareProcessorDecorator(mockPreProcessor, true);
      initVictim();
      victim.process(mockReader, mockWriter);
      Mockito.verify(mockPreProcessor, Mockito.atLeastOnce()).process(Mockito.any(Resource.class),
          Mockito.any(Reader.class), Mockito.any(Writer.class));
    }
  
    @Test
    public void shouldInvokePreProcessorWhenMinimizeIsNotRequired()
        throws Exception {
      victim = new MinimizeAwareProcessorDecorator(mockPreProcessor, false);
      initVictim();
      victim.process(mockReader, mockWriter);
      Mockito.verify(mockPreProcessor, Mockito.atLeastOnce()).process(Mockito.any(Resource.class),
          Mockito.any(Reader.class), Mockito.any(Writer.class));
    }
  
    @Test
    public void shouldInvokePostProcessorWhenMinimizeIsRequired()
        throws Exception {
      victim = new MinimizeAwareProcessorDecorator(mockPostProcessor, true);
      initVictim();
      victim.process(mockReader, mockWriter);
      Mockito.verify(mockPostProcessor, Mockito.atLeastOnce()).process(Mockito.any(Reader.class),
          Mockito.any(Writer.class));
    }
  
    @Test
    public void shouldInvokePostProcessorWhenMinimizeIsNotRequired()
        throws Exception {
      victim = new MinimizeAwareProcessorDecorator(mockPostProcessor, false);
      initVictim();
      victim.process(mockReader, mockWriter);
      Mockito.verify(mockPostProcessor, Mockito.atLeastOnce()).process(Mockito.any(Reader.class),
          Mockito.any(Writer.class));
    }
  
    @Test
    public void shouldLeaveContentUnchangedWhenProcessorIsSkipped()
        throws Exception {
      final ResourcePreProcessor processor = Mockito.spy(new JSMinProcessor());
      victim = new MinimizeAwareProcessorDecorator(processor, false);
      initVictim();
      final String resourceContent = "var i      =     1;";
      final StringWriter writer = new StringWriter();
      victim.process(new StringReader(resourceContent), writer);
      Mockito.verify(mockPostProcessor, Mockito.never()).process(Mockito.any(Reader.class),
          Mockito.any(Writer.class));
      Assert.assertEquals(resourceContent, writer.toString());
    }
  
    @Test
    public void shouldInvokePreProcessor()
        throws Exception {
      victim = new MinimizeAwareProcessorDecorator(mockPreProcessor);
      initVictim();
      victim.process(null, mockReader, mockWriter);
      Mockito.verify(mockPreProcessor, Mockito.atLeastOnce()).process(Mockito.any(Resource.class), Mockito.any(Reader.class),
          Mockito.any(Writer.class));
    }
  
  
    @Test
    public void shouldInvokePreProcessorWithResourceWantingMinimize()
        throws Exception {
      victim = new MinimizeAwareProcessorDecorator(mockPreProcessor);
      initVictim();
      final Resource resource = Resource.create("someResource.js");
      resource.setMinimize(true);
      victim.process(resource, mockReader, mockWriter);
      Mockito.verify(mockPreProcessor, Mockito.atLeastOnce()).process(Mockito.any(Resource.class), Mockito.any(Reader.class),
          Mockito.any(Writer.class));
    }
  
    @Test
    public void shouldInvokePreProcessorWithResourceNotWantingMinimize()
        throws Exception {
      victim = new MinimizeAwareProcessorDecorator(mockPreProcessor);
      initVictim();
      final Resource resource = Resource.create("someResource.js");
      resource.setMinimize(false);
      victim.process(resource, mockReader, mockWriter);
      Mockito.verify(mockPreProcessor, Mockito.atLeastOnce()).process(Mockito.any(Resource.class), Mockito.any(Reader.class),
          Mockito.any(Writer.class));
    }
  
    @Test
    public void shouldInvokeMinimizeAwarePreProcessorWithResourceWantingMinimize()
        throws Exception {
      victim = new MinimizeAwareProcessorDecorator(new MinimizeAwareProcessor());
      initVictim();
      final Resource resource = Resource.create("someResource.js");
      resource.setMinimize(true);
      victim.process(resource, mockReader, mockWriter);
      Mockito.verify(mockPreProcessor, Mockito.never()).process(Mockito.any(Resource.class), Mockito.any(Reader.class),
          Mockito.any(Writer.class));
    }
  
    @Test
    public void shouldNotInvokeMinimizeAwarePreProcessorWithResourceNotWantingMinimize()
        throws Exception {
      victim = new MinimizeAwareProcessorDecorator(new MinimizeAwareProcessor());
      initVictim();
      final Resource resource = Resource.create("someResource.js");
      resource.setMinimize(false);
      victim.process(resource, mockReader, mockWriter);
      Mockito.verify(mockPreProcessor, Mockito.never()).process(Mockito.any(Resource.class), Mockito.any(Reader.class),
          Mockito.any(Writer.class));
    }
  
    @After
    public void tearDown() {
      Context.unset();
    }
  }
  