Ticket #21931: 21931.2.patch

File 21931.2.patch, 13.5 KB (added by taylor.smock, 3 years ago)

Basic tests (to use with attachment:21931.patch)

  • new file test/unit/org/openstreetmap/josm/io/importexport/FileExporterTest.java

    Subject: [PATCH] #21931: Add some basic tests
    ---
    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/io/importexport/FileExporterTest.java b/test/unit/org/openstreetmap/josm/io/importexport/FileExporterTest.java
    new file mode 100644
    - +  
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.io.importexport;
     3
     4import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
     5import static org.junit.jupiter.api.Assertions.assertEquals;
     6import static org.junit.jupiter.api.Assertions.assertFalse;
     7import static org.junit.jupiter.api.Assertions.assertTrue;
     8
     9import java.io.File;
     10import java.io.IOException;
     11import java.nio.file.Path;
     12import java.util.ArrayList;
     13import java.util.Collections;
     14import java.util.List;
     15import java.util.stream.Collectors;
     16
     17import org.junit.jupiter.api.Test;
     18import org.junit.jupiter.api.io.TempDir;
     19import org.openstreetmap.josm.gui.MainApplication;
     20import org.openstreetmap.josm.gui.io.importexport.FileExporter;
     21import org.openstreetmap.josm.gui.io.importexport.FileImporter;
     22import org.openstreetmap.josm.gui.layer.Layer;
     23import org.openstreetmap.josm.gui.layer.LayerManager;
     24import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
     25import org.openstreetmap.josm.gui.util.GuiHelper;
     26import org.openstreetmap.josm.io.IllegalDataException;
     27import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
     28
     29/**
     30 * A test class for file exporters
     31 * @param <E> The file exporter class
     32 * @param <I> The <i>original</i> importer class
     33 * @param <J> The importer to class to use <i>after</i> we have exported the original data
     34 */
     35@BasicPreferences
     36public interface FileExporterTest<E extends FileExporter, I extends FileImporter, J extends FileImporter> {
     37    /**
     38     * Get the exporter instance for tests
     39     * @return The exporter to test
     40     */
     41    E getExporter();
     42
     43    /**
     44     * Get a file extension for the exporter
     45     * @return The expected file extension
     46     */
     47    String getExtension();
     48
     49    /**
     50     * Get the original importer instance for tests
     51     * @return The importer to use
     52     */
     53    I getOriginalImporter();
     54
     55    /**
     56     * Get the importer instance for verifying that the data was written correctly
     57     */
     58    J getSavedDataImporter();
     59
     60    /**
     61     * Verify that the importers have generated the same data
     62     */
     63    default void verifyData(File original, File saved) throws IOException, IllegalDataException {
     64        assertTrue(MainApplication.getLayerManager().getLayers().isEmpty());
     65        final LayerManager layerManager = MainApplication.getLayerManager();
     66        I originalImporter = getOriginalImporter();
     67        assertTrue(originalImporter.acceptFile(original));
     68        if (originalImporter.isBatchImporter()) {
     69            originalImporter.importData(Collections.singletonList(original), NullProgressMonitor.INSTANCE);
     70        } else {
     71            originalImporter.importData(original, NullProgressMonitor.INSTANCE);
     72        }
     73        syncThreads();
     74        final List<Layer> originalLayers = new ArrayList<>(layerManager.getLayers());
     75        originalLayers.forEach(layerManager::removeLayer);
     76        assertFalse(originalLayers.isEmpty());
     77
     78        assertTrue(MainApplication.getLayerManager().getLayers().isEmpty());
     79        J savedImporter = getSavedDataImporter();
     80        assertTrue(savedImporter.acceptFile(saved));
     81        if (savedImporter.isBatchImporter()) {
     82            savedImporter.importData(Collections.singletonList(saved), NullProgressMonitor.INSTANCE);
     83        } else {
     84            savedImporter.importData(saved, NullProgressMonitor.INSTANCE);
     85        }
     86        syncThreads();
     87        final List<Layer> savedLayers = new ArrayList<>(layerManager.getLayers());
     88        savedLayers.forEach(layerManager::removeLayer);
     89        assertFalse(savedLayers.isEmpty());
     90
     91        verifyLayers(originalLayers, savedLayers);
     92    }
     93
     94    /**
     95     * Verify that two layer lists are equal
     96     * @param original The original layers (from the original data)
     97     * @param saved The saved layers (from the exporter)
     98     */
     99    void verifyLayers(List<Layer> original, List<Layer> saved);
     100
     101    /**
     102     * Load data that the exporter can save
     103     * @return The data to save via the exporter
     104     */
     105    File goodData();
     106
     107    /**
     108     * Data that the exporter should not save
     109     * @return The data to try and save via the exporter. Will be loaded via an importer.
     110     */
     111    File badData();
     112
     113    /**
     114     * Check that the exporter enablement methods work properly
     115     */
     116    @Test
     117    default void testEnabled() {
     118        E exporter = getExporter();
     119        assertTrue(exporter.isEnabled(), "Exporters default to enabled");
     120        exporter.setEnabled(false);
     121        assertFalse(exporter.isEnabled(), "Exporters should be able to be enabled/disabled");
     122        exporter.setEnabled(true);
     123        assertTrue(exporter.isEnabled(), "Exporters should be able to be enabled/disabled");
     124    }
     125
     126    /**
     127     * Check that the exporter (at least) sets that it is cancelled
     128     */
     129    @Test
     130    default void testCancelled() {
     131        E exporter = getExporter();
     132        assertFalse(exporter.isCanceled());
     133        exporter.setCanceled(true);
     134        assertTrue(exporter.isCanceled());
     135    }
     136
     137    /**
     138     * Test whether or not a file is accepted
     139     */
     140    @Test
     141    default void testAcceptFileGood() {
     142        assertTrue(getOriginalImporter().acceptFile(goodData()));
     143        assertTrue(getOriginalImporter().acceptFile(badData()));
     144    }
     145
     146    /**
     147     * Test a file that probably shouldn't be exported to
     148     */
     149    @Test
     150    default void testAcceptFileBad() {
     151        E exporter = getExporter();
     152        assertFalse(exporter.acceptFile(new File("foo.bazzzz"), null));
     153    }
     154
     155    /**
     156     * Test quietly exporting data
     157     * @param directory The directory in which we are exporting data
     158     * @throws IOException If we cannot read/write files
     159     * @throws IllegalDataException If the data was not good
     160     */
     161    @Test
     162    default void testExportDataQuiet(@TempDir Path directory) throws IOException, IllegalDataException {
     163        final E exporter = getExporter();
     164        final LayerManager layerManager = MainApplication.getLayerManager();
     165        getOriginalImporter().importData(goodData(), NullProgressMonitor.INSTANCE);
     166        syncThreads();
     167        final File testFile = directory.resolve("exportDataQuiet." + getExtension()).toFile();
     168        List<Layer> exportableLayers = layerManager.getLayers()
     169                .stream().filter(layer -> exporter.acceptFile(testFile, layer)).collect(Collectors.toList());
     170        assertEquals(1, exportableLayers.size());
     171        exporter.exportDataQuiet(testFile, exportableLayers.get(0));
     172        syncThreads();
     173        for (Layer layer : new ArrayList<>(layerManager.getLayers())) {
     174            layerManager.removeLayer(layer);
     175        }
     176        verifyData(goodData(), testFile);
     177    }
     178
     179    /**
     180     * Test overwrite behavior
     181     * @param directory The root directory
     182     */
     183    @Test
     184    void testExportDataOverwrite(@TempDir Path directory);
     185
     186    /**
     187     * Force a thread sync
     188     */
     189    default void syncThreads() {
     190        GuiHelper.runInEDTAndWait(() -> { /* Sync thread */ });
     191        assertDoesNotThrow(() -> MainApplication.worker.submit(() -> { /* Sync thread */ }).get());
     192    }
     193}
  • new file test/unit/org/openstreetmap/josm/io/importexport/GpxExporterTest.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/io/importexport/GpxExporterTest.java b/test/unit/org/openstreetmap/josm/io/importexport/GpxExporterTest.java
    new file mode 100644
    - +  
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.io.importexport;
     3
     4import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
     5import static org.junit.jupiter.api.Assertions.assertEquals;
     6import static org.junit.jupiter.api.Assertions.assertNotEquals;
     7import static org.junit.jupiter.api.Assertions.assertThrows;
     8
     9import java.io.IOException;
     10import java.nio.file.Files;
     11import java.nio.file.Path;
     12import java.util.Collections;
     13import java.util.concurrent.atomic.AtomicInteger;
     14
     15import junit.framework.AssertionFailedError;
     16import org.junit.jupiter.api.Test;
     17import org.junit.jupiter.api.io.TempDir;
     18import org.openstreetmap.josm.TestUtils;
     19import org.openstreetmap.josm.gui.ExtendedDialog;
     20import org.openstreetmap.josm.gui.io.importexport.FileImporter;
     21import org.openstreetmap.josm.gui.io.importexport.GpxExporter;
     22import org.openstreetmap.josm.gui.io.importexport.GpxImporter;
     23import org.openstreetmap.josm.testutils.mockers.ExtendedDialogMocker;
     24
     25/**
     26 * An interface for various import -&gt; export -&gt; import tests
     27 */
     28public interface GpxExporterTest<I extends FileImporter> extends FileExporterTest<GpxExporter, I, GpxImporter> {
     29    @Override
     30    default GpxExporter getExporter() {
     31        return new GpxExporter();
     32    }
     33
     34    @Override
     35    default GpxImporter getSavedDataImporter() {
     36        return new GpxImporter();
     37    }
     38
     39    @Override
     40    default String getExtension() {
     41        return "gpx";
     42    }
     43
     44    @Test
     45    @Override
     46    default void testExportDataOverwrite(@TempDir Path directory) {
     47        TestUtils.assumeWorkingJMockit();
     48        // For reference, save == 1, save_as == 2, and cancel == 3
     49        final AtomicInteger returnValue = new AtomicInteger(1); // Save
     50        new ExtendedDialogMocker() {
     51            @Override
     52            protected int getMockResult(ExtendedDialog instance) {
     53                return returnValue.get();
     54            }
     55        };
     56        final Path path = directory.resolve("exportDataQuiet.gpx");
     57        assertDoesNotThrow(() -> Files.write(path, Collections.singletonList("Test file")));
     58        assertDoesNotThrow(() -> testExportDataQuiet(directory));
     59        assertNotEquals("Test file", assertDoesNotThrow(() -> Files.readAllLines(path)).get(0));
     60
     61        assertDoesNotThrow(() -> Files.write(path, Collections.singletonList("Test file")));
     62        returnValue.set(3); // Cancel
     63        // We expect it to fail during re-read
     64        assertThrows(IOException.class, () -> testExportDataQuiet(directory));
     65        assertEquals("Test file", assertDoesNotThrow(() -> Files.readAllLines(path)).get(0));
     66    }
     67}
  • new file test/unit/org/openstreetmap/josm/io/importexport/NmeaToGpxExporterTest.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/io/importexport/NmeaToGpxExporterTest.java b/test/unit/org/openstreetmap/josm/io/importexport/NmeaToGpxExporterTest.java
    new file mode 100644
    - +  
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.io.importexport;
     3
     4import static org.junit.jupiter.api.Assertions.assertAll;
     5import static org.junit.jupiter.api.Assertions.assertEquals;
     6import static org.junit.jupiter.api.Assertions.assertTrue;
     7
     8import java.io.File;
     9import java.nio.file.Paths;
     10import java.util.List;
     11
     12import org.openstreetmap.josm.TestUtils;
     13import org.openstreetmap.josm.data.gpx.GpxData;
     14import org.openstreetmap.josm.gui.io.importexport.NMEAImporter;
     15import org.openstreetmap.josm.gui.layer.GpxLayer;
     16import org.openstreetmap.josm.gui.layer.Layer;
     17
     18/**
     19 * A class that tests importing NMEA data and exporting it to GPX
     20 */
     21class NmeaToGpxExporterTest implements GpxExporterTest<NMEAImporter> {
     22    @Override
     23    public NMEAImporter getOriginalImporter() {
     24        return new NMEAImporter();
     25    }
     26
     27    @Override
     28    public void verifyLayers(List<Layer> original, List<Layer> saved) {
     29        assertAll(() -> assertEquals(1, original.size()),
     30                () -> assertEquals(1, saved.size()),
     31                () -> assertTrue(original.get(0) instanceof GpxLayer),
     32                () -> assertTrue(saved.get(0) instanceof GpxLayer));
     33        final GpxData originalData = ((GpxLayer) original.get(0)).getGpxData();
     34        final GpxData savedData = ((GpxLayer) saved.get(0)).getGpxData();
     35        assertAll(() -> assertEquals(originalData.getTrackCount(), savedData.getTrackCount()),
     36                () -> assertEquals(originalData.getTrackSegsCount(), savedData.getTrackSegsCount()),
     37                () -> assertEquals(originalData.getRoutes().size(), savedData.getRoutes().size()),
     38                () -> assertEquals(originalData.getWaypoints().size(), savedData.getWaypoints().size()),
     39                () -> assertEquals(originalData.getTrackPoints().count(), savedData.getTrackPoints().count()));
     40    }
     41
     42    @Override
     43    public File goodData() {
     44        return Paths.get(TestUtils.getTestDataRoot(), "sessions", "data.nmea").toFile();
     45    }
     46
     47    @Override
     48    public File badData() {
     49        return new File(TestUtils.getRegressionDataFile(14924, "input.nmea"));
     50    }
     51}