--- /dev/null
+package jalview.gui;
+
+import static org.testng.Assert.assertNotNull;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
+import jalview.gui.QuitHandler.QResponse;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
+import jalview.io.FileLoader;
+import jalview.project.Jalview2XML;
+
+@Test(singleThreaded = true)
+public class QuitHandlerTest
+{
+ private static String saveProjectFile = "test-output/tempSaveFile.jvp";
+
+ private static String saveFastaFile = "test-output/tempSaveFile.fa";
+
+ @BeforeClass(alwaysRun = true)
+ public void setUpJvOptionPane()
+ {
+ JvOptionPane.setInteractiveMode(false);
+ JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+ Jalview2XML.setDebugDelaySave(3);
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @BeforeClass(alwaysRun = true)
+ public static void setUpBeforeClass() throws Exception
+ {
+ Cache.loadProperties("test/jalview/gui/quitProps.jvprops");
+
+ /*
+ * set news feed last read to a future time to ensure no
+ * 'unread' news item is displayed
+ */
+ Date oneHourFromNow = new Date(
+ System.currentTimeMillis() + 3600 * 1000);
+ Cache.setDateProperty("JALVIEW_NEWS_RSS_LASTMODIFIED", oneHourFromNow);
+
+ Jalview.main(
+ new String[]
+ { "-nowebservicediscovery", "-nosplash", "-nonews" });
+ }
+
+ @AfterClass(alwaysRun = true)
+ public static void resetProps()
+ {
+ // reset quit response
+ QuitHandler.setResponse(QResponse.NULL);
+ // reset mock response
+ JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+ // close desktop windows/frames
+ jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
+ // reset debug delay
+ Jalview2XML.setDebugDelaySave(20);
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ public static void tearDownAfterClass() throws Exception
+ {
+ // reset quit response
+ QuitHandler.setResponse(QResponse.NULL);
+ // reset mock response
+ JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+ // close desktop windows/frames
+ jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
+ // reset debug delay
+ Cache.setProperty("DEBUG_DELAY_SAVE", "false");
+ Jalview2XML.setDebugDelaySave(3);
+ }
+
+ @AfterMethod(alwaysRun = true)
+ public static void cleanup()
+ {
+ // delete save files
+ List<String> files = new ArrayList<>();
+ files.add(saveProjectFile);
+ files.add(saveFastaFile);
+ for (String filename : files)
+ {
+ File file = new File(filename);
+ if (file.exists())
+ {
+ file.delete();
+ }
+ }
+ }
+
+ @Test(groups = { "Functional" }, singleThreaded = true, priority = 1)
+ public void testInstantQuit() throws Exception
+ {
+ String inFile = "examples/uniref50.fa";
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
+ DataSourceType.FILE);
+ assertNotNull(af, "Didn't read input file " + inFile);
+
+ long start = System.currentTimeMillis();
+
+ // if a save is attempted it will delay 3s
+ Cache.setProperty("DEBUG_DELAY_SAVE", "true");
+
+ // loaded file but haven't done anything, should just quit
+ QResponse response = QuitHandler.getQuitResponse(true);
+ long end = System.currentTimeMillis();
+
+ Assert.assertEquals(response, QResponse.QUIT);
+ Assert.assertTrue(end - start < 1000,
+ "Quit-with-no-save-needed took too long (" + (end - start)
+ + "ms)");
+ Desktop.instance.closeAll_actionPerformed(null);
+ }
+
+ @Test(groups = { "Functional" }, singleThreaded = true, priority = 10)
+ public void testWaitForSaveQuit() throws Exception
+ {
+ String inFile = "examples/uniref50.fa";
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
+ DataSourceType.FILE);
+ assertNotNull(af, "Didn't read input file " + inFile);
+
+ long start = System.currentTimeMillis();
+
+ // start a long save (3s)
+ Cache.setProperty("DEBUG_DELAY_SAVE", "true");
+ af.saveAlignment(saveProjectFile, FileFormat.Jalview);
+
+ QResponse response = QuitHandler.getQuitResponse(true,
+ QuitHandler.defaultOkQuit, () -> {
+ // set FORCE_QUIT without the force quit
+ QuitHandler.setResponse(QResponse.FORCE_QUIT);
+ return null;
+ }, QuitHandler.defaultCancelQuit);
+ long end = System.currentTimeMillis();
+
+ Assert.assertEquals(response, QResponse.QUIT);
+ Assert.assertTrue(end - start > 2900,
+ "Quit-whilst-saving was too short (" + (end - start) + "ms)");
+
+ Desktop.instance.closeAll_actionPerformed(null);
+ }
+
+ @Test(groups = { "Functional" }, singleThreaded = true, priority = 9)
+ public void testSavedProjectChanges() throws Exception
+ {
+ String inFile = "examples/uniref50.fa";
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
+ DataSourceType.FILE);
+ assertNotNull(af, "Didn't read input file " + inFile);
+ AlignViewport viewport = af.getViewport();
+ // pretend something has happened
+ viewport.setSavedUpToDate(false);
+ Jalview2XML.setStateSavedUpToDate(false);
+
+ // no hanging around needed here
+ Cache.setProperty("DEBUG_DELAY_SAVE", "false");
+ af.saveAlignment(saveProjectFile, FileFormat.Jalview);
+
+ // this is only a two button dialog [Quit] [Cancel] so use NO_OPTION
+ JvOptionPane.setMockResponse(JvOptionPane.NO_OPTION);
+ QResponse response = QuitHandler.getQuitResponse(true,
+ QuitHandler.defaultOkQuit, () -> {
+ // set FORCE_QUIT without the force quit
+ QuitHandler.setResponse(QResponse.FORCE_QUIT);
+ return null;
+ }, QuitHandler.defaultCancelQuit);
+
+ // if not saved this would be CANCEL_QUIT
+ Assert.assertEquals(response, QResponse.QUIT);
+ Desktop.instance.closeAll_actionPerformed(null);
+ }
+
+ @Test(groups = { "Functional" }, singleThreaded = true, priority = 9)
+ public void testSavedAlignmentChanges() throws Exception
+ {
+ String inFile = "examples/uniref50.fa";
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
+ DataSourceType.FILE);
+ assertNotNull(af, "Didn't read input file " + inFile);
+ AlignViewport viewport = af.getViewport();
+ // pretend something has happened
+ viewport.setSavedUpToDate(false);
+ Jalview2XML.setStateSavedUpToDate(false);
+
+ // no hanging around needed here
+ Cache.setProperty("DEBUG_DELAY_SAVE", "false");
+ af.saveAlignment(saveFastaFile, FileFormat.Fasta);
+
+ // this is only a two button dialog [Quit] [Cancel] so use NO_OPTION
+ JvOptionPane.setMockResponse(JvOptionPane.NO_OPTION);
+ QResponse response = QuitHandler.getQuitResponse(true,
+ QuitHandler.defaultOkQuit, () -> {
+ // set FORCE_QUIT without the force quit
+ QuitHandler.setResponse(QResponse.FORCE_QUIT);
+ return null;
+ }, QuitHandler.defaultCancelQuit);
+
+ // if not saved this would be CANCEL_QUIT
+ Assert.assertEquals(response, QResponse.QUIT);
+ Desktop.instance.closeAll_actionPerformed(null);
+ }
+
+ @Test(groups = { "Functional" }, singleThreaded = true, priority = 1)
+ public void testUnsavedChanges() throws Exception
+ {
+ String inFile = "examples/uniref50.fa";
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
+ DataSourceType.FILE);
+ assertNotNull(af, "Didn't read input file " + inFile);
+ AlignViewport viewport = af.getViewport();
+ // pretend something has happened
+ viewport.setSavedUpToDate(false);
+ Jalview2XML.setStateSavedUpToDate(false);
+
+ // this is only a two button dialog [Quit] [Cancel] so use NO_OPTION
+ JvOptionPane.setMockResponse(JvOptionPane.NO_OPTION);
+ QResponse response = QuitHandler.getQuitResponse(true,
+ QuitHandler.defaultOkQuit, () -> {
+ // set FORCE_QUIT without the force quit
+ QuitHandler.setResponse(QResponse.FORCE_QUIT);
+ return null;
+ }, QuitHandler.defaultCancelQuit);
+
+ Assert.assertEquals(response, QResponse.CANCEL_QUIT);
+ Desktop.instance.closeAll_actionPerformed(null);
+ }
+
+ @Test(groups = { "Functional" }, singleThreaded = true, priority = 1)
+ public void testNoGUIUnsavedChanges() throws Exception
+ {
+ String inFile = "examples/uniref50.fa";
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
+ DataSourceType.FILE);
+ assertNotNull(af, "Didn't read input file " + inFile);
+ AlignViewport viewport = af.getViewport();
+ // pretend something has happened
+ viewport.setSavedUpToDate(false);
+ Jalview2XML.setStateSavedUpToDate(false);
+
+ // this is only a two button dialog [Quit] [Cancel] so use NO_OPTION
+ JvOptionPane.setMockResponse(JvOptionPane.NO_OPTION);
+ QResponse response = QuitHandler.getQuitResponse(false,
+ QuitHandler.defaultOkQuit, () -> {
+ // set FORCE_QUIT without the force quit
+ QuitHandler.setResponse(QResponse.FORCE_QUIT);
+ return null;
+ }, QuitHandler.defaultCancelQuit);
+
+ Assert.assertEquals(response, QResponse.QUIT);
+ Desktop.instance.closeAll_actionPerformed(null);
+ }
+
+}