|
|
@@ -0,0 +1,162 @@
|
|
|
+package org.leumasjaffe.recipe.view;
|
|
|
+
|
|
|
+import static org.hamcrest.MatcherAssert.assertThat;
|
|
|
+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 javax.swing.JTextField;
|
|
|
+import javax.swing.event.DocumentListener;
|
|
|
+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.BetterAutoGrowPanel.ChildComponent;
|
|
|
+import org.mockito.Mock;
|
|
|
+import org.mockito.Spy;
|
|
|
+import org.mockito.junit.jupiter.MockitoExtension;
|
|
|
+
|
|
|
+@ExtendWith(MockitoExtension.class)
|
|
|
+@RunWith(JUnitPlatform.class)
|
|
|
+class BetterAutoGrowPanelTest extends SwingTestCase {
|
|
|
+ @SuppressWarnings("serial")
|
|
|
+ private static class MockComponent extends JTextField implements ChildComponent {
|
|
|
+ public MockComponent() {
|
|
|
+ }
|
|
|
+
|
|
|
+ public MockComponent(String s) {
|
|
|
+ super(s);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void addGrowShrinkListener(DocumentListener dl) {
|
|
|
+ super.getDocument().addDocumentListener(dl);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void removeGrowShrinkListener(DocumentListener dl) {
|
|
|
+ super.getDocument().removeDocumentListener(dl);
|
|
|
+ }
|
|
|
+
|
|
|
+ public String toString() {
|
|
|
+ return this.getClass().getSimpleName() + "@" + this.hashCode();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Mock Consumer<Boolean> callback;
|
|
|
+ List<MockComponent> internal = new ArrayList<>();
|
|
|
+ @Spy List<MockComponent> shared = new ArrayList<>();
|
|
|
+
|
|
|
+ private MockComponent mocked() {
|
|
|
+ final MockComponent mock = spy(new MockComponent());
|
|
|
+ internal.add(mock);
|
|
|
+ return mock;
|
|
|
+ }
|
|
|
+
|
|
|
+ private BetterAutoGrowPanel<MockComponent, MockComponent> create(MockComponent... mocks) {
|
|
|
+ shared.addAll(Arrays.asList(mocks));
|
|
|
+ final BetterAutoGrowPanel<MockComponent, MockComponent> rval =
|
|
|
+ new BetterAutoGrowPanel<>(this::mocked, m -> m);
|
|
|
+
|
|
|
+ rval.setModel(shared);
|
|
|
+
|
|
|
+ return rval;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testAlwaysHasAtLeastOneComponent() {
|
|
|
+ BetterAutoGrowPanel<MockComponent, MockComponent> panel = create();
|
|
|
+
|
|
|
+ assertThat(panel.getComponents(), arrayWithSize(1));
|
|
|
+ verify(shared, never()).add(any());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testCreatesGivenNumberOfChildrenPlusOne() {
|
|
|
+ BetterAutoGrowPanel<MockComponent, MockComponent> panel = create(mocked(), mocked());
|
|
|
+
|
|
|
+ assertThat(panel.getComponents(), arrayWithSize(3));
|
|
|
+ verify(shared, never()).add(any());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testEnteringContentTriggersNewRow() {
|
|
|
+ BetterAutoGrowPanel<MockComponent, MockComponent> panel = create();
|
|
|
+ getTestFrame().add(panel);
|
|
|
+
|
|
|
+ internal.get(0).setText("A");
|
|
|
+ assertThat(panel.getComponents(), arrayWithSize(2));
|
|
|
+
|
|
|
+ internal.get(1).setText("B");
|
|
|
+ assertThat(panel.getComponents(), arrayWithSize(3));
|
|
|
+ verify(shared, times(2)).add(any());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testEnteringEmptyContentDoesNotTrigger() {
|
|
|
+ BetterAutoGrowPanel<MockComponent, MockComponent> panel = create();
|
|
|
+ getTestFrame().add(panel);
|
|
|
+ internal.get(0).setText("");
|
|
|
+
|
|
|
+ assertThat(panel.getComponents(), arrayWithSize(1));
|
|
|
+ verify(shared, never()).add(any());
|
|
|
+ verify(shared, never()).remove(anyInt());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testEmptyingContentClearsPanel() {
|
|
|
+ final MockComponent mock = spy(new MockComponent("A"));
|
|
|
+
|
|
|
+ BetterAutoGrowPanel<MockComponent, MockComponent> panel = create(mock);
|
|
|
+ getTestFrame().add(panel);
|
|
|
+ mock.setText("");
|
|
|
+
|
|
|
+ assertThat(panel.getComponents(), arrayWithSize(1));
|
|
|
+ verify(shared, times(1)).remove(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testRemovingSomeContentDoesntClear() throws BadLocationException {
|
|
|
+ final MockComponent mock = spy(new MockComponent("AB"));
|
|
|
+
|
|
|
+ BetterAutoGrowPanel<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"));
|
|
|
+
|
|
|
+ BetterAutoGrowPanel<MockComponent, MockComponent> panel = create(mock);
|
|
|
+ getTestFrame().add(panel);
|
|
|
+ mock.getDocument().insertString(0, "B", null);
|
|
|
+
|
|
|
+ assertThat(panel.getComponents(), arrayWithSize(2));
|
|
|
+ verify(shared, never()).remove(anyInt());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void testCanInstallNotificationCallbackForAddsAndDeletes() {
|
|
|
+ BetterAutoGrowPanel<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);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|