/*
* Copyright 2017 Laszlo Balazs-Csiki
*
* This file is part of Pixelitor. Pixelitor is free software: you
* can redistribute it and/or modify it under the terms of the GNU
* General Public License, version 3 as published by the Free
* Software Foundation.
*
* Pixelitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Pixelitor. If not, see <http://www.gnu.org/licenses/>.
*/
package pixelitor.layers;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
import pixelitor.Canvas;
import pixelitor.Composition;
import pixelitor.TestHelper;
import pixelitor.history.History;
import pixelitor.history.LayerOpacityEdit;
import pixelitor.testutils.WithMask;
import java.awt.Rectangle;
import java.util.Arrays;
import java.util.Collection;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertSame;
import static org.mockito.Mockito.spy;
/**
* Tests the functionality common to all Layer subclasses
*/
@RunWith(Parameterized.class)
public class LayerTest {
private Composition comp;
private Layer layer;
@Parameter
public Class<Layer> layerClass;
@Parameter(value = 1)
public WithMask withMask;
private IconUpdateChecker iconUpdates;
@Parameters(name = "{index}: {0}, mask = {1}")
public static Collection<Object[]> instancesToTest() {
return Arrays.asList(new Object[][]{
{ImageLayer.class, WithMask.NO},
{ImageLayer.class, WithMask.YES},
{TextLayer.class, WithMask.NO},
{TextLayer.class, WithMask.YES},
{AdjustmentLayer.class, WithMask.NO},
{AdjustmentLayer.class, WithMask.YES},
});
}
@Before
public void setUp() {
comp = TestHelper.createEmptyComposition();
// make sure each test runs with a fresh Layer
layer = TestHelper.createLayerOfClass(layerClass, comp);
// LayerUI ui = mock(LayerUI.class);
LayerGUI ui = spy(layer.getUI());
layer.setUI(ui);
comp.addLayerNoGUI(layer);
ImageLayer layer2 = TestHelper.createImageLayer("LayerTest layer 2", comp);
comp.addLayerNoGUI(layer2);
withMask.init(layer);
LayerMask mask = null;
if (withMask.isYes()) {
mask = layer.getMask();
}
iconUpdates = new IconUpdateChecker(ui, layer, mask, 0, 1);
comp.setActiveLayer(layer, true);
assert comp.getNumLayers() == 2 : "found " + comp.getNumLayers() + " layers";
// TODO this should be automatic for all tests
// or should be avoidable
TestHelper.setupAnActiveICFor(comp);
History.clear();
}
@Test
public void test_setVisible() {
LayerGUI layerUI = layer.getUI();
assertThat(layer.isVisible()).isTrue();
assertThat(layerUI.isVisibilityChecked()).isTrue();
layer.setVisible(false, true);
assertThat(layer.isVisible()).isFalse();
assertThat(layerUI.isVisibilityChecked()).isFalse();
History.assertNumEditsIs(1);
History.assertLastEditNameIs("Hide Layer");
History.undo();
assertThat(layer.isVisible()).isTrue();
assertThat(layerUI.isVisibilityChecked()).isTrue();
History.redo();
assertThat(layer.isVisible()).isFalse();
assertThat(layerUI.isVisibilityChecked()).isFalse();
iconUpdates.check(0, 0);
}
@Test
public void test_duplicate() {
Layer copy = layer.duplicate(false);
assertThat(copy.getName()).isEqualTo("layer 1 copy");
assertThat(copy.getClass()).isEqualTo(layer.getClass());
Layer copy2 = copy.duplicate(false);
assertThat(copy2.getName()).isEqualTo("layer 1 copy 2");
Layer copy3 = copy2.duplicate(false);
assertThat(copy3.getName()).isEqualTo("layer 1 copy 3");
Layer exactCopy = layer.duplicate(true);
assertThat(exactCopy.getName()).isEqualTo("layer 1");
iconUpdates.check(0, 0);
}
@Test
public void testOpacityChange() {
float oldValue = 1.0f;
float newValue = 0.7f;
assertThat(layer.getOpacity()).isEqualTo(oldValue);
layer.setOpacity(newValue, true, true, true);
assertThat(layer.getOpacity()).isEqualTo(newValue);
History.assertNumEditsIs(1);
History.assertLastEditNameIs("Layer Opacity Change");
LayerOpacityEdit lastEdit = (LayerOpacityEdit) History.getLastEdit();
assertSame(layer, lastEdit.getLayer());
History.undo();
float opacity = layer.getOpacity();
assertThat(opacity).isEqualTo(oldValue);
History.redo();
assertThat(layer.getOpacity()).isEqualTo(newValue);
iconUpdates.check(0, 0);
}
@Test
public void testBlendingModeChange() {
assertSame(BlendingMode.NORMAL, layer.getBlendingMode());
layer.setBlendingMode(BlendingMode.DIFFERENCE, true, true, true);
assertSame(BlendingMode.DIFFERENCE, layer.getBlendingMode());
History.assertNumEditsIs(1);
History.assertLastEditNameIs("Blending Mode Change");
History.undo();
assertSame(BlendingMode.NORMAL, layer.getBlendingMode());
History.redo();
assertSame(BlendingMode.DIFFERENCE, layer.getBlendingMode());
iconUpdates.check(0, 0);
}
@Test
public void testNameChange() {
assertThat(layer.getName()).isEqualTo("layer 1");
layer.setName("newName", true);
assertThat(layer.getName()).isEqualTo("newName");
assertThat(layer.getUI().getLayerName()).isEqualTo("newName");
History.assertNumEditsIs(1);
History.assertLastEditNameIs("Rename Layer to \"newName\"");
History.undo();
assertThat(layer.getName()).isEqualTo("layer 1");
assertThat(layer.getUI().getLayerName()).isEqualTo("layer 1");
History.redo();
assertThat(layer.getName()).isEqualTo("newName");
assertThat(layer.getUI().getLayerName()).isEqualTo("newName");
iconUpdates.check(0, 0);
}
@Test
public void test_mergeDownOn() {
ImageLayer lower = TestHelper.createImageLayer("lower", comp);
layer.mergeDownOn(lower);
iconUpdates.check(0, 0);
}
@Test
public void test_makeActive() {
Layer layer2 = comp.getLayer(1);
assertThat(layer2.isActive()).isFalse();
layer2.makeActive(true);
assertThat(layer2.isActive()).isTrue();
History.assertNumEditsIs(1);
History.assertLastEditNameIs("Layer Selection Change");
History.undo();
assertThat(layer2.isActive()).isFalse();
History.redo();
assertThat(layer2.isActive()).isTrue();
iconUpdates.check(0, 0);
}
@Test
public void test_resize() {
Canvas canvas = layer.getComp().getCanvas();
int canvasWidth = canvas.getWidth();
int canvasHeight = canvas.getHeight();
layer.resize(canvasWidth, canvasHeight, true);
layer.resize(30, 25, true);
layer.resize(25, 30, false);
layer.resize(canvasWidth, canvasHeight, true);
iconUpdates.check(0, 0);
}
@Test
public void test_crop() {
layer.crop(new Rectangle(3, 3, 5, 5));
iconUpdates.check(0, 0);
}
@Test
public void test_dragFinished() {
assertThat(comp.getLayerIndex(layer)).isEqualTo(0);
layer.dragFinished(1);
assertThat(comp.getLayerIndex(layer)).isEqualTo(1);
iconUpdates.check(0, 0);
}
@Test
public void test_addMask() {
if (!withMask.isYes()) {
assertThat(layer.hasMask()).isFalse();
layer.addMask(LayerMaskAddType.REVEAL_ALL);
assertThat(layer.hasMask()).isTrue();
History.assertNumEditsIs(1);
History.assertLastEditNameIs("Add Layer Mask");
History.undo();
assertThat(layer.hasMask()).isFalse();
History.redo();
assertThat(layer.hasMask()).isTrue();
iconUpdates.check(0, 0);
}
}
@Test
public void test_deleteMask() {
if (withMask.isYes()) {
assertThat(layer.hasMask()).isTrue();
layer.deleteMask(true);
assertThat(layer.hasMask()).isFalse();
History.assertNumEditsIs(1);
History.assertLastEditNameIs("Delete Layer Mask");
iconUpdates.check(0, 0);
History.undo();
assertThat(layer.hasMask()).isTrue();
iconUpdates.check(0, 1);
History.redo();
assertThat(layer.hasMask()).isFalse();
iconUpdates.check(0, 1);
}
}
@Test
public void test_setMaskEnabled() {
if (withMask.isYes()) {
assertThat(layer.hasMask()).isTrue();
assertThat(layer.isMaskEnabled()).isTrue();
LayerMaskActions.EnableDisableMaskAction enableAction = new LayerMaskActions.EnableDisableMaskAction(layer);
assertThat(enableAction.getName()).isEqualTo("Disable");
layer.setMaskEnabled(false, true);
assertThat(layer.isMaskEnabled()).isFalse();
assertThat(enableAction.getName()).isEqualTo("Enable");
History.assertNumEditsIs(1);
History.assertLastEditNameIs("Disable Layer Mask");
iconUpdates.check(0, 1);
History.undo();
assertThat(layer.isMaskEnabled()).isTrue();
assertThat(enableAction.getName()).isEqualTo("Disable");
iconUpdates.check(0, 2);
History.redo();
assertThat(layer.isMaskEnabled()).isFalse();
assertThat(enableAction.getName()).isEqualTo("Enable");
iconUpdates.check(0, 3);
}
}
@Test
public void testMaskLinking() {
if (withMask.isYes()) {
assertThat(layer.hasMask()).isTrue();
LayerMask mask = layer.getMask();
assertThat(mask.isLinked()).isTrue();
LayerMaskActions.LinkUnlinkMaskAction linkAction = new LayerMaskActions.LinkUnlinkMaskAction(layer);
assertThat(linkAction.getName()).isEqualTo("Unlink");
mask.setLinked(false, true);
assertThat(mask.isLinked()).isFalse();
assertThat(linkAction.getName()).isEqualTo("Link");
History.assertNumEditsIs(1);
History.assertLastEditNameIs("Unlink Layer Mask");
History.undo();
assertThat(mask.isLinked()).isTrue();
assertThat(linkAction.getName()).isEqualTo("Unlink");
History.redo();
assertThat(mask.isLinked()).isFalse();
assertThat(linkAction.getName()).isEqualTo("Link");
iconUpdates.check(0, 0);
}
}
}