|
|
@@ -5,9 +5,9 @@ import static org.hamcrest.collection.IsArrayWithSize.arrayWithSize;
|
|
|
import static org.mockito.Mockito.*;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
import java.util.List;
|
|
|
import java.util.function.Consumer;
|
|
|
-import java.util.function.IntConsumer;
|
|
|
|
|
|
import javax.swing.JTextField;
|
|
|
import javax.swing.event.DocumentListener;
|
|
|
@@ -15,17 +15,15 @@ import javax.swing.text.BadLocationException;
|
|
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
import org.junit.jupiter.api.extension.ExtendWith;
|
|
|
-import org.junit.platform.runner.JUnitPlatform;
|
|
|
-import org.junit.runner.RunWith;
|
|
|
-import org.leumasjaffe.recipe.view.AutoGrowPanel.DocumentListenable;
|
|
|
+import org.leumasjaffe.recipe.view.AutoGrowPanel.ChildComponent;
|
|
|
import org.mockito.Mock;
|
|
|
+import org.mockito.Spy;
|
|
|
import org.mockito.junit.jupiter.MockitoExtension;
|
|
|
|
|
|
@ExtendWith(MockitoExtension.class)
|
|
|
-@RunWith(JUnitPlatform.class)
|
|
|
class AutoGrowPanelTest extends SwingTestCase {
|
|
|
@SuppressWarnings("serial")
|
|
|
- private static class MockComponent extends JTextField implements DocumentListenable {
|
|
|
+ private static class MockComponent extends JTextField implements ChildComponent {
|
|
|
public MockComponent() {
|
|
|
}
|
|
|
|
|
|
@@ -34,92 +32,174 @@ class AutoGrowPanelTest extends SwingTestCase {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public void addDocumentListener(DocumentListener dl) {
|
|
|
+ public void addGrowShrinkListener(DocumentListener dl) {
|
|
|
super.getDocument().addDocumentListener(dl);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public void removeDocumentListener(DocumentListener dl) {
|
|
|
+ public void removeGrowShrinkListener(DocumentListener dl) {
|
|
|
super.getDocument().removeDocumentListener(dl);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- @Mock Consumer<MockComponent> add;
|
|
|
- @Mock IntConsumer remove;
|
|
|
- List<MockComponent> components = new ArrayList<>();
|
|
|
+ @Mock Consumer<Boolean> callback;
|
|
|
+ List<MockComponent> internal = new ArrayList<>();
|
|
|
+ @Spy List<MockComponent> shared = new ArrayList<>();
|
|
|
|
|
|
private MockComponent mocked() {
|
|
|
final MockComponent mock = spy(new MockComponent());
|
|
|
- components.add(mock);
|
|
|
+ internal.add(mock);
|
|
|
return mock;
|
|
|
}
|
|
|
|
|
|
- private AutoGrowPanel create(MockComponent... mocks) {
|
|
|
- return new AutoGrowPanel(m -> m, this::mocked, add, remove, mocks);
|
|
|
+ private AutoGrowPanel<MockComponent, MockComponent> create(MockComponent... mocks) {
|
|
|
+ shared.addAll(Arrays.asList(mocks));
|
|
|
+ final AutoGrowPanel<MockComponent, MockComponent> rval =
|
|
|
+ new AutoGrowPanel<>(this::mocked, m -> m);
|
|
|
+
|
|
|
+ rval.setModel(shared);
|
|
|
+
|
|
|
+ return rval;
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
void testAlwaysHasAtLeastOneComponent() {
|
|
|
- AutoGrowPanel panel = create();
|
|
|
+ AutoGrowPanel<MockComponent, MockComponent> panel =
|
|
|
+ new AutoGrowPanel<>(this::mocked, m -> m);
|
|
|
+
|
|
|
+ assertThat(panel.getComponents(), arrayWithSize(1));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testInitialComponentAssignedFirstPosition() {
|
|
|
+ @SuppressWarnings("unused")
|
|
|
+ AutoGrowPanel<MockComponent, MockComponent> panel =
|
|
|
+ new AutoGrowPanel<>(this::mocked, m -> m);
|
|
|
+
|
|
|
+ verify(internal.get(0)).setListPosition(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testSetModelCallsListPositionEvenIfNoChange() {
|
|
|
+ AutoGrowPanel<MockComponent, MockComponent> panel = create();
|
|
|
|
|
|
assertThat(panel.getComponents(), arrayWithSize(1));
|
|
|
- verify(add, never()).accept(any());
|
|
|
+ verify(internal.get(0), times(2)).setListPosition(0);
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
void testCreatesGivenNumberOfChildrenPlusOne() {
|
|
|
- AutoGrowPanel panel = create(mocked(), mocked());
|
|
|
+ AutoGrowPanel<MockComponent, MockComponent> panel = create(mocked(), mocked());
|
|
|
|
|
|
assertThat(panel.getComponents(), arrayWithSize(3));
|
|
|
- verify(add, never()).accept(any());
|
|
|
+ verify(shared, never()).add(any());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testResetsListPositionAfterSettingModel() {
|
|
|
+ @SuppressWarnings("unused")
|
|
|
+ AutoGrowPanel<MockComponent, MockComponent> panel = create(mocked(), mocked());
|
|
|
+
|
|
|
+ // Last element because my helper function pre-installs into the internal list
|
|
|
+ verify(internal.get(2)).setListPosition(0);
|
|
|
+ verify(internal.get(2)).setListPosition(2);
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
void testEnteringContentTriggersNewRow() {
|
|
|
- AutoGrowPanel panel = create();
|
|
|
- getTestFrame().add(panel);
|
|
|
+ AutoGrowPanel<MockComponent, MockComponent> panel = create();
|
|
|
|
|
|
- components.get(0).setText("A");
|
|
|
+ internal.get(0).setText("A");
|
|
|
assertThat(panel.getComponents(), arrayWithSize(2));
|
|
|
|
|
|
- components.get(1).setText("B");
|
|
|
+ internal.get(1).setText("B");
|
|
|
assertThat(panel.getComponents(), arrayWithSize(3));
|
|
|
- verify(add, times(2)).accept(any());
|
|
|
+
|
|
|
+ verify(shared, times(2)).add(any());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testEnteringContentAssignsCorrectListPosition() {
|
|
|
+ @SuppressWarnings("unused")
|
|
|
+ AutoGrowPanel<MockComponent, MockComponent> panel = create();
|
|
|
+
|
|
|
+ internal.get(0).setText("A");
|
|
|
+
|
|
|
+ verify(internal.get(1)).setListPosition(1);
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
void testEnteringEmptyContentDoesNotTrigger() {
|
|
|
- AutoGrowPanel panel = create();
|
|
|
+ AutoGrowPanel<MockComponent, MockComponent> panel = create();
|
|
|
getTestFrame().add(panel);
|
|
|
- components.get(0).setText("");
|
|
|
+ internal.get(0).setText("");
|
|
|
|
|
|
assertThat(panel.getComponents(), arrayWithSize(1));
|
|
|
- verify(add, never()).accept(any());
|
|
|
- verify(remove, never()).accept(anyInt());
|
|
|
+ verify(shared, never()).add(any());
|
|
|
+ verify(shared, never()).remove(anyInt());
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
void testEmptyingContentClearsPanel() {
|
|
|
final MockComponent mock = spy(new MockComponent("A"));
|
|
|
|
|
|
- AutoGrowPanel panel = create(mock);
|
|
|
+ AutoGrowPanel<MockComponent, MockComponent> panel = create(mock);
|
|
|
getTestFrame().add(panel);
|
|
|
mock.setText("");
|
|
|
|
|
|
assertThat(panel.getComponents(), arrayWithSize(1));
|
|
|
- verify(remove, times(1)).accept(0);
|
|
|
+ verify(shared, times(1)).remove(0);
|
|
|
}
|
|
|
|
|
|
|
|
|
+ @Test
|
|
|
+ void testEmptyingContentAdjustsAllPositions() {
|
|
|
+ final MockComponent mock = spy(new MockComponent("A"));
|
|
|
+
|
|
|
+ @SuppressWarnings("unused")
|
|
|
+ AutoGrowPanel<MockComponent, MockComponent> panel = create(mock);
|
|
|
+
|
|
|
+ mock.setText("");
|
|
|
+
|
|
|
+ verify(internal.get(0), times(2)).setListPosition(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testRemovingSomeContentDoesntClear() throws BadLocationException {
|
|
|
+ final MockComponent mock = spy(new MockComponent("AB"));
|
|
|
+
|
|
|
+ AutoGrowPanel<MockComponent, MockComponent> panel = create(mock);
|
|
|
+ getTestFrame().add(panel);
|
|
|
+ mock.getDocument().remove(0, 1);
|
|
|
+
|
|
|
+ assertThat(panel.getComponents(), arrayWithSize(2));
|
|
|
+ verify(shared, never()).remove(anyInt());
|
|
|
+ }
|
|
|
+
|
|
|
@Test
|
|
|
void testChangingTextDoesNotDeleteRow() throws BadLocationException {
|
|
|
final MockComponent mock = spy(new MockComponent("A"));
|
|
|
|
|
|
- AutoGrowPanel panel = create(mock);
|
|
|
+ AutoGrowPanel<MockComponent, MockComponent> panel = create(mock);
|
|
|
getTestFrame().add(panel);
|
|
|
mock.getDocument().insertString(0, "B", null);
|
|
|
|
|
|
assertThat(panel.getComponents(), arrayWithSize(2));
|
|
|
- verify(remove, never()).accept(anyInt());
|
|
|
+ verify(shared, never()).remove(anyInt());
|
|
|
}
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testCanInstallNotificationCallbackForAddsAndDeletes() {
|
|
|
+ AutoGrowPanel<MockComponent, MockComponent> panel = create();
|
|
|
+ panel.setModel(shared, callback);
|
|
|
+ getTestFrame().add(panel);
|
|
|
+ verify(callback, never()).accept(anyBoolean());
|
|
|
+
|
|
|
+ internal.get(0).setText("A");
|
|
|
+ verify(callback).accept(true);
|
|
|
+
|
|
|
+ internal.get(0).setText("");
|
|
|
+ verify(callback).accept(false);
|
|
|
+ }
|
|
|
+
|
|
|
}
|