diff --git a/gclc-swt/pom.xml b/gclc-swt/pom.xml index c8365a5..1ee5ae8 100644 --- a/gclc-swt/pom.xml +++ b/gclc-swt/pom.xml @@ -7,7 +7,7 @@ net.bigeon.gclc swt - 1.1.7-SNAPSHOT + 1.2.0-SNAPSHOT jar GCLC swt A swt window for console applications @@ -55,6 +55,12 @@ collections 1.1.6 + + org.mockito + mockito-core + 2.23.0 + test + diff --git a/gclc-swt/src/main/java/net/bigeon/gclc/swt/ConsoleDelayIO.java b/gclc-swt/src/main/java/net/bigeon/gclc/swt/ConsoleDelayIO.java index cc5eb04..f274eb2 100644 --- a/gclc-swt/src/main/java/net/bigeon/gclc/swt/ConsoleDelayIO.java +++ b/gclc-swt/src/main/java/net/bigeon/gclc/swt/ConsoleDelayIO.java @@ -35,6 +35,8 @@ */ package net.bigeon.gclc.swt; +import java.io.IOException; + /*- * #%L * GCLC swt @@ -86,6 +88,8 @@ public interface ConsoleDelayIO { * @param input the input to set */ void setInput(String input); - /** Actually send the input as the prompt next input. */ - void validateInput(); + /** Actually send the input as the prompt next input. + * + * @throws IOException if an error occurred */ + void validateInput() throws IOException; } diff --git a/gclc-swt/src/main/java/net/bigeon/gclc/swt/ConsoleInputManager.java b/gclc-swt/src/main/java/net/bigeon/gclc/swt/ConsoleInputManager.java new file mode 100644 index 0000000..3c83881 --- /dev/null +++ b/gclc-swt/src/main/java/net/bigeon/gclc/swt/ConsoleInputManager.java @@ -0,0 +1,54 @@ +/** + * + */ +package net.bigeon.gclc.swt; + +import java.io.IOException; + +import org.eclipse.swt.widgets.Text; + +import net.bigeon.gclc.utils.PipedConsoleInput; + +/** @author Emmanuel Bigeon */ +public final class ConsoleInputManager implements ConsoleDelayIO { + + private final Text text; + private PipedConsoleInput input; + + /** @param text the text */ + public ConsoleInputManager(final Text text) { + super(); + this.text = text; + } + + /** @param string the text */ + @Override + public void setInput(final String string) { + text.setText(string); + text.setSelection(string.length()); + } + + /* (non-Javadoc) + * @see net.bigeon.gclc.swt.ConsoleDelayIO#getInput() */ + @Override + public String getInput() { + return text.getText(); + } + + @Override + public void validateInput() throws IOException { + input.type(text.getText()); + } + + /** Set the input to control + * + * @param input the input */ + public void setManager(final PipedConsoleInput input) { + this.input = input; + } + + /** @return the text */ + public Text getText() { + return text; + } +} diff --git a/gclc-swt/src/main/java/net/bigeon/gclc/swt/ConsoleOutputManager.java b/gclc-swt/src/main/java/net/bigeon/gclc/swt/ConsoleOutputManager.java new file mode 100644 index 0000000..0097f3e --- /dev/null +++ b/gclc-swt/src/main/java/net/bigeon/gclc/swt/ConsoleOutputManager.java @@ -0,0 +1,96 @@ +/** + * + */ +package net.bigeon.gclc.swt; + +import org.eclipse.swt.widgets.Text; + +import net.bigeon.gclc.manager.ConsoleOutput; +import net.bigeon.gclc.utils.AOutputForwardRunnable; +import net.bigeon.gclc.utils.PipedConsoleOutput; + +/** @author Emmanuel Bigeon */ +public final class ConsoleOutputManager { + /** The local implementation of the forwarding runnable + * + * @author Emmanuel Bigeon */ + private final class ToSWTConsoleForwardRunnable extends AOutputForwardRunnable { + /** The running status */ + private boolean running = true; + private final PipedConsoleOutput out; + + /** @param manager the manager */ + public ToSWTConsoleForwardRunnable(final PipedConsoleOutput manager) { + super(manager); + out = manager; + } + + @Override + protected void forwardLine(final String m) { + appendConsoleOutput(System.lineSeparator() + m); + } + + @Override + protected boolean isRunning() { + return running && !text.isDisposed(); + } + + /** @param running the running to set */ + public void setRunning(final boolean running) { + this.running = running; + } + + /** @return the currently forwarded output */ + public PipedConsoleOutput getOuput() { + return out; + } + } + + private final Text text; + private ConsoleOutput output; + /** The forwarding runnable */ + private ToSWTConsoleForwardRunnable forward; + private Thread forwardThread; + + /** @param text the text to display the output in. */ + public ConsoleOutputManager(final Text text) { + super(); + this.text = text; + } + + /** @param next the next message */ + public void appendConsoleOutput(final String next) { + text.getDisplay().syncExec(new Runnable() { + @SuppressWarnings("synthetic-access") + @Override + public void run() { + text.append(next); + } + }); + } + + /** Set the output. + * + * @param output the output to set */ + public void setManager(final PipedConsoleOutput output) { + if (forward != null) { + if (forward.getOuput() == output) { + return; + } + forward.setRunning(false); + } + if (output == null) { + forward = null; + forwardThread = null; + return; + } + forward = new ToSWTConsoleForwardRunnable(output); + forwardThread = new Thread(forward, "gclcToSWT"); //$NON-NLS-1$ + forwardThread.start(); + } + + /** @return the forwardThread */ + public Thread getForwardThread() { + return forwardThread; + } +} diff --git a/gclc-swt/src/main/java/net/bigeon/gclc/swt/ConsolePromptManager.java b/gclc-swt/src/main/java/net/bigeon/gclc/swt/ConsolePromptManager.java new file mode 100644 index 0000000..814dd75 --- /dev/null +++ b/gclc-swt/src/main/java/net/bigeon/gclc/swt/ConsolePromptManager.java @@ -0,0 +1,47 @@ +/** + * + */ +package net.bigeon.gclc.swt; + +import java.io.BufferedReader; + +import org.eclipse.swt.widgets.Label; + +/** @author Emmanuel Bigeon */ +public final class ConsolePromptManager { + + private final Label label; + + private PromptReadingRunnable promptRead; + + /** @param label the label to update */ + public ConsolePromptManager(final Label label) { + super(); + this.label = label; + } + + /** @param string the text */ + public void setPrompt(final String string) { + label.setText(string); + } + + /** Set the input to control + * + * @param promptStream the input */ + public void setStream(final BufferedReader promptStream) { + if (promptRead != null) { + if (promptRead.getReader() == promptStream) { + return; + } + promptRead.setRunning(false); + } + if (promptStream == null) { + promptRead = null; + return; + } + promptRead = new PromptReadingRunnable(promptStream, + label); + final Thread th = new Thread(promptRead, "Prompt To Label"); + th.start(); + } +} diff --git a/gclc-swt/src/main/java/net/bigeon/gclc/swt/HistoryTextKeyListener.java b/gclc-swt/src/main/java/net/bigeon/gclc/swt/HistoryTextKeyListener.java index 089037d..1710301 100644 --- a/gclc-swt/src/main/java/net/bigeon/gclc/swt/HistoryTextKeyListener.java +++ b/gclc-swt/src/main/java/net/bigeon/gclc/swt/HistoryTextKeyListener.java @@ -35,6 +35,10 @@ */ package net.bigeon.gclc.swt; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + /*- * #%L * GCLC swt @@ -83,7 +87,9 @@ public final class HistoryTextKeyListener extends KeyAdapter { /** The size of commands history. */ private static final int DEFAULT_HISTORY_SIZE = 10; /** The empty string constant. */ - private static final String EMPTY = ""; //$NON-NLS-1$ + private static final String EMPTY = ""; //$NON-NLS-1$ + private static final Logger LOGGER = Logger + .getLogger(HistoryTextKeyListener.class.getName()); /** The history ribbon. */ private final Ribbon commands; /** The current index in history search. */ @@ -118,7 +124,11 @@ public final class HistoryTextKeyListener extends KeyAdapter { if (!input.isEmpty()) { commands.add(input); } - console.validateInput(); + try { + console.validateInput(); + } catch (final IOException e) { + LOGGER.log(Level.SEVERE, "Unable to write to console", e); + } currentIndex = -1; } diff --git a/gclc-swt/src/main/java/net/bigeon/gclc/swt/PromptReadingRunnable.java b/gclc-swt/src/main/java/net/bigeon/gclc/swt/PromptReadingRunnable.java new file mode 100644 index 0000000..d50d6cb --- /dev/null +++ b/gclc-swt/src/main/java/net/bigeon/gclc/swt/PromptReadingRunnable.java @@ -0,0 +1,65 @@ +/** + * + */ +package net.bigeon.gclc.swt; + +import java.io.BufferedReader; +import java.io.IOException; + +import org.eclipse.swt.widgets.Label; + +/** + * @author Emmanuel Bigeon + * + */ +public class PromptReadingRunnable implements Runnable { + + private final BufferedReader reader; + private final Label view; + private boolean running = true; + + /** @param reader the reader + * @param view the view to update on lines. */ + public PromptReadingRunnable(final BufferedReader reader, final Label view) { + super(); + this.reader = reader; + this.view = view; + } + + /* (non-Javadoc) + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + String prompt; + try { + while (isRunning() && (prompt = reader.readLine()) != null) { + final String curPrompt = prompt; + view.getDisplay().syncExec(new Runnable() { + @Override + public void run() { + view.setText(curPrompt); + } + }); + } + } catch (final IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + /** @return the running */ + public synchronized boolean isRunning() { + return running; + } + + /** @param running the running to set */ + public synchronized void setRunning(final boolean running) { + this.running = running; + } + + /** @return the reader */ + public BufferedReader getReader() { + return reader; + } +} diff --git a/gclc-swt/src/main/java/net/bigeon/gclc/swt/SWTConsole.java b/gclc-swt/src/main/java/net/bigeon/gclc/swt/SWTConsole.java deleted file mode 100644 index 827b324..0000000 --- a/gclc-swt/src/main/java/net/bigeon/gclc/swt/SWTConsole.java +++ /dev/null @@ -1,478 +0,0 @@ -/* - * GCLC swt, provide a swt window for console applications - * Copyright (C) 2015-2017 E. Bigeon - * mailto:emmanuel@bigeon.fr - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ -/** - * gclc-swt:net.bigeon.gclc.swt.SWTConsole.java - * Created on: Apr 18, 2015 - */ -package net.bigeon.gclc.swt; - -/*- - * #%L - * GCLC swt - * %% - * Copyright (C) 2015 - 2018 Bigeon - * %% - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - * #L% - */ -import java.io.IOException; -import java.util.function.Supplier; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; - -import net.bigeon.gclc.ConsoleApplication; -import net.bigeon.gclc.manager.ConsoleInput; -import net.bigeon.gclc.manager.ConsoleOutput; -import net.bigeon.gclc.tools.ConstantString; - -/** A SWT component to connect to gclc {@link ConsoleApplication}. - *

- * - * @author Emmanuel Bigeon */ -public final class SWTConsole extends Composite - implements ConsoleDelayIO, ConsoleInput, ConsoleOutput { - private static final int TWO = 2; - private static final String ERROR_SYNCHRO_PROMPT = "Error in synchronization of prompting"; - /** The number of columns of the layout. */ - private static final int LAYOUT_NB_COLUMNS = 2; - /** The cmd prefix in the output console. */ - private static final String CMD_PREFIX = "[CMD] "; //$NON-NLS-1$ - /** The class logger. */ - private static final Logger LOGGER = Logger - .getLogger(SWTConsole.class.getName()); - /** The empty string constant. */ - private static final String EMPTY = ""; //$NON-NLS-1$ - - /** The console output text field. */ - private final Text consoleOutput; - /** The console input text field. */ - private final Text consoleInput; - /** The prompt label. */ - private final Label lblPromptlabel; - /** The prompt text. */ - private Supplier prompt = new ConstantString("> "); //$NON-NLS-1$ - /** The command entered by the user. */ - private String command = null; - /** If the prompt should be active. */ - private boolean prompting = false; - /** The object for thread synchronization with the prompt. */ - private final Object promptLock = new Object(); - - /** Create the composite. - * - * @param parent the prent composite - * @param style the composite style */ - public SWTConsole(final Composite parent, final int style) { - super(parent, style); - - setLayout(new GridLayout(LAYOUT_NB_COLUMNS, false)); - - consoleOutput = new Text(this, - SWT.BORDER | SWT.READ_ONLY | SWT.WRAP | SWT.V_SCROLL | SWT.MULTI); - consoleOutput.setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, true, LAYOUT_NB_COLUMNS, 1)); - consoleOutput.setRedraw(true); - - lblPromptlabel = new Label(this, SWT.NONE); - lblPromptlabel.setText(prompt.get()); - - consoleInput = new Text(this, SWT.BORDER); - consoleInput.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); - consoleInput.addKeyListener(new HistoryTextKeyListener(this)); - - } - - /* (non-Javadoc) - * @see org.eclipse.swt.widgets.Composite#checkSubclass() */ - @Override - protected void checkSubclass() { - // Disable the check that prevents subclassing of SWT components - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.manager.ConsoleManager#close() */ - @Override - public void close() { - synchronized (promptLock) { - prompting = false; - promptLock.notifyAll(); - } - if (consoleInput.isDisposed()) { - return; - } - consoleInput.setEnabled(false); - consoleOutput.setEnabled(false); - } - - /* (non-Javadoc) - * @see net.bigeon.gclc.swt.ConsoleDelayIO#getInput() */ - @Override - public String getInput() { - return consoleInput.getText(); - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.ConsoleManager#getPrompt() */ - @Override - public Supplier getPrompt() { - return prompt; - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.manager.ConsoleManager#interruptPrompt() */ - @Override - public void interruptPrompt() { - synchronized (promptLock) { - promptLock.notifyAll(); - } - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.manager.ConsoleManager#isClosed() */ - @Override - public boolean isClosed() { - return isDisposed(); - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.ConsoleManager#print(java.lang.String) */ - @Override - public void print(final String text) throws IOException { - if (isDisposed()) { - throw new IOException(); - } - Display.getDefault().syncExec(new Runnable() { - @SuppressWarnings("synthetic-access") - @Override - public void run() { - if (!consoleOutput.isDisposed()) { - consoleOutput.append(text); - } - } - }); - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.ConsoleManager#println() */ - @Override - public void println() throws IOException { - if (isDisposed()) { - throw new IOException(); - } - Display.getDefault().syncExec(new Runnable() { - @SuppressWarnings("synthetic-access") - @Override - public void run() { - if (!consoleOutput.isDisposed()) { - consoleOutput.append(System.lineSeparator()); - } - } - }); - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.ConsoleManager#println(java.lang.String) */ - @Override - public void println(final String message) throws IOException { - if (isDisposed()) { - throw new IOException(); - } - Display.getDefault().syncExec(new Runnable() { - @SuppressWarnings("synthetic-access") - @Override - public void run() { - if (!consoleOutput.isDisposed()) { - consoleOutput.append(message + System.lineSeparator()); - } - } - }); - - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.ConsoleManager#prompt() */ - @Override - public String prompt() throws IOException { - synchronized (promptLock) { - initPrompt(prompt.get()); - promptLock.notifyAll(); - try { - while (prompting) { - promptLock.wait(); - } - } catch (final InterruptedException e) { - LOGGER.log(Level.WARNING, ERROR_SYNCHRO_PROMPT, e); - command = null; - Thread.currentThread().interrupt(); - } - } - if (isDisposed()) { - throw new IOException("Input closed"); //$NON-NLS-1$ - } - return command; - } - - /** Initialize the prompting. - * - * @param message the prompt message - * @throws IOException if the console is disposed */ - private void initPrompt(final String message) throws IOException { - if (isDisposed()) { - throw new IOException(); - } - Display.getDefault().syncExec(new Runnable() { - @SuppressWarnings("synthetic-access") - @Override - public void run() { - if (!consoleOutput.isDisposed()) { - lblPromptlabel.setText(message); - // relayout - SWTConsole.this.layout(); - consoleInput.setEnabled(true); - consoleInput.setFocus(); - } - } - }); - prompting = true; - command = null; - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.manager.ConsoleInput#prompt(long) */ - @Override - public String prompt(final long timeout) throws IOException { - synchronized (promptLock) { - initPrompt(prompt.get()); - promptLock.notifyAll(); - try { - waitPromptResolution(timeout); - } catch (final InterruptedException e) { - LOGGER.log(Level.WARNING, ERROR_SYNCHRO_PROMPT, e); - command = null; - Thread.currentThread().interrupt(); - } - } - return command; - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.ConsoleManager#prompt(java.lang.String) */ - @Override - public String prompt(final String message) throws IOException { - synchronized (promptLock) { - initPrompt(message); - promptLock.notifyAll(); - try { - while (prompting) { - promptLock.wait(); - } - if (isDisposed()) { - throw new IOException(); - } - } catch (final InterruptedException e) { - LOGGER.log(Level.WARNING, ERROR_SYNCHRO_PROMPT, e); - command = null; - Thread.currentThread().interrupt(); - } finally { - resetPrompt(); - } - } - return command; - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.manager.ConsoleInput#prompt(java.lang.String, long) */ - @Override - public String prompt(final String message, final long timeout) throws IOException { - synchronized (promptLock) { - initPrompt(message); - promptLock.notifyAll(); - try { - waitPromptResolution(timeout); - } catch (final InterruptedException e) { - LOGGER.log(Level.WARNING, ERROR_SYNCHRO_PROMPT, e); - command = null; - Thread.currentThread().interrupt(); - } finally { - resetPrompt(); - } - } - return command; - } - - /** Wait the prompt resolution by user. - * - * @param timeout the timeout for the wait - * @throws InterruptedException if the thread is interrupted - * @throws IOException if the console is disposed. */ - private void waitPromptResolution(final long timeout) - throws InterruptedException, IOException { - final long start = System.currentTimeMillis(); - long cur = start; - while (prompting && start + timeout > cur) { - promptLock.wait((cur - start - timeout) / TWO); - cur = System.currentTimeMillis(); - } - if (isDisposed()) { - throw new IOException(); - } - } - - /** Reset the prompt message. */ - private void resetPrompt() { - Display.getDefault().syncExec(new Runnable() { - @SuppressWarnings("synthetic-access") - @Override - public void run() { - if (!consoleOutput.isDisposed()) { - lblPromptlabel.setText(prompt.get()); - // relayout - SWTConsole.this.layout(); - } - } - }); - } - - /* (non-Javadoc) - * @see org.eclipse.swt.widgets.Composite#setFocus() */ - @Override - public boolean setFocus() { - return consoleInput.setFocus(); - } - - /* (non-Javadoc) - * @see net.bigeon.gclc.swt.ConsoleDelayIO#setInput(java.lang.String) */ - @Override - public void setInput(final String input) { - consoleInput.setText(input); - consoleInput.setSelection(input.length()); - } - - /* (non-Javadoc) - * @see net.bigeon.gclc.manager.ConsoleInput#setPrompt(java.lang.String) */ - @Override - public void setPrompt(final String prompt) { - setPrompt(new ConstantString(prompt)); - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.ConsoleManager#setPrompt(java.lang.String) */ - @Override - public void setPrompt(final Supplier prompt) { - this.prompt = prompt; - Display.getDefault().syncExec(new Runnable() { - @SuppressWarnings("synthetic-access") - @Override - public void run() { - if (!consoleOutput.isDisposed()) { - lblPromptlabel.setText(prompt.get()); - // relayout - SWTConsole.this.layout(); - } - } - }); - } - - /** Set the input text. - * - * @param string the text */ - public void setText(final String string) { - consoleInput.setText(string); - } - - /* (non-Javadoc) - * @see net.bigeon.gclc.swt.ConsoleDelayIO#validateInput() */ - @Override - public void validateInput() { - Display.getDefault().syncExec(new Runnable() { - @SuppressWarnings("synthetic-access") - @Override - public void run() { - consoleInput.setEnabled(false); - } - }); - synchronized (promptLock) { - while (!prompting) { - try { - promptLock.wait(); - } catch (final InterruptedException e) { - LOGGER.log(Level.SEVERE, "Interruption while waiting prompt", e); //$NON-NLS-1$ - Thread.currentThread().interrupt(); - } - } - Display.getDefault().syncExec(new Runnable() { - @SuppressWarnings("synthetic-access") - @Override - public void run() { - command = consoleInput.getText(); - prompting = false; - consoleInput.setText(EMPTY); - consoleOutput.append(CMD_PREFIX + command + System.lineSeparator()); - } - }); - promptLock.notifyAll(); - } - } - -} diff --git a/gclc-swt/src/main/java/net/bigeon/gclc/swt/SWTConsoleShell.java b/gclc-swt/src/main/java/net/bigeon/gclc/swt/SWTConsoleShell.java index dc30d1e..40bf9de 100644 --- a/gclc-swt/src/main/java/net/bigeon/gclc/swt/SWTConsoleShell.java +++ b/gclc-swt/src/main/java/net/bigeon/gclc/swt/SWTConsoleShell.java @@ -35,6 +35,8 @@ */ package net.bigeon.gclc.swt; +import java.io.BufferedReader; + /*- * #%L * GCLC swt @@ -69,26 +71,32 @@ package net.bigeon.gclc.swt; * #L% */ import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; -/** A shell containing a {@link SWTConsole} +import net.bigeon.gclc.utils.PipedConsoleInput; +import net.bigeon.gclc.utils.PipedConsoleOutput; + +/** A shell containing a {@link SWTConsoleView} *

* * @author Emmanuel Bigeon */ public final class SWTConsoleShell extends Shell { - /** The console component */ - private SWTConsole console; + private ConsoleInputManager inputManager; + private ConsoleOutputManager outputManager; + private ConsolePromptManager promptManager; /** Create the shell. * * @param display the display */ public SWTConsoleShell(final Display display, final int style) { super(display, style); - setLayout(new FillLayout(SWT.HORIZONTAL)); - + setLayout(new GridLayout(2, false)); createContents(); } @@ -99,20 +107,39 @@ public final class SWTConsoleShell extends Shell { /** Create contents of the shell. */ private void createContents() { - console = new SWTConsole(this, SWT.NONE); + final Text output = new Text(this, + SWT.WRAP | SWT.READ_ONLY | SWT.MULTI | SWT.V_SCROLL); + output.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); + final Label prompt = new Label(this, SWT.NONE); + prompt.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); + final Text input = new Text(this, SWT.NONE); + input.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + inputManager = new ConsoleInputManager(input); + outputManager = new ConsoleOutputManager(output); + promptManager = new ConsolePromptManager(prompt); setText("Console Application"); //$NON-NLS-1$ } - /* (non-Javadoc) - * @see org.eclipse.swt.widgets.Shell#dispose() */ - @Override - public void dispose() { - super.dispose(); - console.close(); + public void connect(final PipedConsoleInput input, final PipedConsoleOutput output, + final BufferedReader promptStream) { + inputManager.setManager(input); + outputManager.setManager(output); + promptManager.setStream(promptStream); } - /** @return the input and output. */ - public SWTConsole getManager() { - return console; + /** @return the inputManager */ + public ConsoleInputManager getInputManager() { + return inputManager; + } + + /** @return the outputManager */ + public ConsoleOutputManager getOutputManager() { + return outputManager; + } + + /** @return the promptManager */ + public ConsolePromptManager getPromptManager() { + return promptManager; } } diff --git a/gclc-swt/src/main/java/net/bigeon/gclc/swt/SWTConsoleView.java b/gclc-swt/src/main/java/net/bigeon/gclc/swt/SWTConsoleView.java index 1443fd6..020f87d 100644 --- a/gclc-swt/src/main/java/net/bigeon/gclc/swt/SWTConsoleView.java +++ b/gclc-swt/src/main/java/net/bigeon/gclc/swt/SWTConsoleView.java @@ -35,52 +35,15 @@ */ package net.bigeon.gclc.swt; -/*- - * #%L - * GCLC swt - * %% - * Copyright (C) 2015 - 2018 Bigeon - * %% - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - * #L% - */ -import java.io.IOException; -import java.util.logging.Level; import java.util.logging.Logger; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Text; import net.bigeon.gclc.ConsoleApplication; -import net.bigeon.gclc.utils.AOutputForwardRunnable; import net.bigeon.gclc.utils.PipedConsoleInput; import net.bigeon.gclc.utils.PipedConsoleOutput; @@ -88,47 +51,14 @@ import net.bigeon.gclc.utils.PipedConsoleOutput; *

* * @author Emmanuel Bigeon */ -public final class SWTConsoleView extends Composite implements ConsoleDelayIO { - /** The local implementation of the forwarding runnable - * - * @author Emmanuel Bigeon */ - private final class ToSWTConsoleForwardRunnable extends AOutputForwardRunnable { - /** The running status */ - private boolean running = true; - - /** @param manager the manager */ - public ToSWTConsoleForwardRunnable(final PipedConsoleOutput manager) { - super(manager); - } - - @Override - protected void forwardLine(final String m) { - appendConsoleOutput(System.lineSeparator() + m); - } - - @Override - protected boolean isRunning() { - return running && !isDisposed(); - } - - /** @param running the running to set */ - public void setRunning(final boolean running) { - this.running = running; - } - } - +public final class SWTConsoleView extends Composite { /** The class logger */ private static final Logger LOGGER = Logger .getLogger(SWTConsoleView.class.getName()); - /** The console output text field */ - private final Text consoleOutput; - /** The console input text field */ - private final Text consoleInput; /** The input. */ private PipedConsoleInput input; - /** The forwarding runnable */ - private ToSWTConsoleForwardRunnable forward; - + private final ConsoleInputManager inManager; + private final ConsoleOutputManager outManager; /** Create the composite. * * @param parent the prent composite @@ -138,25 +68,16 @@ public final class SWTConsoleView extends Composite implements ConsoleDelayIO { setLayout(new GridLayout(1, false)); - consoleOutput = new Text(this, + final Text consoleOutput = new Text(this, SWT.BORDER | SWT.READ_ONLY | SWT.WRAP | SWT.V_SCROLL | SWT.MULTI); consoleOutput.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); consoleOutput.setRedraw(true); + outManager = new ConsoleOutputManager(consoleOutput); - consoleInput = new Text(this, SWT.BORDER); + final Text consoleInput = new Text(this, SWT.BORDER); consoleInput.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); - consoleInput.addKeyListener(new HistoryTextKeyListener(this)); - } - - /** @param next the next message */ - public void appendConsoleOutput(final String next) { - Display.getDefault().syncExec(new Runnable() { - @SuppressWarnings("synthetic-access") - @Override - public void run() { - consoleOutput.append(next); - } - }); + inManager = new ConsoleInputManager(consoleInput); + consoleInput.addKeyListener(new HistoryTextKeyListener(inManager)); } @Override @@ -164,26 +85,11 @@ public final class SWTConsoleView extends Composite implements ConsoleDelayIO { // Disable the check that prevents subclassing of SWT components } - /* (non-Javadoc) - * @see net.bigeon.gclc.swt.ConsoleDelayIO#getInput() */ - @Override - public String getInput() { - return consoleInput.getText(); - } - /* (non-Javadoc) * @see org.eclipse.swt.widgets.Composite#setFocus() */ @Override public boolean setFocus() { - return consoleInput.setFocus(); - } - - /* (non-Javadoc) - * @see net.bigeon.gclc.swt.ConsoleDelayIO#setInput(java.lang.String) */ - @Override - public void setInput(final String input) { - consoleInput.setText(input); - consoleInput.setSelection(input.length()); + return inManager.getText().setFocus(); } /** Set the input and output. @@ -192,29 +98,17 @@ public final class SWTConsoleView extends Composite implements ConsoleDelayIO { * @param input the input */ public void setManager(final PipedConsoleOutput manager, final PipedConsoleInput input) { - this.input = input; - if (forward != null) { - forward.setRunning(false); - } - forward = new ToSWTConsoleForwardRunnable(manager); - final Thread th = new Thread(forward, "gclcToSWT"); //$NON-NLS-1$ - th.start(); + outManager.setManager(manager); + inManager.setManager(input); } - /** @param string the text */ - public void setText(final String string) { - consoleInput.setText(string); + /** @return the inManager */ + public ConsoleInputManager getInputManager() { + return inManager; } - /** - * - */ - @Override - public void validateInput() { - try { - input.type(getInput()); - } catch (final IOException e) { - LOGGER.log(Level.SEVERE, "Unable to input value to console", e); //$NON-NLS-1$ - } + /** @return the outManager */ + public ConsoleOutputManager getOutputManager() { + return outManager; } } diff --git a/gclc-swt/src/test/java/net/bigeon/gclc/swt/ConsoleInputManagerTest.java b/gclc-swt/src/test/java/net/bigeon/gclc/swt/ConsoleInputManagerTest.java new file mode 100644 index 0000000..bf1f286 --- /dev/null +++ b/gclc-swt/src/test/java/net/bigeon/gclc/swt/ConsoleInputManagerTest.java @@ -0,0 +1,85 @@ +/** + * + */ +package net.bigeon.gclc.swt; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.IOException; + +import org.eclipse.swt.widgets.Text; +import org.junit.Test; + +import net.bigeon.gclc.utils.PipedConsoleInput; + +/** @author Emmanuel Bigeon */ +public class ConsoleInputManagerTest { + + private final Text text = mock(Text.class); + private final ConsoleInputManager cim = new ConsoleInputManager(text); + + /** Test method for + * {@link net.bigeon.gclc.swt.ConsoleInputManager#setInput(java.lang.String)}. */ + @Test + public void testSetText() { + cim.setInput("Text"); + verify(text).setText("Text"); + } + + /** Test method for + * {@link net.bigeon.gclc.swt.ConsoleInputManager#validateInput()}. + * + * @throws IOException if an error occurred */ + @Test + public void testValidateInput() throws IOException { + // Expected calls + when(text.getText()).thenReturn("abc"); + + try { + cim.validateInput(); + fail("No input should cause exception for input validation"); + } catch (final Exception e) { + // ok + } + final PipedConsoleInput input = mock(PipedConsoleInput.class); + cim.setManager(input); + + cim.validateInput(); + verify(input).type("abc"); + } + + @Test + public void testValidateInputWithError() throws IOException { + final PipedConsoleInput input = mock(PipedConsoleInput.class); + cim.setManager(input); + // Expected calls + when(text.getText()).thenReturn("abc"); + doThrow(new IOException()).when(input).type("abc"); + + try { + cim.validateInput(); + fail("IO exception should be forwarded"); + } catch (final IOException e) { + // ok + } + } + + /** Test method for + * {@link net.bigeon.gclc.swt.ConsoleInputManager#getText()}. */ + @Test + public void testGetText() { + assertEquals("Text component should be preserved", text, cim.getText()); + } + + @Test + public void testGetInput() { + when(text.getText()).thenReturn("abc"); + assertEquals("Text component should be preserved", "abc", cim.getInput()); + } + +} diff --git a/gclc-swt/src/test/java/net/bigeon/gclc/swt/ConsoleOutputManagerTest.java b/gclc-swt/src/test/java/net/bigeon/gclc/swt/ConsoleOutputManagerTest.java new file mode 100644 index 0000000..26cdad3 --- /dev/null +++ b/gclc-swt/src/test/java/net/bigeon/gclc/swt/ConsoleOutputManagerTest.java @@ -0,0 +1,66 @@ +/** + * + */ +package net.bigeon.gclc.swt; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.IOException; + +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Text; +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import net.bigeon.gclc.utils.PipedConsoleOutput; + +/** @author Emmanuel Bigeon */ +public class ConsoleOutputManagerTest { + private final Text text = mock(Text.class); + private final ConsoleOutputManager com = new ConsoleOutputManager(text); + private final Display display = mock(Display.class); + { + when(text.getDisplay()).thenReturn(display); + doAnswer(new Answer() { + /* (non-Javadoc) + * @see + * org.mockito.stubbing.Answer#answer(org.mockito.invocation.InvocationOnMock) */ + @Override + public Object answer(final InvocationOnMock invocation) throws Throwable { + final Runnable runnable = invocation.getArgument(0); + runnable.run(); + return null; + } + }).when(display).syncExec(any(Runnable.class)); + } + + /** Test method for + * {@link net.bigeon.gclc.swt.ConsoleOutputManager#appendConsoleOutput(java.lang.String)}. */ + @Test + public void testAppendConsoleOutput() { + com.appendConsoleOutput("abc"); + verify(text).append("abc"); + } + + @Test + public void testSetManager() throws IOException, InterruptedException { + final PipedConsoleOutput output = mock(PipedConsoleOutput.class); + com.setManager(output); + com.setManager(output); + + try (PipedConsoleOutput output2 = new PipedConsoleOutput()) { + com.setManager(output2); + output2.println("line"); + final Thread forwardThread = com.getForwardThread(); + forwardThread.join(500); + com.setManager(null); + forwardThread.join(); + verify(text).append(System.lineSeparator() + "line"); + } + } +} diff --git a/gclc-swt/src/test/java/net/bigeon/gclc/swt/ConsolePromptManagerTest.java b/gclc-swt/src/test/java/net/bigeon/gclc/swt/ConsolePromptManagerTest.java new file mode 100644 index 0000000..da818bf --- /dev/null +++ b/gclc-swt/src/test/java/net/bigeon/gclc/swt/ConsolePromptManagerTest.java @@ -0,0 +1,47 @@ +/** + * + */ +package net.bigeon.gclc.swt; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import java.io.BufferedReader; + +import org.eclipse.swt.widgets.Label; +import org.junit.Test; + +/** + * @author Emmanuel Bigeon + * + */ +public class ConsolePromptManagerTest { + + private final Label label = mock(Label.class); + + private final ConsolePromptManager manager = new ConsolePromptManager(label); + + /** + * Test method for {@link net.bigeon.gclc.swt.ConsolePromptManager#setPrompt(java.lang.String)}. + */ + @Test + public void testSetPrompt() { + manager.setPrompt("abc"); + verify(label).setText("abc"); + } + + /** + * Test method for {@link net.bigeon.gclc.swt.ConsolePromptManager#setStream(java.io.BufferedReader)}. + */ + @Test + public void testSetStream() { + BufferedReader output = mock(BufferedReader.class); + manager.setStream(output); + manager.setStream(output); + output = mock(BufferedReader.class); + manager.setStream(output); + manager.setStream(null); + manager.setStream(output); + } + +} diff --git a/gclc-swt/src/test/java/net/bigeon/gclc/swt/HistoryTextKeyListenerTest.java b/gclc-swt/src/test/java/net/bigeon/gclc/swt/HistoryTextKeyListenerTest.java index 8b49c6c..5e82145 100644 --- a/gclc-swt/src/test/java/net/bigeon/gclc/swt/HistoryTextKeyListenerTest.java +++ b/gclc-swt/src/test/java/net/bigeon/gclc/swt/HistoryTextKeyListenerTest.java @@ -69,8 +69,10 @@ package net.bigeon.gclc.swt; * #L% */ import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyEvent; import org.junit.Test; /** @@ -84,7 +86,7 @@ public class HistoryTextKeyListenerTest { * {@link net.bigeon.gclc.swt.HistoryTextKeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)}. */ @Test public final void testKeyPressedKeyEvent() { - ConsoleDelayIO io = new ConsoleDelayIO() { + final ConsoleDelayIO io = new ConsoleDelayIO() { private String input = ""; @Override @@ -93,7 +95,7 @@ public class HistoryTextKeyListenerTest { } @Override - public void setInput(String input) { + public void setInput(final String input) { this.input = input; } @@ -102,7 +104,7 @@ public class HistoryTextKeyListenerTest { input = ""; } }; - HistoryTextKeyListener listener = new HistoryTextKeyListener(io); + final HistoryTextKeyListener listener = new HistoryTextKeyListener(io); // no effects assertEquals("", io.getInput()); @@ -139,4 +141,12 @@ public class HistoryTextKeyListenerTest { assertEquals("cmd arg2", io.getInput()); } + @Test + public void testKeyPressed() { + final ConsoleDelayIO io = mock(ConsoleDelayIO.class); + final KeyEvent event = mock(KeyEvent.class); + event.keyCode = 'a'; + final HistoryTextKeyListener listener = new HistoryTextKeyListener(io); + listener.keyPressed(event); + } } diff --git a/gclc-swt/src/test/java/net/bigeon/gclc/swt/SWTConsoleShellTest.java b/gclc-swt/src/test/java/net/bigeon/gclc/swt/SWTConsoleShellTest.java deleted file mode 100644 index 67a21ae..0000000 --- a/gclc-swt/src/test/java/net/bigeon/gclc/swt/SWTConsoleShellTest.java +++ /dev/null @@ -1,366 +0,0 @@ -/* - * GCLC swt, provide a swt window for console applications - * Copyright (C) 2015-2017 E. Bigeon - * mailto:emmanuel@bigeon.fr - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ -/** - * gclc-swt:net.bigeon.gclc.swt.SWTConsoleShellTest.java - * Created on: Jun 8, 2016 - */ -package net.bigeon.gclc.swt; - -/*- - * #%L - * GCLC swt - * %% - * Copyright (C) 2015 - 2018 Bigeon - * %% - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - * #L% - */ -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.IOException; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Display; -import org.junit.Test; - -import net.bigeon.gclc.ConsoleApplication; -import net.bigeon.gclc.command.Command; -import net.bigeon.gclc.command.base.ExitCommand; -import net.bigeon.gclc.exception.CommandRunException; -import net.bigeon.gclc.exception.InvalidCommandName; -import net.bigeon.gclc.manager.ConsoleInput; -import net.bigeon.gclc.manager.ConsoleOutput; - -/** - *

- * TODO - * - * @author Emmanuel Bigeon */ -@SuppressWarnings({ "javadoc", "static-method", "nls", "deprecation" }) -public class SWTConsoleShellTest { - - protected static final long TWO_SECONDS = 2000; - private static final Display DISPLAY = Display.getDefault(); - - @Test - public void testGeneric() { - final SWTConsoleShell shell = new SWTConsoleShell(DISPLAY, SWT.SHELL_TRIM); - final SWTConsole swtConsole = shell.getManager(); - try { - final ConsoleApplication appl = new ConsoleApplication(swtConsole, swtConsole, - "Hello", "See you"); - appl.add(new ExitCommand("exit", appl)); - appl.add(new Command("long") { - - /* (non-Javadoc) - * @see fr.bigeon.gclc.command.ICommand#execute(fr.bigeon.gclc. - * manager.ConsoleOutput, fr.bigeon.gclc.manager.ConsoleInput, - * java.lang.String[]) */ - @Override - public void execute(final ConsoleOutput out, final ConsoleInput in, - final String... args) throws CommandRunException { - try { - Thread.sleep(TWO_SECONDS); - } catch (final InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - @Override - public String tip() { - return "a long running command"; - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.command.Command#usageDetail() */ - @Override - protected String usageDetail() { - // TODO Auto-generated method stub - // return null; - throw new RuntimeException("Not implemented yet"); - } - }); -// shell.pack(); - shell.open(); - shell.setVisible(false); - final Thread applThread = new Thread(new Runnable() { - - @Override - public void run() { - appl.start(); - } - }); - final Thread testThread = new Thread(new Runnable() { - - @Override - public void run() { - try { - Thread.sleep(TWO_SECONDS); - } catch (final InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - Display.getDefault().syncExec(new Runnable() { - @Override - public void run() { - swtConsole.setText("test"); //$NON-NLS-1$ - swtConsole.validateInput(); - } - }); - try { - Thread.sleep(TWO_SECONDS); - } catch (final InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - Display.getDefault().syncExec(new Runnable() { - @Override - public void run() { - shell.dispose(); - } - }); - } - }); - applThread.start(); - testThread.start(); - while (!shell.isDisposed()) { - if (!DISPLAY.readAndDispatch()) { - DISPLAY.sleep(); - } - } -// DISPLAY.dispose(); - assertTrue(swtConsole.isClosed()); - Thread.sleep(TWO_SECONDS); - assertFalse(appl.isRunning()); - } catch (final InvalidCommandName e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (final InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - @Test - public void testConsoleClose() { - final SWTConsoleShell shell = new SWTConsoleShell(DISPLAY, SWT.SHELL_TRIM); - final SWTConsole swtConsole = shell.getManager(); - swtConsole.close(); - swtConsole.setPrompt(":"); - try { - final ConsoleApplication appl = new ConsoleApplication(swtConsole, swtConsole, - "Hello", "See you"); - appl.add(new ExitCommand("exit", appl)); - appl.add(new Command("long") { - /* (non-Javadoc) - * @see fr.bigeon.gclc.command.ICommand#execute(fr.bigeon.gclc. - * manager.ConsoleOutput, fr.bigeon.gclc.manager.ConsoleInput, - * java.lang.String[]) */ - @Override - public void execute(final ConsoleOutput out, final ConsoleInput in, - final String... args) throws CommandRunException { - try { - Thread.sleep(TWO_SECONDS); - } catch (final InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - @Override - public String tip() { - return "a long running command"; - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.command.Command#usageDetail() */ - @Override - protected String usageDetail() { - // TODO Auto-generated method stub - // return null; - throw new RuntimeException("Not implemented yet"); - } - }); - appl.add(new Command("test") { - /* (non-Javadoc) - * @see fr.bigeon.gclc.command.ICommand#execute(fr.bigeon.gclc. - * manager.ConsoleOutput, fr.bigeon.gclc.manager.ConsoleInput, - * java.lang.String[]) */ - @Override - public void execute(final ConsoleOutput out, final ConsoleInput in, - final String... args) throws CommandRunException { - try { - swtConsole.prompt("Test"); - } catch (final IOException e) { - throw new CommandRunException("No input", e); - } - } - - @Override - public String tip() { - return "a prompting running command"; - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.command.Command#usageDetail() */ - @Override - protected String usageDetail() { - // TODO Auto-generated method stub - // return null; - throw new RuntimeException("Not implemented yet"); - } - }); -// shell.pack(); - shell.open(); - shell.setVisible(false); - final Thread applThread = new Thread(new Runnable() { - - @Override - public void run() { - appl.start(); - } - }); - final Thread testThread = new Thread(new Runnable() { - - @Override - public void run() { - try { - Thread.sleep(TWO_SECONDS); - } catch (final InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - Display.getDefault().syncExec(new Runnable() { - @Override - public void run() { - swtConsole.setText("test"); //$NON-NLS-1$ - swtConsole.validateInput(); - } - }); - Display.getDefault().syncExec(new Runnable() { - @Override - public void run() { - swtConsole.setText("ok"); //$NON-NLS-1$ - } - }); - swtConsole.validateInput(); - Display.getDefault().syncExec(new Runnable() { - @Override - public void run() { - swtConsole.setText("long"); //$NON-NLS-1$ - } - }); - swtConsole.validateInput(); - Display.getDefault().syncExec(new Runnable() { - @Override - public void run() { - swtConsole.setText("test"); //$NON-NLS-1$ - } - }); - swtConsole.validateInput(); - Display.getDefault().syncExec(new Runnable() { - @Override - public void run() { - swtConsole.setText("test"); //$NON-NLS-1$ - } - }); - swtConsole.validateInput(); - try { - Thread.sleep(TWO_SECONDS); - } catch (final InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - Display.getDefault().syncExec(new Runnable() { - @Override - public void run() { - shell.dispose(); - } - }); - - } - }); - applThread.start(); - testThread.start(); - while (!shell.isDisposed()) { - if (!DISPLAY.readAndDispatch()) { - DISPLAY.sleep(); - } - } - swtConsole.setPrompt(">"); - try { - swtConsole.prompt(); - fail("Prompting when closed should fail!"); - } catch (final IOException e) { - assertNotNull(e); - } -// DISPLAY.dispose(); - assertTrue(swtConsole.isClosed()); - Thread.sleep(TWO_SECONDS); - assertFalse(appl.isRunning()); - } catch (final InvalidCommandName e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (final InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } -} diff --git a/gclc-swt/src/test/java/net/bigeon/gclc/swt/SWTConsoleViewTest.java b/gclc-swt/src/test/java/net/bigeon/gclc/swt/SWTConsoleViewTest.java deleted file mode 100644 index 4135463..0000000 --- a/gclc-swt/src/test/java/net/bigeon/gclc/swt/SWTConsoleViewTest.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * GCLC swt, provide a swt window for console applications - * Copyright (C) 2015-2017 E. Bigeon - * mailto:emmanuel@bigeon.fr - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ -/** - * gclc-swt:net.bigeon.gclc.swt.SWTConsoleShellTest.java - * Created on: Jun 8, 2016 - */ -package net.bigeon.gclc.swt; - -/*- - * #%L - * GCLC swt - * %% - * Copyright (C) 2015 - 2018 Bigeon - * %% - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - * #L% - */ -import static org.junit.Assert.assertNull; - -import java.io.IOException; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.junit.Test; - -import net.bigeon.gclc.ConsoleApplication; -import net.bigeon.gclc.command.Command; -import net.bigeon.gclc.command.base.ExitCommand; -import net.bigeon.gclc.exception.CommandRunException; -import net.bigeon.gclc.exception.InvalidCommandName; -import net.bigeon.gclc.manager.ConsoleInput; -import net.bigeon.gclc.manager.ConsoleOutput; -import net.bigeon.gclc.utils.PipedConsoleInput; -import net.bigeon.gclc.utils.PipedConsoleOutput; - -/** - *

- * TODO - * - * @author Emmanuel Bigeon */ -@SuppressWarnings({ "javadoc", "static-method", "nls", "deprecation" }) -public class SWTConsoleViewTest { - - protected static final long TWO_SECONDS = 2000; - private static final Display DISPLAY = Display.getDefault(); - - @Test - public void testGeneric() { - final Shell shell = new Shell(DISPLAY); - final SWTConsoleView swtConsole = new SWTConsoleView(shell, SWT.NONE); - try (PipedConsoleOutput manager = new PipedConsoleOutput(); - PipedConsoleInput input = new PipedConsoleInput(System.out)) { - swtConsole.setManager(manager, input); - } catch (final IOException e2) { - assertNull(e2); - } - try (PipedConsoleOutput manager = new PipedConsoleOutput(); - PipedConsoleInput input = new PipedConsoleInput(System.out)) { - swtConsole.setManager(manager, input); - final ConsoleApplication appl = new ConsoleApplication(manager, input, - "Hello", "See you"); - appl.add(new ExitCommand("exit", appl)); - appl.add(new Command("long") { - - /* (non-Javadoc) - * @see fr.bigeon.gclc.command.ICommand#execute(fr.bigeon.gclc.manager. - * ConsoleOutput, fr.bigeon.gclc.manager.ConsoleInput, - * java.lang.String[]) */ - @Override - public void execute(final ConsoleOutput out, final ConsoleInput in, - final String... args) throws CommandRunException { - try { - Thread.sleep(TWO_SECONDS); - } catch (final InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - @Override - public String tip() { - return "a long running command"; - } - - /* (non-Javadoc) - * @see fr.bigeon.gclc.command.Command#usageDetail() */ - @Override - protected String usageDetail() { - // TODO Auto-generated method stub - // return null; - throw new RuntimeException("Not implemented yet"); - } - }); -// shell.pack(); - shell.open(); - shell.setVisible(false); - final Thread applThread = new Thread(new Runnable() { - - @Override - public void run() { - appl.start(); - } - }); - final Thread testThread = new Thread(new Runnable() { - - @Override - public void run() { - try { - Thread.sleep(TWO_SECONDS); - } catch (final InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - Display.getDefault().syncExec(new Runnable() { - @Override - public void run() { - swtConsole.setText("test"); //$NON-NLS-1$ - swtConsole.validateInput(); - } - }); - try { - Thread.sleep(TWO_SECONDS); - } catch (final InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - Display.getDefault().syncExec(new Runnable() { - @Override - public void run() { - shell.dispose(); - } - }); - } - }); - applThread.start(); - testThread.start(); - while (!shell.isDisposed()) { - if (!DISPLAY.readAndDispatch()) { - DISPLAY.sleep(); - } - } - } catch (final InvalidCommandName e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (final IOException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - } -} diff --git a/gclc-swt/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/gclc-swt/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000..ca6ee9c --- /dev/null +++ b/gclc-swt/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file