package ro.isdc.wro.model.resource.processor.decorator;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.Arrays;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import ro.isdc.wro.model.resource.Resource;
import ro.isdc.wro.model.resource.ResourceType;
import ro.isdc.wro.model.resource.SupportedResourceType;
import ro.isdc.wro.model.resource.processor.Destroyable;
import ro.isdc.wro.model.resource.processor.ImportAware;
import ro.isdc.wro.model.resource.processor.ResourcePostProcessor;
import ro.isdc.wro.model.resource.processor.ResourcePreProcessor;
import ro.isdc.wro.model.resource.processor.SupportAware;
import ro.isdc.wro.model.resource.processor.impl.CommentStripperProcessor;
import ro.isdc.wro.model.resource.processor.impl.css.CssImportPreProcessor;
import ro.isdc.wro.model.resource.processor.impl.css.CssMinProcessor;
import ro.isdc.wro.model.resource.processor.impl.css.CssVariablesProcessor;
import ro.isdc.wro.model.resource.processor.impl.js.JSMinProcessor;
import ro.isdc.wro.model.resource.processor.impl.js.SemicolonAppenderPreProcessor;
/**
* @author Alex Objelean
*/
public class TestProcessorDecorator {
@Mock
private ResourcePreProcessor mockProcessor;
@Before
public void setUp() {
initMocks(this);
}
@Test(expected = NullPointerException.class)
public void shouldNotAcceptNullProcessor() {
new ProcessorDecorator(null);
}
@Test(expected = IllegalArgumentException.class)
public void shouldNotAcceptInvalidProcessor() {
new ProcessorDecorator(new Object());
}
@Test
public void shouldCreateHelperWithPreProcessor() {
new ProcessorDecorator(new ResourcePreProcessor() {
public void process(final Resource resource, final Reader reader, final Writer writer)
throws IOException {
}
});
}
@Test
public void shouldCreateHelperWithPostProcessor() {
new ProcessorDecorator(new ResourcePostProcessor() {
public void process(final Reader reader, final Writer writer)
throws IOException {
}
});
}
@Test
public void shouldPreserveProcessorMetadataAfterTransform() {
final ResourcePostProcessor postProcessor = new JSMinProcessor();
final ProcessorDecorator decorator = new ProcessorDecorator(postProcessor);
assertTrue(Arrays.equals(new ResourceType[] {ResourceType.JS}, decorator.getSupportedResourceTypes()));
assertTrue(decorator.isMinimize());
}
@Test
public void shouldComputeCorrectlySupportedResourceTypes() {
assertTrue(Arrays.equals(new ResourceType[] {ResourceType.JS}, new ProcessorDecorator(new JSMinProcessor()).getSupportedResourceTypes()));
assertTrue(Arrays.equals(new ResourceType[] {ResourceType.CSS}, new ProcessorDecorator(new CssMinProcessor()).getSupportedResourceTypes()));
assertTrue(Arrays.equals(ResourceType.values(), new ProcessorDecorator(new CommentStripperProcessor()).getSupportedResourceTypes()));
}
@Test
public void shouldDetectJsMinAsMinimizeAwareProcessor() {
assertTrue(new ProcessorDecorator(new JSMinProcessor()).isMinimize());
}
@Test
public void shouldDetectANonMinimizeAwareProcessor() {
assertFalse(new ProcessorDecorator(new SemicolonAppenderPreProcessor()).isMinimize());
}
@Test(expected = NullPointerException.class)
public void cannotAcceptNullResourceTypeForIsEligible() {
assertTrue(new ProcessorDecorator(new JSMinProcessor()).isEligible(true, null));
}
@Test
public void shouldComputeEligibilityForMinimizeAwareProcessorWithJsType() {
assertTrue(new ProcessorDecorator(new JSMinProcessor()).isEligible(true, ResourceType.JS));
assertFalse(new ProcessorDecorator(new JSMinProcessor()).isEligible(true, ResourceType.CSS));
assertFalse(new ProcessorDecorator(new JSMinProcessor()).isEligible(false, ResourceType.JS));
assertFalse(new ProcessorDecorator(new JSMinProcessor()).isEligible(false, ResourceType.CSS));
}
@Test
public void shouldComputeEligibilityForProcessorWithJsType() {
assertTrue(new ProcessorDecorator(new SemicolonAppenderPreProcessor()).isEligible(true, ResourceType.JS));
assertTrue(new ProcessorDecorator(new SemicolonAppenderPreProcessor()).isEligible(false, ResourceType.JS));
assertFalse(new ProcessorDecorator(new SemicolonAppenderPreProcessor()).isEligible(true, ResourceType.CSS));
assertFalse(new ProcessorDecorator(new SemicolonAppenderPreProcessor()).isEligible(false, ResourceType.CSS));
}
@Test
public void shouldComputeEligibilityForProcessorWithCssType() {
assertTrue(new ProcessorDecorator(new CssVariablesProcessor()).isEligible(true, ResourceType.CSS));
assertTrue(new ProcessorDecorator(new CssVariablesProcessor()).isEligible(false, ResourceType.CSS));
assertFalse(new ProcessorDecorator(new CssVariablesProcessor()).isEligible(true, ResourceType.JS));
assertFalse(new ProcessorDecorator(new CssVariablesProcessor()).isEligible(false, ResourceType.JS));
}
@Test
public void shouldComputeEligibilityForMinimizeAwareProcessorWithCssType() {
assertTrue(new ProcessorDecorator(new CssMinProcessor()).isEligible(true, ResourceType.CSS));
assertFalse(new ProcessorDecorator(new CssMinProcessor()).isEligible(false, ResourceType.CSS));
assertFalse(new ProcessorDecorator(new CssMinProcessor()).isEligible(true, ResourceType.JS));
assertFalse(new ProcessorDecorator(new CssMinProcessor()).isEligible(false, ResourceType.JS));
}
@Test
public void shouldComputeEligibilityForProcessorWithNoTypeAndNotMinimizeAware() {
final ResourcePreProcessor noOpProcessor = new ResourcePreProcessor() {
public void process(final Resource resource, final Reader reader, final Writer writer)
throws IOException {
}
};
assertTrue(new ProcessorDecorator(noOpProcessor).isEligible(true, ResourceType.CSS));
assertTrue(new ProcessorDecorator(noOpProcessor).isEligible(false, ResourceType.CSS));
assertTrue(new ProcessorDecorator(noOpProcessor).isEligible(true, ResourceType.JS));
assertTrue(new ProcessorDecorator(noOpProcessor).isEligible(false, ResourceType.JS));
}
@Test
public void shouldChangeMinimizaFlagWhenInternalMethodIsOverriden() {
final ResourcePreProcessor processor = new ProcessorDecorator(new JSMinProcessor()) {
@Override
protected boolean isMinimizeInternal() {
return false;
}
};
assertFalse(new ProcessorDecorator(processor).isMinimize());
}
@Test
public void shouldChangeSupportedTypesWhenInternalMethodIsOverriden() {
final ResourcePreProcessor processor = new ProcessorDecorator(new JSMinProcessor()) {
@Override
protected SupportedResourceType getSupportedResourceTypeInternal() {
return null;
}
};
assertNull(null, new ProcessorDecorator(processor).getSupportedResourceType());
}
@Test
public void shouldComputeIsMinimizeFlagOfDeepNestedDecoratedProcessor() {
final ProcessorDecorator processor = new ProcessorDecorator(new ProcessorDecorator(new ProcessorDecorator(new JSMinProcessor())));
assertTrue(processor.isMinimize());
}
private static class SupportAwareProcessor extends JSMinProcessor implements SupportAware {
public boolean isSupported() {
return true;
}
}
@Test
public void shouldIdentifyProcessorSupport() {
final SupportAwareProcessor supportAwareProcessor = mock(SupportAwareProcessor.class);
final ProcessorDecorator decorator = new ProcessorDecorator(supportAwareProcessor);
when(supportAwareProcessor.isSupported()).thenReturn(true);
assertEquals(true, decorator.isSupported());
when(supportAwareProcessor.isSupported()).thenReturn(false);
assertEquals(false, decorator.isSupported());
}
@Test
public void shouldDecoratePostProcessor() {
final String expected = "TestProcessor";
final ResourcePostProcessor postProcessor = new ResourcePostProcessor() {
public void process(final Reader reader, final Writer writer)
throws IOException {
}
@Override
public String toString() {
return expected;
}
};
final ProcessorDecorator decorator = new ProcessorDecorator(new ProcessorDecorator(new ProcessorDecorator(
postProcessor)));
assertEquals(expected, decorator.toString());
}
@Test
public void shouldNotBeImportAwareForDefaultProcessor() {
final ProcessorDecorator decorator = new ProcessorDecorator(mockProcessor);
assertFalse(decorator.isImportAware());
}
@Test
public void shouldBeImportAwareForImportAwareProcessor() {
final ProcessorDecorator decorator = new ProcessorDecorator(new ImportAwareProcessor());
assertTrue(decorator.isImportAware());
}
private static class ImportAwareProcessor extends CssImportPreProcessor implements ImportAware {
@Override
public boolean isImportAware() {
return true;
}
}
private static class DestroyableProcessor extends CssMinProcessor implements Destroyable {
public void destroy()
throws Exception {
}
}
@Test
public void shouldBeDestroyableProcessorWhenDecoratingDestroyable() throws Exception {
final DestroyableProcessor originalProcessor = Mockito.spy(new DestroyableProcessor());
final ProcessorDecorator decorated = new ProcessorDecorator(originalProcessor);
decorated.destroy();
Mockito.verify(originalProcessor).destroy();
}
}