|
From: David C. <dc...@us...> - 2005-10-02 21:07:58
|
Update of /cvsroot/rubyeclipse/org.rubypeople.rdt.launching.tests/src/org/rubypeople/rdt/internal/launching In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8073/src/org/rubypeople/rdt/internal/launching Added Files: EvaluateRubyProcessOutput.java TS_Launching.java ShamProcess.java TC_RubyInterpreter.java TC_RunnerLaunching.java TC_ArgumentSplitter.java TC_RubyRuntime.java Log Message: Added additional UTs for launching. Moved tests to the correct package. Slight refactoring of launching code. --- NEW FILE: ShamProcess.java --- /** * */ package org.rubypeople.rdt.internal.launching; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; public class ShamProcess extends Process { public void destroy() { } public int exitValue() { return 0; } public InputStream getErrorStream() { return new ByteArrayInputStream(new byte[0]); } public InputStream getInputStream() { return new ByteArrayInputStream(new byte[0]); } public OutputStream getOutputStream() { return new ByteArrayOutputStream(1024); } public int waitFor() throws InterruptedException { return 0; } } --- NEW FILE: TC_RubyRuntime.java --- package org.rubypeople.rdt.internal.launching; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; import java.util.Arrays; import java.util.List; import junit.framework.TestCase; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFileState; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IResourceProxyVisitor; import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourceAttributes; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.core.runtime.content.IContentDescription; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.rubypeople.rdt.internal.launching.RubyInterpreter; import org.rubypeople.rdt.internal.launching.RubyRuntime; public class TC_RubyRuntime extends TestCase { protected StringWriter runtimeConfigurationWriter = new StringWriter(); public TC_RubyRuntime(String name) { super(name); } public void testGetInstalledInterpreters() { ShamRubyRuntime runtime = new ShamRubyRuntime(); RubyInterpreter interpreterOne = new RubyInterpreter("InterpreterOne", new Path("C:/RubyInstallRootOne")); RubyInterpreter interpreterTwo = new RubyInterpreter("InterpreterTwo", new Path("C:/RubyInstallRootTwo")); assertTrue("Runtime should contain all interpreters.", runtime.getInstalledInterpreters().containsAll(Arrays.asList(new Object[] { interpreterOne, interpreterTwo }))); assertTrue("interpreterTwo should be selected interpreter.", runtime.getSelectedInterpreter().equals(interpreterTwo)); } public void testSetInstalledInterpreters() { ShamRubyRuntime runtime = new ShamRubyRuntime(); RubyInterpreter interpreterOne = new RubyInterpreter("InterpreterOne", new Path("C:/RubyInstallRootOne")); runtime.setInstalledInterpreters(Arrays.asList(new Object[] { interpreterOne })); runtime.saveRuntimeConfiguration() ; assertEquals("XML should indicate only one interpreter with it being the selected.", "<?xml version=\"1.0\" encoding=\"UTF-8\"?><runtimeconfig><interpreter name=\"InterpreterOne\" path=\"C:/RubyInstallRootOne\" selected=\"true\"/></runtimeconfig>", runtimeConfigurationWriter.toString()); RubyInterpreter interpreterTwo = new RubyInterpreter("InterpreterTwo", new Path("C:/RubyInstallRootTwo")); runtime.setInstalledInterpreters(Arrays.asList(new Object[] { interpreterOne, interpreterTwo })); runtime.saveRuntimeConfiguration() ; assertEquals("XML should indicate both interpreters with the first one being selected.", "<?xml version=\"1.0\" encoding=\"UTF-8\"?><runtimeconfig><interpreter name=\"InterpreterOne\" path=\"C:/RubyInstallRootOne\" selected=\"true\"/><interpreter name=\"InterpreterTwo\" path=\"C:/RubyInstallRootTwo\"/></runtimeconfig>", runtimeConfigurationWriter.toString()); runtime.setSelectedInterpreter(interpreterTwo); runtime.saveRuntimeConfiguration() ; assertEquals("XML should indicate selected interpreter change.", "<?xml version=\"1.0\" encoding=\"UTF-8\"?><runtimeconfig><interpreter name=\"InterpreterOne\" path=\"C:/RubyInstallRootOne\"/><interpreter name=\"InterpreterTwo\" path=\"C:/RubyInstallRootTwo\" selected=\"true\"/></runtimeconfig>", runtimeConfigurationWriter.toString()); } protected class ShamRubyRuntime extends RubyRuntime { protected ShamRubyRuntime() { super(); } protected Reader getRuntimeConfigurationReader() { return new StringReader("<?xml version=\"1.0\" encoding=\"UTF-8\"?><runtimeconfig><interpreter name=\"InterpreterOne\" path=\"C:/RubyInstallRootOne\"/><interpreter name=\"InterpreterTwo\" path=\"C:/RubyInstallRootTwo\" selected=\"true\"/></runtimeconfig>"); } protected Writer getRuntimeConfigurationWriter() { return runtimeConfigurationWriter; } public void setInstalledInterpreters(List newInstalledInterpreters) { super.setInstalledInterpreters(newInstalledInterpreters); } public void saveRuntimeConfiguration() { runtimeConfigurationWriter = new StringWriter(); super.saveRuntimeConfiguration() ; } } protected class RuntimeConfigurationFile implements IFile { protected RuntimeConfigurationFile() {} public void setCharset(String newCharset, IProgressMonitor monitor) throws CoreException { } public void appendContents(InputStream source, boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException {} public void appendContents(InputStream source, int updateFlags, IProgressMonitor monitor) throws CoreException {} public void create(InputStream source, boolean force, IProgressMonitor monitor) throws CoreException {} public void create(InputStream source, int updateFlags, IProgressMonitor monitor) throws CoreException {} public void delete(boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException {} public InputStream getContents() throws CoreException { return new ByteArrayInputStream("<?xml version=\"1.0\" encoding=\"UTF-8\"?><runtimeconfig><interpreter name=\"InterpreterOne\" path=\"C:/RubyInstallRootOne\"/><interpreter name=\"InterpreterTwo\" path=\"C:/RubyInstallRootTwo\" selected=\"true\"/></runtimeconfig>".getBytes()); } public InputStream getContents(boolean force) throws CoreException { return getContents(); } public IPath getFullPath() { return null; } public IFileState[] getHistory(IProgressMonitor monitor) throws CoreException { return null; } public String getName() { return null; } public boolean isReadOnly() { return false; } public String getCharset() throws CoreException { return null; } public void move(IPath destination, boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException {} public void setContents(IFileState source, boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException {} public void setContents(IFileState source, int updateFlags, IProgressMonitor monitor) throws CoreException {} public void setContents(InputStream source, boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException {} public void setContents(InputStream source, int updateFlags, IProgressMonitor monitor) throws CoreException {} public void accept(IResourceVisitor visitor, int depth, boolean includePhantoms) throws CoreException {} public void accept(IResourceVisitor visitor, int depth, int memberFlags) throws CoreException {} public void accept(IResourceVisitor visitor) throws CoreException {} public void clearHistory(IProgressMonitor monitor) throws CoreException {} public void copy(IPath destination, boolean force, IProgressMonitor monitor) throws CoreException {} public void copy(IPath destination, int updateFlags, IProgressMonitor monitor) throws CoreException {} public void copy(IProjectDescription description, boolean force, IProgressMonitor monitor) throws CoreException {} public void copy(IProjectDescription description, int updateFlags, IProgressMonitor monitor) throws CoreException {} public IMarker createMarker(String type) throws CoreException { return null; } public void delete(boolean force, IProgressMonitor monitor) throws CoreException {} public void delete(int updateFlags, IProgressMonitor monitor) throws CoreException {} public void deleteMarkers(String type, boolean includeSubtypes, int depth) throws CoreException {} public boolean exists() { return false; } public IMarker findMarker(long id) throws CoreException { return null; } public IMarker[] findMarkers(String type, boolean includeSubtypes, int depth) throws CoreException { return null; } public String getFileExtension() { return null; } public IPath getLocation() { return null; } public IMarker getMarker(long id) { return null; } public long getModificationStamp() { return 0; } public IContainer getParent() { return null; } public String getPersistentProperty(QualifiedName key) throws CoreException { return null; } public IProject getProject() { return null; } public IPath getProjectRelativePath() { return null; } public Object getSessionProperty(QualifiedName key) throws CoreException { return null; } public int getType() { return 0; } public IWorkspace getWorkspace() { return null; } public boolean isAccessible() { return false; } public boolean isDerived() { return false; } public boolean isLocal(int depth) { return false; } public boolean isPhantom() { return false; } public boolean isTeamPrivateMember() { return false; } public void move(IPath destination, boolean force, IProgressMonitor monitor) throws CoreException {} public void move(IPath destination, int updateFlags, IProgressMonitor monitor) throws CoreException {} public void move(IProjectDescription description, boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException {} public void move(IProjectDescription description, int updateFlags, IProgressMonitor monitor) throws CoreException {} public void refreshLocal(int depth, IProgressMonitor monitor) throws CoreException {} public void setDerived(boolean isDerived) throws CoreException {} public void setLocal(boolean flag, int depth, IProgressMonitor monitor) throws CoreException {} public void setPersistentProperty(QualifiedName key, String value) throws CoreException {} public void setReadOnly(boolean readOnly) {} public void setSessionProperty(QualifiedName key, Object value) throws CoreException {} public void setTeamPrivateMember(boolean isTeamPrivate) throws CoreException {} public void touch(IProgressMonitor monitor) throws CoreException {} public Object getAdapter(Class adapter) { return null; } public boolean isSynchronized(int depth) { return false; } public int getEncoding() throws CoreException { return 0; } public void createLink( IPath localLocation, int updateFlags, IProgressMonitor monitor) throws CoreException { } public IPath getRawLocation() { return null; } public boolean isLinked() { return false; } public void accept(IResourceProxyVisitor arg0, int arg1) throws CoreException { } public long getLocalTimeStamp() { return 0; } public long setLocalTimeStamp(long value) throws CoreException { return 0; } public boolean contains(ISchedulingRule rule) { return false; } public boolean isConflicting(ISchedulingRule rule) { return false; } public void setCharset(String newCharset) throws CoreException { } /* (non-Javadoc) * @see org.eclipse.core.resources.IFile#getCharset(boolean) */ public String getCharset(boolean checkImplicit) throws CoreException { // TODO Auto-generated method stub return null; } /* (non-Javadoc) * @see org.eclipse.core.resources.IFile#getContentDescription() */ public IContentDescription getContentDescription() throws CoreException { // TODO Auto-generated method stub return null; } public String getCharsetFor(Reader reader) throws CoreException { // TODO Auto-generated method stub return null; } public ResourceAttributes getResourceAttributes() { // TODO Auto-generated method stub return null; } public void revertModificationStamp(long value) throws CoreException { // TODO Auto-generated method stub } public void setResourceAttributes(ResourceAttributes attributes) throws CoreException { // TODO Auto-generated method stub } } } --- NEW FILE: TC_RunnerLaunching.java --- package org.rubypeople.rdt.internal.launching; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import junit.framework.TestCase; import org.eclipse.core.boot.BootLoader; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationType; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.core.Launch; import org.rubypeople.eclipse.shams.debug.core.ShamLaunchConfigurationType; import org.rubypeople.eclipse.testutils.ResourceTools; import org.rubypeople.rdt.internal.launching.DebuggerRunner; import org.rubypeople.rdt.internal.launching.RubyInterpreter; import org.rubypeople.rdt.internal.launching.RubyLaunchConfigurationAttribute; import org.rubypeople.rdt.internal.launching.RubyRuntime; public class TC_RunnerLaunching extends TestCase { private final static String PROJECT_NAME = "Simple Project"; private final static String RUBY_LIB_DIR = "someRubyDir"; // dir inside project private final static String RUBY_FILE_NAME = "rubyFile.rb"; private final static String INTERPRETER_ARGUMENTS = "interpreter Arguments"; private final static String PROGRAM_ARGUMENTS = "programArguments"; private final static String RUBY_COMMAND = "rubyw"; public TC_RunnerLaunching(String name) { super(name); } protected ILaunchManager getLaunchManager() { return DebugPlugin.getDefault().getLaunchManager(); } protected List getCommandLine(IProject project, boolean debug) { List commandLine = new ArrayList(); if (debug) { commandLine.add("-reclipseDebug"); } if (debug) { String dirOfRubyDebuggerFile = DebuggerRunner.getDirectoryOfRubyDebuggerFile().replace('/', File.separatorChar) ; if (dirOfRubyDebuggerFile.startsWith("\\")) { dirOfRubyDebuggerFile = dirOfRubyDebuggerFile.substring(1) ; } commandLine.add("-I"); commandLine.add(dirOfRubyDebuggerFile); } commandLine.add("-I"); commandLine.add( project.getLocation().toOSString()); commandLine.add("-I"); commandLine.add(project.getLocation().toOSString() + File.separator + RUBY_LIB_DIR) ; commandLine.addAll(Arrays.asList(INTERPRETER_ARGUMENTS.split("\\s+"))); commandLine.add("--"); // use always forward slashes for path relative to project dir commandLine.add(project.getLocation().toOSString() + "/" + RUBY_LIB_DIR + "/" + RUBY_FILE_NAME); commandLine.add(PROGRAM_ARGUMENTS); return commandLine; } public void testDebugEnabled() throws Exception { // check if debugging is enabled in plugin.xml ILaunchConfigurationType launchConfigurationType = getLaunchManager().getLaunchConfigurationType( RubyLaunchConfigurationAttribute.RUBY_LAUNCH_CONFIGURATION_TYPE); assertEquals("Ruby Application", launchConfigurationType.getName()); assertTrue( "LaunchConfiguration supports debug", launchConfigurationType.supportsMode(ILaunchManager.DEBUG_MODE)); } public void launch(boolean debug) throws Exception { IProject project = ResourceTools.createProject(PROJECT_NAME); ShamInterpreter interpreter = new ShamInterpreter("", new Path("")); List installedInterpreters = new ArrayList(); installedInterpreters.add(interpreter); RubyRuntime.getDefault().setInstalledInterpreters(installedInterpreters); RubyRuntime.getDefault().setSelectedInterpreter(interpreter); ILaunchConfiguration configuration = new ShamLaunchConfiguration(); ILaunch launch = new Launch(configuration, debug ? ILaunchManager.DEBUG_MODE : ILaunchManager.RUN_MODE, null); ILaunchConfigurationType launchConfigurationType = getLaunchManager().getLaunchConfigurationType( RubyLaunchConfigurationAttribute.RUBY_LAUNCH_CONFIGURATION_TYPE); launchConfigurationType.getDelegate().launch( configuration, debug ? ILaunchManager.DEBUG_MODE : ILaunchManager.RUN_MODE, launch, null); assertEquals("One process has been spawned", 1, launch.getProcesses().length); List expected = getCommandLine(project, debug); List actual = interpreter.getArguments(); assertEquals("Assembled command line.", expected, actual); assertEquals( "Process label.", "Ruby " + RUBY_COMMAND + " : " + RUBY_LIB_DIR + "/" + RUBY_FILE_NAME, launch.getProcesses()[0].getLabel()); } public void testRunInDebugMode() throws Exception { launch(true); } public void testRunInRunMode() throws Exception { launch(false); } public class ShamLaunchConfiguration implements ILaunchConfiguration { public boolean contentsEqual(ILaunchConfiguration configuration) { return false; } public ILaunchConfigurationWorkingCopy copy(String name) throws CoreException { return null; } public void delete() throws CoreException { } public boolean exists() { return true; } public boolean getAttribute(String attributeName, boolean defaultValue) throws CoreException { return false; } public int getAttribute(String attributeName, int defaultValue) throws CoreException { return 0; } public List getAttribute(String attributeName, List defaultValue) throws CoreException { return null; } public Map getAttribute(String attributeName, Map defaultValue) throws CoreException { return null; } public String getAttribute(String attributeName, String defaultValue) throws CoreException { if (attributeName.equals(RubyLaunchConfigurationAttribute.PROJECT_NAME)) { return PROJECT_NAME; } else if (attributeName.equals(RubyLaunchConfigurationAttribute.FILE_NAME)) { return RUBY_LIB_DIR + File.separator + RUBY_FILE_NAME; } else if (attributeName.equals(RubyLaunchConfigurationAttribute.WORKING_DIRECTORY)) { return "C:\\Working Dir"; } else if (attributeName.equals(RubyLaunchConfigurationAttribute.INTERPRETER_ARGUMENTS)) { return INTERPRETER_ARGUMENTS; } else if (attributeName.equals(RubyLaunchConfigurationAttribute.PROGRAM_ARGUMENTS)) { return PROGRAM_ARGUMENTS; } return null; } public IFile getFile() { return null; } public IPath getLocation() { return null; } public String getMemento() throws CoreException { return null; } public String getName() { return null; } public ILaunchConfigurationType getType() throws CoreException { return new ShamLaunchConfigurationType(); } public ILaunchConfigurationWorkingCopy getWorkingCopy() throws CoreException { return null; } public boolean isLocal() { return false; } public boolean isWorkingCopy() { return false; } public ILaunch launch(String mode, IProgressMonitor monitor) throws CoreException { return null; } public boolean supportsMode(String mode) throws CoreException { return false; } public Object getAdapter(Class adapter) { return null; } public String getCategory() throws CoreException { return null; } public Map getAttributes() throws CoreException { return null; } public ILaunch launch(String mode, IProgressMonitor monitor, boolean build) throws CoreException { return null; } /* (non-Javadoc) * @see org.eclipse.debug.core.ILaunchConfiguration#launch(java.lang.String, org.eclipse.core.runtime.IProgressMonitor, boolean, boolean) */ public ILaunch launch(String mode, IProgressMonitor monitor, boolean build, boolean register) throws CoreException { // TODO Auto-generated method stub return null; } } public class ShamInterpreter extends RubyInterpreter { public ShamInterpreter(String aName, IPath validInstallLocation) { super(aName, validInstallLocation); } private List arguments; public List getArguments() { return arguments; } public String getCommand() { return RUBY_COMMAND; } public Process exec(List args, File workingDirectory) { arguments = args; return new ShamProcess(); } } } --- NEW FILE: TS_Launching.java --- package org.rubypeople.rdt.internal.launching; import junit.framework.Test; import junit.framework.TestSuite; public class TS_Launching { public static Test suite() { TestSuite suite = new TestSuite(); suite.addTestSuite(TC_RubyInterpreter.class); suite.addTestSuite(TC_RubyRuntime.class); suite.addTestSuite(TC_RunnerLaunching.class) ; suite.addTestSuite(TC_ArgumentSplitter.class) ; return suite; } } --- NEW FILE: TC_RubyInterpreter.java --- package org.rubypeople.rdt.internal.launching; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import junit.framework.TestCase; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.rubypeople.rdt.internal.launching.CommandExecutor; import org.rubypeople.rdt.internal.launching.IllegalCommandException; import org.rubypeople.rdt.internal.launching.RubyInterpreter; public class TC_RubyInterpreter extends TestCase { private static final String TEST_RUBY_CMD = "/foo bar ruby"; private static final File WORKING_DIR = new File("/testDir"); public void testEquals() { RubyInterpreter interpreterOne = new RubyInterpreter("InterpreterOne", new Path("/InterpreterOnePath")); RubyInterpreter similarInterpreterOne = new RubyInterpreter("InterpreterOne", new Path("/InterpreterOnePath")); assertTrue("Interpreters should be equal.", interpreterOne.equals(similarInterpreterOne)); RubyInterpreter interpreterTwo = new RubyInterpreter("InterpreterTwo", new Path("/InterpreterTwoPath")); assertTrue("Interpreters should not be equal.", !interpreterOne.equals(interpreterTwo)); } public void testExecList() throws Exception { ShamCommandExecutor executor = new ShamCommandExecutor(); RubyInterpreter interpreter = new NonValidatingInterpreter("Test", new Path("/path to ruby"), executor); ShamProcess process = new ShamProcess(); executor.setProcessToReturn(process); Process result = interpreter.exec(Arrays.asList(new String[] {"a","b b", "c"}), WORKING_DIR); executor.assertExecute(new String[] {TEST_RUBY_CMD, "a", "b b", "c"}, WORKING_DIR); assertEquals(process, result); } public void testExecutorThrows() throws Exception { ShamCommandExecutor executor = new ShamCommandExecutor(); RubyInterpreter interpreter = new NonValidatingInterpreter("Test", new Path("/path to ruby"), executor); IOException testException = new IOException("test"); executor.setExceptionToThrow(testException); try { interpreter.exec(new ArrayList(), WORKING_DIR); fail("Expected CoreException"); } catch (CoreException expected) { assertEquals(IStatus.ERROR, expected.getStatus().getSeverity()); assertEquals(testException, expected.getStatus().getException()); } } public void testUnknownInterperterThrows() throws Exception { RubyInterpreter interpreter = new RubyInterpreter("Test", new Path("unknown ruby interpreter"), null); try { interpreter.exec(new ArrayList(), WORKING_DIR); fail("Expected CoreException"); } catch (CoreException expected) { assertEquals(IStatus.ERROR, expected.getStatus().getSeverity()); assertEquals(IllegalCommandException.class, expected.getStatus().getException().getClass()); } } private static final class NonValidatingInterpreter extends RubyInterpreter { private NonValidatingInterpreter(String name, IPath location, CommandExecutor executor) { super(name, location, executor); } public String getCommand() throws IllegalCommandException { return TEST_RUBY_CMD; } } private static class ShamCommandExecutor implements CommandExecutor { private String[] commandArg; private File workingDirectoryArg; private ShamProcess processToReturn; private IOException exceptionToThrow; public void assertExecute(String[] expectedCommand, File expectedWorkingDir) { assertEquals("Command ", Arrays.asList(expectedCommand), Arrays.asList(commandArg)); assertEquals("Working dir", expectedWorkingDir, workingDirectoryArg); } public void setExceptionToThrow(IOException exception) { this.exceptionToThrow = exception; } public void setProcessToReturn(ShamProcess process) { this.processToReturn = process; } public Process exec(String[] command, File workingDirectory) throws IOException { commandArg = command; workingDirectoryArg = workingDirectory; if (exceptionToThrow != null) throw exceptionToThrow; return processToReturn; } } } --- NEW FILE: TC_ArgumentSplitter.java --- package org.rubypeople.rdt.internal.launching; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import junit.framework.TestCase; import org.rubypeople.rdt.internal.launching.ArgumentSplitter; public class TC_ArgumentSplitter extends TestCase { public void testNoArgs() { verifySplit(new String[]{}, ""); verifySplit(new String[]{}, " "); verifySplit(new String[]{}, " "); } public void testSimpleSplit() { verifySplit(new String[]{"foo"}, "foo"); verifySplit(new String[]{"foo"}, " foo "); verifySplit(new String[]{"foo", "bar"}, "foo bar"); verifySplit(new String[]{"foo", "bar"}, " foo bar "); } public void testSimpleQuotes() { verifySplit(new String[]{"foo"}, "'foo'"); verifySplit(new String[]{"foo bar"}, "'foo bar'"); verifySplit(new String[]{"foo bar","red blue"}, "'foo bar' 'red blue'"); verifySplit(new String[]{"foo"}, "\"foo\""); } public void testEmptyQuotes() { verifySplit(new String[]{""}, "''"); verifySplit(new String[]{"F", "", "B", "X"}, "F '' B \"X"); verifySplit(new String[]{"F", "", "B"}, "F '' B \""); } public void testMixedQuotes() { verifySplit(new String[]{"f\"oo"}, "'f\"oo'"); verifySplit(new String[]{"f'oo"}, "\"f'oo\""); } private void verifySplit(String[] expected, String input) { List args = ArgumentSplitter.split(input); assertEquals("For input: "+input, new ArrayList(Arrays.asList(expected)), args); } } --- NEW FILE: EvaluateRubyProcessOutput.java --- package org.rubypeople.rdt.internal.launching; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; /* There is a different behaviour, when a ruby application ist started from commandlined compared to a ruby application started with RDT. E.g. there must be additional STDOUT.flush commands for RDT started applications in order to achieve same bahvior. */ public class EvaluateRubyProcessOutput implements Runnable { // Allocate 1K buffers for Input and Error Streams.. private byte[] inBuffer = new byte[1024]; private byte[] errBuffer = new byte[1024]; // Declare internal variables we will need.. private Process process; private InputStream pErrorStream; private InputStream pInputStream; private OutputStream pOutputStream; private PrintWriter outputWriter; private Thread inReadThread; private Thread errReadThread; public EvaluateRubyProcessOutput(Process p) { // Save variables.. process = p; // Get the streams.. pErrorStream = process.getErrorStream(); pInputStream = process.getInputStream(); pOutputStream = process.getOutputStream(); // Create a PrintWriter on top of the output stream.. // Create the threads and start them.. inReadThread = new Thread(this); errReadThread = new Thread(this); outputWriter = new PrintWriter(pOutputStream, true); new Thread() { public void run() { try { // This Thread just waits for the process to // end and notifies the handler.. process.waitFor() ; System.out.println("Process endend.") ; } catch (InterruptedException ex) { ex.printStackTrace(); } } }.start(); inReadThread.start(); errReadThread.start(); } private void processEnded(int exitValue) { // Handle process end.. //handler.processEnded(exitValue); } private void processNewInput(String input) { // Handle process new input.. //handler.processNewInput(input); System.out.println(input) ; } private void processNewError(String error) { // Handle process new error.. //handler.processNewError(error); } // Run the command and return the ExecHelper wrapper object.. // Send the output string through the print writer.. public void sendOutput(String output) throws IOException { outputWriter.println(output); } public void run() { // Are we on the InputRead Thread? if (inReadThread == Thread.currentThread()) { try { // Read the InputStream in a loop until we find no // more bytes to read.. for (int i = 0; i > -1; i = pInputStream.read(inBuffer)) { // We have a new segment of input, so process // it as a String.. processNewInput(new String(inBuffer, 0, i)); } } catch (IOException ex) { ex.printStackTrace(); } // Are we on the ErrorRead Thread? } else if (errReadThread == Thread.currentThread()) { try { // Read the ErrorStream in a loop until we find no // more bytes to read.. for (int i = 0; i > -1; i = pErrorStream.read(errBuffer)) { // We have a new segment of error, so process // it as a String.. processNewError(new String(errBuffer, 0, i)); } } catch (IOException ex) { ex.printStackTrace(); } } } public static void main(String[] args) throws Exception { /* file D:\\Temp\\test.rb: class Hello attr_reader :msg def initialize @msg = "Hello, World\n" end end h = Hello.new puts h.msg print "Press RETURN" STDOUT.flush input = $stdin.gets puts "You entered #{input}" */ Process p = Runtime.getRuntime().exec("D:\\ruby-1.8.0\\ruby\\bin\\ruby.exe D:\\Temp\\test.rb"); EvaluateRubyProcessOutput erpo = new EvaluateRubyProcessOutput(p) ; String in = new BufferedReader(new InputStreamReader(System.in)).readLine() ; erpo.sendOutput(in) ; } } |