Changeset 18842 in josm for trunk/test/unit/org


Ignore:
Timestamp:
2023-09-25T17:34:00+02:00 (14 months ago)
Author:
taylor.smock
Message:

Fix #23191: NPE in AddTagsDialog

This is caused when a new layer is added via Remote Control while the add tag
dialog is open.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/test/unit/org/openstreetmap/josm/gui/dialogs/properties/TagEditHelperTest.java

    r18799 r18842  
    22package org.openstreetmap.josm.gui.dialogs.properties;
    33
     4import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
    45import static org.junit.jupiter.api.Assertions.assertEquals;
    56import static org.junit.jupiter.api.Assertions.assertFalse;
    67import static org.junit.jupiter.api.Assertions.assertNotNull;
     8import static org.junit.jupiter.api.Assertions.assertTrue;
    79
    810import java.awt.GraphicsEnvironment;
     
    1517import java.util.List;
    1618import java.util.Map;
     19import java.util.concurrent.Future;
     20import java.util.concurrent.atomic.AtomicBoolean;
    1721import java.util.function.Function;
    1822import java.util.stream.Collectors;
    1923
     24import javax.swing.JOptionPane;
    2025import javax.swing.JTable;
    2126import javax.swing.table.DefaultTableModel;
    2227
     28import org.awaitility.Awaitility;
     29import org.awaitility.Durations;
    2330import org.junit.jupiter.api.Test;
    2431import org.openstreetmap.josm.TestUtils;
     
    3037import org.openstreetmap.josm.data.osm.Way;
    3138import org.openstreetmap.josm.data.tagging.ac.AutoCompletionItem;
     39import org.openstreetmap.josm.gui.ExtendedDialog;
    3240import org.openstreetmap.josm.gui.MainApplication;
    3341import org.openstreetmap.josm.gui.dialogs.properties.TagEditHelper.AddTagsDialog;
     
    3543import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
    3644import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource;
     45import org.openstreetmap.josm.spi.preferences.Config;
    3746import org.openstreetmap.josm.testutils.annotations.Projection;
    3847import org.openstreetmap.josm.testutils.annotations.Territories;
    3948import org.openstreetmap.josm.testutils.mockers.WindowMocker;
     49import org.openstreetmap.josm.tools.JosmRuntimeException;
     50
     51import mockit.Mock;
     52import mockit.MockUp;
    4053
    4154/**
     
    104117            return node;
    105118        }, "junction", "roundabout");
     119    }
     120
     121    /**
     122     * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/23191>#23191</a>
     123     */
     124    @Test
     125    void testTicket23191() {
     126        TestUtils.assumeWorkingJMockit();
     127        final TagEditHelper tagEditHelper = newTagEditHelper();
     128        final DataSet original = new DataSet();
     129        MainApplication.getLayerManager().addLayer(new OsmDataLayer(original, "TagEditHelperTest.testTicket23191_1", null));
     130        final Node toSelect = TestUtils.newNode("");
     131        original.addPrimitive(toSelect);
     132        original.setSelected(toSelect);
     133        assertEquals(1, OsmDataManager.getInstance().getInProgressISelection().size());
     134        assertTrue(OsmDataManager.getInstance().getInProgressISelection().contains(toSelect));
     135
     136        final AtomicBoolean canContinue = new AtomicBoolean();
     137        final AtomicBoolean showingDialog = new AtomicBoolean();
     138
     139        // Instantiate the AddTagsDialog where we don't have to worry about race conditions
     140        tagEditHelper.sel = OsmDataManager.getInstance().getInProgressSelection();
     141        final AddTagsDialog addTagsDialog = tagEditHelper.getAddTagsDialog();
     142        tagEditHelper.resetSelection();
     143        new MockUp<TagEditHelper>() {
     144            @Mock
     145            public AddTagsDialog getAddTagsDialog() {
     146                return addTagsDialog;
     147            }
     148        };
     149
     150        new MockUp<AddTagsDialog>() {
     151            @Mock
     152            public ExtendedDialog showDialog() {
     153                showingDialog.set(true);
     154                while (!canContinue.get()) {
     155                    synchronized (canContinue) {
     156                        try {
     157                            canContinue.wait();
     158                        } catch (InterruptedException e) {
     159                            throw new JosmRuntimeException(e);
     160                        }
     161                    }
     162                }
     163                return null;
     164            }
     165
     166            @Mock
     167            public int getValue() {
     168                return 1;
     169            }
     170        };
     171
     172        // Avoid showing the JOption pane
     173        Config.getPref().putBoolean("message.properties.selection-changed", false);
     174        Config.getPref().putInt("message.properties.selection-changed.value", JOptionPane.YES_OPTION);
     175
     176        // "Open" the tag edit dialog -- this should technically be in the EDT, but we are mocking the UI parts out,
     177        // since the EDT does allow new EDT runnables when showing the add tag dialog
     178        Future<?> tagFuture = MainApplication.worker.submit(tagEditHelper::addTag);
     179
     180        Awaitility.await().atMost(Durations.ONE_SECOND).untilTrue(showingDialog);
     181        // This is what remote control will effectively do
     182        MainApplication.getLayerManager().addLayer(new OsmDataLayer(new DataSet(), "TagEditHelperTest.testTicket23191_2", null));
     183        tagEditHelper.resetSelection();
     184
     185        // Enter key=value
     186        addTagsDialog.keys.setText("building");
     187        addTagsDialog.values.setText("yes");
     188
     189        // Close the tag edit dialog
     190        synchronized (canContinue) {
     191            canContinue.set(true);
     192            canContinue.notifyAll();
     193        }
     194
     195        assertDoesNotThrow(() -> tagFuture.get());
    106196    }
    107197
Note: See TracChangeset for help on using the changeset viewer.