You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2022/12/26 16:55:04 UTC
[groovy] 02/02: GROOVY-10105: streamline `GroovyStarter` -> `Groovysh` -> user's script
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit b8ba3e0e71a2994b741d1bf9478b479be1b4b91e
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Dec 26 10:37:57 2022 -0600
GROOVY-10105: streamline `GroovyStarter` -> `Groovysh` -> user's script
---
.../org/codehaus/groovy/tools/GroovyStarter.java | 48 ++-
.../codehaus/groovy/tools/LoaderConfiguration.java | 3 +-
.../java/org/codehaus/groovy/tools/RootLoader.java | 94 +++---
.../org/apache/groovy/groovysh/Groovysh.groovy | 206 ++++++------
.../groovy/groovysh/InteractiveShellRunner.groovy | 86 ++---
.../org/apache/groovy/groovysh/Interpreter.groovy | 73 +++--
.../groovy/org/apache/groovy/groovysh/Main.groovy | 17 +-
.../groovysh/util/DefaultCommandsRegistrar.groovy | 15 +-
.../groovy/groovysh/CompleterTestSupport.groovy | 37 +--
.../apache/groovy/groovysh/ErrorDisplayTest.groovy | 48 ++-
.../groovy/groovysh/ImportCompleterTest.groovy | 5 +-
.../apache/groovy/groovysh/ShellRunnerTest.groovy | 94 +++---
.../groovy/groovysh/ShellRunnerTestSupport.groovy | 34 +-
.../completion/GroovySyntaxCompleterTest.groovy | 351 ++++++++-------------
14 files changed, 486 insertions(+), 625 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/tools/GroovyStarter.java b/src/main/java/org/codehaus/groovy/tools/GroovyStarter.java
index 2dd9a596ab..fdd3491cca 100644
--- a/src/main/java/org/codehaus/groovy/tools/GroovyStarter.java
+++ b/src/main/java/org/codehaus/groovy/tools/GroovyStarter.java
@@ -19,9 +19,8 @@
package org.codehaus.groovy.tools;
import java.io.FileInputStream;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.security.PrivilegedAction;
+import java.util.Arrays;
/**
* Helper class to initialize the Groovy runtime.
@@ -33,6 +32,14 @@ public class GroovyStarter {
System.exit(1);
}
+ public static void main(String[] args) {
+ try {
+ rootLoader(args);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
public static void rootLoader(String[] args) {
String conf = System.getProperty("groovy.starter.conf",null);
final LoaderConfiguration lc = new LoaderConfiguration();
@@ -72,7 +79,7 @@ public class GroovyStarter {
break;
default:
break label;
- }
+ }
}
// this allows to override the commandline conf
@@ -84,9 +91,8 @@ public class GroovyStarter {
exit("no configuration file or main class specified");
}
- // copy arguments for main class
- String[] newArgs = new String[args.length-argsOffset];
- System.arraycopy(args, 0 + argsOffset, newArgs, 0, newArgs.length);
+ // copy arguments for main class
+ String[] mainArgs = Arrays.copyOfRange(args, argsOffset, args.length);
// load configuration file
if (conf!=null) {
try {
@@ -98,23 +104,23 @@ public class GroovyStarter {
}
// create loader and execute main class
ClassLoader loader = getLoader(lc);
- Method m=null;
+ Method m = null;
try {
- Class c = loader.loadClass(lc.getMainClass());
+ Class<?> c = loader.loadClass(lc.getMainClass());
m = c.getMethod("main", String[].class);
- } catch (ClassNotFoundException | NoSuchMethodException | SecurityException e1) {
- exit(e1);
+ } catch (ReflectiveOperationException | SecurityException e2) {
+ exit(e2);
}
try {
- m.invoke(null, new Object[]{newArgs});
- } catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException e3) {
+ m.invoke(null, new Object[]{mainArgs});
+ } catch (ReflectiveOperationException | IllegalArgumentException e3) {
exit(e3);
}
}
- @SuppressWarnings("removal") // TODO a future Groovy version should perform the operation not as a privileged action
- private static RootLoader getLoader(LoaderConfiguration lc) {
- return java.security.AccessController.doPrivileged((PrivilegedAction<RootLoader>) () -> new RootLoader(lc));
+ @SuppressWarnings("removal") // TODO: a future Groovy version should perform the operation not as a privileged action
+ private static ClassLoader getLoader(LoaderConfiguration lc) {
+ return java.security.AccessController.doPrivileged((java.security.PrivilegedAction<ClassLoader>) () -> new RootLoader(lc));
}
private static void exit(Exception e) {
@@ -122,16 +128,8 @@ public class GroovyStarter {
System.exit(1);
}
- private static void exit(String msg) {
- System.err.println(msg);
+ private static void exit(String text) {
+ System.err.println(text);
System.exit(1);
}
-
- public static void main(String[] args) {
- try {
- rootLoader(args);
- } catch (Throwable t) {
- t.printStackTrace();
- }
- }
}
diff --git a/src/main/java/org/codehaus/groovy/tools/LoaderConfiguration.java b/src/main/java/org/codehaus/groovy/tools/LoaderConfiguration.java
index 27daeea92f..4acf272ce8 100644
--- a/src/main/java/org/codehaus/groovy/tools/LoaderConfiguration.java
+++ b/src/main/java/org/codehaus/groovy/tools/LoaderConfiguration.java
@@ -19,7 +19,6 @@
package org.codehaus.groovy.tools;
import org.apache.groovy.util.SystemUtil;
-import org.codehaus.groovy.runtime.DefaultGroovyMethods;
import java.io.BufferedReader;
import java.io.File;
@@ -142,7 +141,7 @@ public class LoaderConfiguration {
if (requireMain && main == null) throw new IOException("missing main class definition in config file");
if (!configScripts.isEmpty()) {
- System.setProperty("groovy.starter.configscripts", DefaultGroovyMethods.join((Iterable)configScripts, ","));
+ System.setProperty("groovy.starter.configscripts", String.join(",", configScripts));
}
}
diff --git a/src/main/java/org/codehaus/groovy/tools/RootLoader.java b/src/main/java/org/codehaus/groovy/tools/RootLoader.java
index a47508fd46..ff8779c430 100644
--- a/src/main/java/org/codehaus/groovy/tools/RootLoader.java
+++ b/src/main/java/org/codehaus/groovy/tools/RootLoader.java
@@ -23,8 +23,8 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
+import java.util.Optional;
/**
* This ClassLoader should be used as root of class loaders. Any
@@ -73,58 +73,54 @@ import java.util.Map;
* instance will solve that problem.
*/
public class RootLoader extends URLClassLoader {
- private static final URL[] EMPTY_URL_ARRAY = new URL[0];
- private final Map<String, Class> customClasses = new HashMap<>();
+
private static final String ORG_W3C_DOM_NODE = "org.w3c.dom.Node";
+ private final Map<String, Class<?>> customClasses = new HashMap<>();
/**
- * constructs a new RootLoader without classpath
+ * Constructs a {@code RootLoader} without classpath.
*
* @param parent the parent Loader
*/
- public RootLoader(ClassLoader parent) {
- this(EMPTY_URL_ARRAY, parent);
+ public RootLoader(final ClassLoader parent) {
+ this(new URL[0], parent);
}
/**
- * constructs a new RootLoader with a parent loader and an
- * array of URLs as classpath
+ * Constructs a {@code RootLoader} with a parent loader and an array of URLs
+ * as its classpath.
*/
- public RootLoader(URL[] urls, ClassLoader parent) {
+ public RootLoader(final URL[] urls, final ClassLoader parent) {
super(urls, parent);
- // major hack here...!
+ // major hack here!!
try {
customClasses.put(ORG_W3C_DOM_NODE, super.loadClass(ORG_W3C_DOM_NODE, false));
- } catch (Exception e) { /* ignore */ }
- }
-
- private static ClassLoader chooseParent() {
- ClassLoader cl = RootLoader.class.getClassLoader();
- if (cl != null) return cl;
- return ClassLoader.getSystemClassLoader();
+ } catch (Exception e) {
+ // ignore
+ }
}
/**
- * constructs a new RootLoader with a {@link LoaderConfiguration}
- * object which holds the classpath
+ * Constructs a {@code RootLoader} with a {@link LoaderConfiguration} object
+ * which holds the classpath.
*/
- public RootLoader(LoaderConfiguration lc) {
- this(chooseParent());
+ public RootLoader(final LoaderConfiguration lc) {
+ this(Optional.ofNullable(RootLoader.class.getClassLoader()).orElseGet(ClassLoader::getSystemClassLoader));
+
Thread.currentThread().setContextClassLoader(this);
- URL[] urls = lc.getClassPathUrls();
- for (URL url : urls) {
+
+ for (URL url : lc.getClassPathUrls()) {
addURL(url);
}
// TODO M12N eventually defer this until later when we have a full Groovy
// environment and use normal Grape.grab()
String groovyHome = System.getProperty("groovy.home");
- List<String> grabUrls = lc.getGrabUrls();
- for (String grabUrl : grabUrls) {
- Map<String, Object> grabParts = GrapeUtil.getIvyParts(grabUrl);
- String group = grabParts.get("group").toString();
- String module = grabParts.get("module").toString();
- String name = grabParts.get("module").toString() + "-" + grabParts.get("version") + ".jar";
- File jar = new File(groovyHome + "/repo/" + group + "/" + module + "/jars/" + name);
+ for (String url : lc.getGrabUrls()) {
+ Map<String, Object> grabParts = GrapeUtil.getIvyParts(url);
+ String group = (String) grabParts.get("group");
+ String module = (String) grabParts.get("module");
+ String version = (String) grabParts.get("version");
+ File jar = new File(groovyHome + "/repo/" + group + "/" + module + "/jars/" + module + "-" + version + ".jar");
try {
addURL(jar.toURI().toURL());
} catch (MalformedURLException e) {
@@ -134,51 +130,53 @@ public class RootLoader extends URLClassLoader {
}
/**
- * loads a class using the name of the class
+ * {@inheritDoc}
*/
@Override
- protected synchronized Class loadClass(final String name, boolean resolve) throws ClassNotFoundException {
- Class c = this.findLoadedClass(name);
+ protected synchronized Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
+ Class<?> c = findLoadedClass(name);
if (c != null) return c;
c = customClasses.get(name);
if (c != null) return c;
try {
- c = oldFindClass(name);
- } catch (ClassNotFoundException cnfe) {
- // IGNORE
+ c = super.findClass(name);
+ } catch (ClassNotFoundException e) {
+ // ignore
}
- if (c == null) c = super.loadClass(name, resolve);
+ if (c == null)
+ c = super.loadClass(name, resolve);
- if (resolve) resolveClass(c);
+ if (resolve)
+ resolveClass(c);
return c;
}
/**
- * returns the URL of a resource, or null if it is not found
+ * {@inheritDoc}
*/
@Override
- public URL getResource(String name) {
+ public URL getResource(final String name) {
URL url = findResource(name);
- if (url == null) url = super.getResource(name);
+ if (url == null)
+ url = super.getResource(name);
return url;
}
/**
- * adds an url to the classpath of this classloader
+ * {@inheritDoc}
*/
@Override
- public void addURL(URL url) {
+ public void addURL(final URL url) {
super.addURL(url);
}
- private Class oldFindClass(String name) throws ClassNotFoundException {
- return super.findClass(name);
- }
-
+ /**
+ * {@inheritDoc}
+ */
@Override
- protected Class findClass(String name) throws ClassNotFoundException {
+ protected Class<?> findClass(final String name) throws ClassNotFoundException {
throw new ClassNotFoundException(name);
}
}
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Groovysh.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Groovysh.groovy
index 2fbcd6548a..8be4ba6795 100644
--- a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Groovysh.groovy
+++ b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Groovysh.groovy
@@ -18,7 +18,11 @@
*/
package org.apache.groovy.groovysh
+import groovy.transform.AutoFinal
+import groovy.transform.CompileDynamic
import groovy.transform.CompileStatic
+import groovy.transform.stc.ClosureParams
+import groovy.transform.stc.SimpleType
import jline.Terminal
import jline.WindowsTerminal
import jline.console.history.FileHistory
@@ -44,18 +48,19 @@ import org.fusesource.jansi.AnsiRenderer
import java.util.regex.Pattern
+import static org.codehaus.groovy.control.CompilerConfiguration.DEFAULT
+
/**
* An interactive shell for evaluating Groovy code from the command-line (aka. groovysh).
*
* The set of available commands can be modified by placing a file in the classpath named
* <code>org/codehaus/groovy/tools/shell/commands.xml</code>
*
- * See {@link XmlCommandRegistrar}
+ * @see XmlCommandRegistrar
*/
+@AutoFinal @CompileStatic
class Groovysh extends Shell {
- private static final MessageSource messages = new MessageSource(Groovysh)
-
private static final Pattern TYPEDEF_PATTERN = ~'^\\s*((?:public|protected|private|static|abstract|final)\\s+)*(?:class|enum|interface).*'
private static final Pattern METHODDEF_PATTERN = ~'^\\s*((?:public|protected|private|static|abstract|final|synchronized)\\s+)*[a-zA-Z_.]+[a-zA-Z_.<>]+\\s+[a-zA-Z_]+\\(.*'
@@ -70,6 +75,9 @@ class Groovysh extends Shell {
// after how many prefix characters we start displaying all metaclass methods
public static final String METACLASS_COMPLETION_PREFIX_LENGTH_PREFERENCE_KEY = 'meta-completion-prefix-length'
+ private static final MessageSource messages = new MessageSource(Groovysh)
+
+ //
final BufferManager buffers = new BufferManager()
@@ -86,59 +94,57 @@ class Groovysh extends Shell {
FileHistory history
- boolean historyFull // used as a workaround for GROOVY-2177
+ boolean historyFull // used as a workaround for GROOVY-2177
- String evictedLine // remembers the command which will get evicted if history is full
+ String evictedLine // remembers the command which will get evicted if history is full
PackageHelper packageHelper
+
private CompilerConfiguration configuration
- Groovysh(final ClassLoader classLoader, final Binding binding, final IO io, final Closure registrar) {
- this(classLoader, binding, io, registrar, CompilerConfiguration.DEFAULT)
+ private static Closure createDefaultRegistrar(ClassLoader classLoader) {
+ return { Groovysh groovysh ->
+ URL xmlCommandResource = groovysh.getClass().getResource('commands.xml')
+ if (xmlCommandResource != null) {
+ def registrar = new XmlCommandRegistrar(groovysh, classLoader)
+ registrar.register(xmlCommandResource)
+ } else {
+ def registrar = new DefaultCommandsRegistrar(groovysh)
+ registrar.register()
+ }
+ }
}
- Groovysh(final ClassLoader classLoader, final Binding binding, final IO io, final Closure registrar, CompilerConfiguration configuration) {
- this(classLoader, binding, io, registrar, configuration, new Interpreter(classLoader, binding, configuration))
- }
+ //--------------------------------------------------------------------------
- Groovysh(final ClassLoader classLoader, final Binding binding, final IO io, final Closure registrar, CompilerConfiguration configuration, Interpreter interpreter) {
+ Groovysh(ClassLoader classLoader, Binding binding, IO io, @ClosureParams(value=SimpleType, options='org.apache.groovy.groovysh.Groovysh') Closure registrar, CompilerConfiguration configuration, Interpreter interpreter) {
super(io)
assert classLoader
assert binding
- def actualRegistrar = registrar ?: createDefaultRegistrar(classLoader)
- parser = new Parser()
+ def theRegistrar = registrar ?: createDefaultRegistrar(classLoader)
interp = interpreter
- actualRegistrar.call(this)
- this.packageHelper = new PackageHelperImpl(classLoader)
+ parser = new Parser()
+ theRegistrar.call(this)
+ packageHelper = new PackageHelperImpl(classLoader)
this.configuration = configuration
}
- private static Closure createDefaultRegistrar(final ClassLoader classLoader) {
- return {Groovysh shell ->
- URL xmlCommandResource = getClass().getResource('commands.xml')
- if (xmlCommandResource != null) {
- def r = new XmlCommandRegistrar(shell, classLoader)
- r.register(xmlCommandResource)
- } else {
- new DefaultCommandsRegistrar(shell).register()
- }
- }
+ Groovysh(ClassLoader classLoader, Binding binding, IO io, @ClosureParams(value=SimpleType, options='org.apache.groovy.groovysh.Groovysh') Closure registrar = null, CompilerConfiguration configuration = DEFAULT) {
+ this(classLoader, binding, io, registrar, configuration, new Interpreter(classLoader, binding, configuration))
}
- Groovysh(final ClassLoader classLoader, final Binding binding, final IO io) {
- this(classLoader, binding, io, null)
- }
+ // ClassLoader,Binding,IO variants (drop left-to-right)
- Groovysh(final Binding binding, final IO io) {
- this(Thread.currentThread().contextClassLoader, binding, io)
+ Groovysh(Binding binding, IO io) {
+ this(Thread.currentThread().getContextClassLoader(), binding, io)
}
- Groovysh(final IO io) {
- this(new Binding(), io)
+ Groovysh(IO io, CompilerConfiguration cc) {
+ this(Thread.currentThread().getContextClassLoader(), new Binding(), io, null, cc)
}
- Groovysh(final IO io, CompilerConfiguration configuration) {
- this(Thread.currentThread().contextClassLoader, new Binding(), io, null, configuration)
+ Groovysh(IO io) {
+ this(new Binding(), io)
}
Groovysh() {
@@ -153,11 +159,11 @@ class Groovysh extends Shell {
* Execute a single line, where the line may be a command or Groovy code (complete or incomplete).
*/
@Override
- Object execute(final String line) {
+ Object execute(String line) {
assert line != null
// Ignore empty lines
- if (line.trim().size() == 0) {
+ if (line.trim().isEmpty()) {
return null
}
@@ -178,7 +184,7 @@ class Groovysh extends Shell {
}
// Otherwise treat the line as Groovy
- List<String> current = new ArrayList<String>(buffers.current())
+ List<String> current = new ArrayList<>(buffers.current())
// Append the line to the current buffer
current << line
@@ -242,7 +248,6 @@ class Groovysh extends Shell {
return result
}
- @CompileStatic
private boolean isIncompleteCaseOfAntlr4(MultipleCompilationErrorsException t) {
// TODO antlr4 parser errors pop out here - can we rework to be like antlr2?
(
@@ -259,16 +264,15 @@ class Groovysh extends Shell {
* @param strings
* @return
*/
- @CompileStatic
- static boolean isTypeOrMethodDeclaration(final List<String> buffer) {
- final String joined = buffer.join('')
+ static boolean isTypeOrMethodDeclaration(List<String> buffer) {
+ String joined = buffer.join('')
return joined.matches(TYPEDEF_PATTERN) || joined.matches(METHODDEF_PATTERN)
}
/*
* to simulate an interpreter mode, this method wraps the statements into a try/finally block that
* stores bound variables like unbound variables
*/
- private Object evaluateWithStoredBoundVars(String importsSpec, final List<String> current) {
+ private Object evaluateWithStoredBoundVars(String importsSpec, List<String> current) {
Object result
String variableBlocks = null
// To make groovysh behave more like an interpreter, we need to retrieve all bound
@@ -294,23 +298,21 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
setLastResult(result = interp.evaluate(buff))
if (variableBlocks) {
- Map<String, Object> boundVarValues = interp.context.getVariable(COLLECTED_BOUND_VARS_MAP_VARNAME)
+ def boundVarValues = (Map<String, Object>) interp.context.getVariable(COLLECTED_BOUND_VARS_MAP_VARNAME)
boundVarValues.each({ String name, Object value -> interp.context.setVariable(name, value) })
}
return result
}
-
-
- protected Object executeCommand(final String line) {
+ protected Object executeCommand(String line) {
return super.execute(line)
}
/**
* Display the given buffer.
*/
- void displayBuffer(final List buffer) {
+ void displayBuffer(List buffer) {
assert buffer
buffer.eachWithIndex { line, index ->
@@ -328,16 +330,15 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
// Prompt
//
- private final AnsiRenderer prompt = new AnsiRenderer()
-
- /*
- Builds the command prompt name in 1 of 3 ways:
- 1. Checks the groovysh.prompt property passed into groovysh script. -Dgroovysh.prompt="hello"
- 2. Checks an environment variable called GROOVYSH_PROMPT. export GROOVYSH_PROMPT
- 3. If no value is defined returns the default groovy shell prompt.
-
- The code will always assume you want the line number in the prompt. To implement differently overhead the render
- prompt variable.
+ /**
+ * Builds the command prompt name in 1 of 3 ways:
+ * <ol>
+ * <li>Checks the groovysh.prompt property passed into groovysh script: {@code -Dgroovysh.prompt="hello"}
+ * <li>Checks an environment variable called GROOVYSH_PROMPT: {@code export GROOVYSH_PROMPT}
+ * <li>If no value is defined returns the default groovy shell prompt.
+ * </ol>
+ * The code will always assume you want the line number in the prompt. To
+ * implement differently overhead the render prompt variable.
*/
private String buildPrompt() {
def lineNum = formatLineNumber(buffers.current().size())
@@ -377,13 +378,13 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
}
String renderPrompt() {
- return prompt.render( buildPrompt() )
+ return AnsiRenderer.render(buildPrompt())
}
/**
* Format the given number suitable for rendering as a line number column.
*/
- protected String formatLineNumber(final int num) {
+ protected String formatLineNumber(int num) {
assert num >= 0
// Make a %03d-like string for the line number
@@ -401,29 +402,25 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
}
/**
- * Loads file from within user groovy state directory
- * @param filename
+ * Loads file from within user groovy state directory.
*/
- protected void loadUserScript(final String filename) {
+ @CompileDynamic
+ protected void loadUserScript(String filename) {
assert filename
- File file = new File(getUserStateDirectory(), filename)
-
+ def file = new File(getUserStateDirectory(), filename)
if (file.exists()) {
- Command command = registry[LoadCommand.COMMAND_NAME] as Command
-
+ def command = registry[LoadCommand.COMMAND_NAME] as Command
if (command) {
log.debug("Loading user-script: $file")
// Disable the result hook for profile scripts
def previousHook = resultHook
resultHook = { result -> /* nothing */}
-
try {
command.load(file.toURI().toURL())
}
finally {
- // Restore the result hook
resultHook = previousHook
}
} else {
@@ -436,30 +433,30 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
// Recording
//
- protected void maybeRecordInput(final String line) {
- RecordCommand record = registry[RecordCommand.COMMAND_NAME]
-
+ protected void maybeRecordInput(String line) {
+ def record = (RecordCommand) registry[RecordCommand.COMMAND_NAME]
if (record != null) {
record.recordInput(line)
}
}
- protected void maybeRecordResult(final Object result) {
- RecordCommand record = registry[RecordCommand.COMMAND_NAME]
-
+ protected void maybeRecordResult(Object result) {
+ def record = (RecordCommand) registry[RecordCommand.COMMAND_NAME]
if (record != null) {
record.recordResult(result)
}
}
protected void maybeRecordError(Throwable cause) {
- RecordCommand record = registry[RecordCommand.COMMAND_NAME]
-
+ def record = (RecordCommand) registry[RecordCommand.COMMAND_NAME]
if (record != null) {
+ Throwable error
if (getPreference(SANITIZE_PREFERENCE_KEY, 'false')) {
- cause = StackTraceUtils.deepSanitize(cause)
+ error = StackTraceUtils.deepSanitize(cause)
+ } else {
+ error = cause
}
- record.recordError(cause)
+ record.recordError(error)
}
}
@@ -467,7 +464,7 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
// Hooks
//
- final Closure defaultResultHook = {Object result ->
+ final Closure defaultResultHook = { Object result ->
boolean showLastResult = !io.quiet && (io.verbose || getPreference(SHOW_LAST_RESULT_PREFERENCE_KEY, 'false'))
if (showLastResult) {
// avoid String.valueOf here because it bypasses pretty-printing of Collections,
@@ -478,7 +475,7 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
Closure resultHook = defaultResultHook
- private void setLastResult(final Object result) {
+ private void setLastResult(Object result) {
if (resultHook == null) {
throw new IllegalStateException('Result hook is not set')
}
@@ -502,7 +499,7 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
Writer data = new org.apache.groovy.io.StringBuilderWriter()
PrintWriter writer = new PrintWriter(data)
ErrorCollector collector = ((MultipleCompilationErrorsException) cause).getErrorCollector()
- Iterator<Message> msgIterator = collector.getErrors().iterator()
+ Iterator<? extends Message> msgIterator = collector.getErrors().iterator()
while (msgIterator.hasNext()) {
Message errorMsg = msgIterator.next()
errorMsg.write(writer)
@@ -514,7 +511,6 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
} else {
io.err.println("@|bold,red ${cause.message}|@")
-
maybeRecordError(cause)
if (log.debug) {
@@ -523,13 +519,8 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
}
else {
boolean sanitize = getPreference(SANITIZE_PREFERENCE_KEY, 'false')
-
// Sanitize the stack trace unless we are in verbose mode, or the user has request otherwise
- if (!io.verbose && sanitize) {
- cause = StackTraceUtils.deepSanitize(cause)
- }
-
- def trace = cause.stackTrace
+ def trace = (sanitize && !io.verbose ? StackTraceUtils.deepSanitize(cause) : cause).stackTrace
def buff = new StringBuilder()
@@ -565,13 +556,13 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
}
// protected for mocking in tests
- protected String getPreference(final String key, final String theDefault) {
+ protected String getPreference(String key, String theDefault) {
return Preferences.get(key, theDefault)
}
Closure errorHook = defaultErrorHook
- private void displayError(final Throwable cause) {
+ private void displayError(Throwable cause) {
if (errorHook == null) {
throw new IllegalStateException('Error hook is not set')
}
@@ -586,38 +577,36 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
}
/**
- * Run Interactive Shell with optional initial script and files to load
+ * Run the Interactive Shell with optional initial script and files to load.
*/
- int run(final String evalString, final List<String> filenames) {
+ int run(String evalString, List<String> filenames) {
List<String> startCommands = []
-
- if (evalString != null && evalString.trim().size() > 0) {
+ if (evalString?.trim()) {
startCommands.add(evalString)
}
- if (filenames != null && filenames.size() > 0) {
- startCommands.addAll(filenames.collect({String it -> "${LoadCommand.COMMAND_NAME} $it"}))
+ if (filenames) {
+ filenames.each {
+ startCommands.add("${LoadCommand.COMMAND_NAME} $it".toString())
+ }
}
return run(startCommands.join('\n'))
}
/**
- * Run Interactive Shell with initial command
+ * Run the Interactive Shell with initial command.
*/
- int run(final String commandLine) {
+ int run(String commandLine) {
def code
-
try {
loadUserScript('groovysh.profile')
loadUserScript('groovysh.rc')
// Setup the interactive runner
- runner = new InteractiveShellRunner(
- this,
- this.&renderPrompt as Closure)
+ runner = new InteractiveShellRunner(this, this.&renderPrompt)
// if args were passed in, just execute as a command
// (but cygwin gives an empty string, so ignore that)
- if (commandLine != null && commandLine.trim().size() > 0) {
+ if (commandLine?.trim()) {
runner.wrappedInputStream.insert(commandLine + '\n')
}
@@ -634,18 +623,14 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
// And let 'er rip... :-)
runner.run()
-
code = 0
} catch (ExitNotification n) {
- log.debug("Exiting w/code: ${n.code}")
-
code = n.code
- }
- catch (Throwable t) {
+ log.debug("Exiting w/code: $code")
+ } catch (Throwable t) {
+ code = 1
io.err.println(messages.format('info.fatal', t))
t.printStackTrace(io.err)
-
- code = 1
}
assert code != null // This should never happen
@@ -653,7 +638,6 @@ try {$COLLECTED_BOUND_VARS_MAP_VARNAME[\"$varname\"] = $varname;
return code
}
-
/**
* maybe displays log information and a welcome message
* @param term
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/InteractiveShellRunner.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/InteractiveShellRunner.groovy
index 4ba5004f58..d5bea2bcf3 100644
--- a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/InteractiveShellRunner.groovy
+++ b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/InteractiveShellRunner.groovy
@@ -18,6 +18,9 @@
*/
package org.apache.groovy.groovysh
+import groovy.transform.AutoFinal
+import groovy.transform.CompileDynamic
+import groovy.transform.CompileStatic
import jline.console.ConsoleReader
import jline.console.completer.AggregateCompleter
import jline.console.completer.CandidateListCompletionHandler
@@ -33,58 +36,55 @@ import org.codehaus.groovy.tools.shell.util.Preferences
/**
* Support for running a {@link Shell} interactively using the JLine library.
*/
+@AutoFinal @CompileStatic
class InteractiveShellRunner extends ShellRunner implements Runnable {
- ConsoleReader reader
+ ConsoleReader reader
final Closure prompt
-
final CommandsMultiCompleter completer
- WrappedInputStream wrappedInputStream
+ WrappedInputStream wrappedInputStream
- InteractiveShellRunner(final Groovysh shell, final Closure prompt) {
+ @CompileDynamic
+ InteractiveShellRunner(Groovysh shell, Closure prompt) {
super(shell)
this.prompt = prompt
this.wrappedInputStream = new WrappedInputStream(shell.io.inputStream)
this.reader = new ConsoleReader(wrappedInputStream, shell.io.outputStream)
- CompletionHandler currentCompletionHandler = this.reader.getCompletionHandler()
+ CompletionHandler currentCompletionHandler = reader.getCompletionHandler()
if (currentCompletionHandler instanceof CandidateListCompletionHandler) {
- // have to downcast because methods not part of the interface
- ((CandidateListCompletionHandler) currentCompletionHandler).setStripAnsi(true)
- ((CandidateListCompletionHandler) currentCompletionHandler).setPrintSpaceAfterFullCompletion(false)
+ currentCompletionHandler.setStripAnsi(true)
+ currentCompletionHandler.setPrintSpaceAfterFullCompletion(false)
}
-
// expand events ia an advanced feature of JLine that clashes with Groovy syntax (e.g. invoke "2!=3")
- this.reader.expandEvents = false
-
+ reader.expandEvents = false
// complete groovysh commands, display, import, ... as first word in line
- this.completer = new CommandsMultiCompleter()
- reader.addCompleter(this.completer)
+ completer = new CommandsMultiCompleter()
def reflectionCompleter = new org.apache.groovy.groovysh.completion.antlr4.ReflectionCompleter(shell)
def classnameCompleter = new org.apache.groovy.groovysh.completion.antlr4.CustomClassSyntaxCompleter(shell)
- def identifierCompleters = [
- new org.apache.groovy.groovysh.completion.antlr4.KeywordSyntaxCompleter(),
- new org.apache.groovy.groovysh.completion.antlr4.VariableSyntaxCompleter(shell),
- classnameCompleter,
- new org.apache.groovy.groovysh.completion.antlr4.ImportsSyntaxCompleter(shell),
+ List<org.apache.groovy.groovysh.completion.antlr4.IdentifierCompleter> identifierCompleters = [
+ new org.apache.groovy.groovysh.completion.antlr4.KeywordSyntaxCompleter(),
+ new org.apache.groovy.groovysh.completion.antlr4.VariableSyntaxCompleter(shell),
+ classnameCompleter,
+ new org.apache.groovy.groovysh.completion.antlr4.ImportsSyntaxCompleter(shell)
]
def filenameCompleter = new FileNameCompleter(false)
- def completerArgs = [shell, reflectionCompleter, classnameCompleter, identifierCompleters, filenameCompleter]
-
- reader.addCompleter(new org.apache.groovy.groovysh.completion.antlr4.GroovySyntaxCompleter(*completerArgs))
+ reader.addCompleter(completer)
+ reader.addCompleter(new org.apache.groovy.groovysh.completion.antlr4.GroovySyntaxCompleter(
+ shell, reflectionCompleter, classnameCompleter, identifierCompleters, filenameCompleter))
}
@Override
void run() {
- for (Command command in shell.registry.commands()) {
+ for (command in shell.registry.commands()) {
completer.add(command)
}
@@ -96,20 +96,7 @@ class InteractiveShellRunner extends ShellRunner implements Runnable {
super.run()
}
- void setHistory(final FileHistory history) {
- reader.history = history
- def dir = history.file.parentFile
-
- if (!dir.exists()) {
- dir.mkdirs()
-
- log.debug("Created base directory for history file: $dir")
- }
-
- log.debug("Using history file: $history.file")
- }
-
- @Override
+ @Override @CompileDynamic
protected String readLine() {
try {
if (Boolean.valueOf(Preferences.get(Groovysh.AUTOINDENT_PREFERENCE_KEY))) {
@@ -144,8 +131,8 @@ class InteractiveShellRunner extends ShellRunner implements Runnable {
// we save the evicted line in case someone wants to use it with history recall
if (shell instanceof Groovysh) {
def history = shell.history
- shell.historyFull = (history != null) && (history.size() >= history.maxSize)
- if (shell.historyFull) {
+ shell.historyFull = history != null && history.size() >= history.maxSize
+ if (shell.isHistoryFull()) {
def first = history.first()
if (first) {
shell.evictedLine = first.value()
@@ -154,20 +141,33 @@ class InteractiveShellRunner extends ShellRunner implements Runnable {
}
}
+ void setHistory(FileHistory history) {
+ reader.history = history
+ def dir = history.file.parentFile
+
+ if (!dir.exists()) {
+ dir.mkdirs()
+
+ log.debug("Created base directory for history file: $dir")
+ }
+
+ log.debug("Using history file: $history.file")
+ }
}
/**
* Completer for interactive shells.
*/
-class CommandsMultiCompleter
- extends AggregateCompleter {
- protected final Logger log = Logger.create(this.class)
+@AutoFinal @CompileStatic
+class CommandsMultiCompleter extends AggregateCompleter {
+
+ protected final Logger log = Logger.create(getClass())
List<Completer> list = []
private boolean dirty
- def add(final Command command) {
+ def add(Command command) {
assert command
//
@@ -194,7 +194,7 @@ class CommandsMultiCompleter
}
@Override
- int complete(final String buffer, final int pos, final List cand) {
+ int complete(String buffer, int pos, List cand) {
assert buffer != null
//
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Interpreter.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Interpreter.groovy
index cc21a239fb..ac3cc4a430 100644
--- a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Interpreter.groovy
+++ b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Interpreter.groovy
@@ -18,63 +18,67 @@
*/
package org.apache.groovy.groovysh
+import groovy.transform.AutoFinal
+import groovy.transform.CompileDynamic
+import groovy.transform.CompileStatic
import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.runtime.FormatHelper
+import org.codehaus.groovy.runtime.InvokerHelper
import org.codehaus.groovy.runtime.MethodClosure
import org.codehaus.groovy.tools.shell.util.Logger
-import java.lang.reflect.Method
+interface Evaluator {
+ Object evaluate(Collection<String> strings)
+}
/**
* Helper to interpret a source buffer.
*/
-class Interpreter implements Evaluator
-{
- static final String SCRIPT_FILENAME = 'groovysh_evaluate'
+@AutoFinal @CompileStatic
+class Interpreter implements Evaluator {
- private final Logger log = Logger.create(this.class)
+ protected static final String SCRIPT_FILENAME = 'groovysh_evaluate'
- private final GroovyShell shell
+ private final Logger log = Logger.create(getClass())
- Interpreter(final ClassLoader classLoader, final Binding binding) {
- this(classLoader, binding, CompilerConfiguration.DEFAULT)
- }
+ private final GroovyShell shell
- Interpreter(final ClassLoader classLoader, final Binding binding, CompilerConfiguration configuration) {
+ Interpreter(ClassLoader classLoader, Binding binding, CompilerConfiguration configuration = CompilerConfiguration.DEFAULT) {
assert classLoader
assert binding
shell = new GroovyShell(classLoader, binding, configuration)
}
+ GroovyClassLoader getClassLoader() {
+ return shell.getClassLoader()
+ }
+
Binding getContext() {
// GROOVY-9584: leave as call to getter not property access to avoid potential context variable in binding
return shell.getContext()
}
- GroovyClassLoader getClassLoader() {
- return shell.classLoader
- }
-
GroovyShell getShell() {
return shell
}
- @Override
- def evaluate(final Collection<String> buffer) {
+ //--------------------------------------------------------------------------
+
+ @Override @CompileDynamic
+ Object evaluate(Collection<String> buffer) {
assert buffer
- def source = buffer.join(Parser.NEWLINE)
+ String source = buffer.join(Parser.NEWLINE)
- def result
+ Object result = null
- Class type
+ Class type = null
try {
- Script script = shell.parse(source, SCRIPT_FILENAME)
- type = script.getClass()
-
+ type = shell.parseClass(new GroovyCodeSource(source, SCRIPT_FILENAME, GroovyShell.DEFAULT_CODE_BASE))
+ Script script = InvokerHelper.createScript(type, context)
log.debug("Compiled script: $script")
- if (type.declaredMethods.any {Method it -> it.name == 'main' }) {
+ if (type.getDeclaredMethods().any { it.name == 'main' }) {
result = script.run()
}
@@ -82,28 +86,23 @@ class Interpreter implements Evaluator
log.debug("Evaluation result: ${FormatHelper.toString(result)} (${result?.getClass()})")
// Keep only the methods that have been defined in the script
- type.declaredMethods.each { Method m ->
- if (!(m.name in [ 'main', 'run' ] || m.name.startsWith('super$') || m.name.startsWith('class$') || m.name.startsWith('$'))) {
- log.debug("Saving method definition: $m.name")
-
- context["${m.name}"] = new MethodClosure(type.newInstance(), m.name)
+ type.getDeclaredMethods().each { m ->
+ String name = m.name
+ if (!(name == 'main' || name == 'run' || name.startsWith('super$') || name.startsWith('class$') || name.startsWith('$'))) {
+ log.debug("Saving script method definition: $name")
+ context[name] = new MethodClosure(script, name)
}
}
- }
- finally {
- // Remove the script class generated
+ } finally {
+ // Remove the generated script class
if (type?.name) {
- classLoader.removeClassCacheEntry(type?.name)
+ classLoader.removeClassCacheEntry(type.name)
}
- // Remove the inline closures from the cache as well
+ // Remove the inline closures as well
classLoader.removeClassCacheEntry('$_run_closure')
}
return result
}
}
-
-interface Evaluator {
- def evaluate(final Collection<String> buffer)
-}
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Main.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Main.groovy
index 705213e198..922dcd15aa 100644
--- a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Main.groovy
+++ b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Main.groovy
@@ -20,6 +20,7 @@ package org.apache.groovy.groovysh
import groovy.cli.internal.CliBuilderInternal
import groovy.cli.internal.OptionAccessor
+import groovy.transform.AutoFinal
import groovy.transform.CompileDynamic
import groovy.transform.CompileStatic
import jline.TerminalFactory
@@ -49,7 +50,7 @@ import static org.apache.groovy.util.SystemUtil.setSystemPropertyFrom
*
* Main CLI entry-point for <tt>groovysh</tt>.
*/
-@CompileStatic
+@AutoFinal @CompileStatic
class Main {
final Groovysh groovysh
@@ -74,7 +75,7 @@ class Main {
* @param main must have a Groovysh member that has an IO member.
*/
@CompileDynamic
- static void main(final String[] args) {
+ static void main(String[] args) {
MessageSource messages = new MessageSource(Main)
def cli = new CliBuilderInternal(usage: 'groovysh [options] [...]', stopAtNonOption: false,
header: messages['cli.option.header'])
@@ -153,10 +154,13 @@ class Main {
if (options.e) {
evalString = options.getOptionValue('e')
}
- def configuration = new CompilerConfiguration(System.getProperties())
- configuration.setParameters((boolean) options.hasOption("pa"))
- List<String> filenames = options.arguments()
+ start(io, evalString, options.arguments(), options.hasOption('pa'))
+ }
+
+ private static void start(IO io, String evalString, List<String> filenames, boolean parameters) {
+ def configuration = new CompilerConfiguration(System.getProperties())
+ configuration.setParameters(parameters)
Main main = new Main(io, configuration)
main.startGroovysh(evalString, filenames)
}
@@ -207,6 +211,7 @@ class Main {
* @param type: one of 'auto', 'unix', ('win', 'windows'), ('false', 'off', 'none')
* @param suppressColor only has effect when ansi is enabled
*/
+ @AutoFinal(enabled=false)
static void setTerminalType(String type, boolean suppressColor) {
assert type != null
@@ -260,7 +265,7 @@ class Main {
}
@Deprecated
- static void setSystemProperty(final String nameValue) {
+ static void setSystemProperty(String nameValue) {
setSystemPropertyFrom(nameValue)
}
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/util/DefaultCommandsRegistrar.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/util/DefaultCommandsRegistrar.groovy
index 9fc9ef430c..522fe10bdf 100644
--- a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/util/DefaultCommandsRegistrar.groovy
+++ b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/util/DefaultCommandsRegistrar.groovy
@@ -40,11 +40,7 @@ import org.apache.groovy.groovysh.commands.SetCommand
import org.apache.groovy.groovysh.commands.ShowCommand
/**
- * Registers {@link Command} classes from an XML file like:
- * <commands>
- * <command>org.apache.groovy.groovysh.commands.HelpCommand</command>
- * ...
- * </commands>
+ * Registers default {@link Command} instances.
*/
class DefaultCommandsRegistrar {
@@ -52,12 +48,11 @@ class DefaultCommandsRegistrar {
DefaultCommandsRegistrar(final Shell shell) {
assert shell != null
-
this.shell = shell
}
void register() {
- def commands = [
+ List<Command> commands = [
new HelpCommand(shell),
new ExitCommand(shell),
new ImportCommand(shell),
@@ -77,12 +72,12 @@ class DefaultCommandsRegistrar {
new RegisterCommand(shell),
]
- if (!System.getProperty("groovysh.disableDocCommand")?.toBoolean()) {
+ if (!Boolean.getBoolean('groovysh.disableDocCommand')) {
commands.add(new DocCommand(shell))
}
- for (Command classname in commands) {
- shell.register(classname)
+ for (command in commands) {
+ shell.register(command)
}
}
}
diff --git a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/CompleterTestSupport.groovy b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/CompleterTestSupport.groovy
index 45dc56e6f0..f173dc633c 100644
--- a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/CompleterTestSupport.groovy
+++ b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/CompleterTestSupport.groovy
@@ -20,48 +20,39 @@ package org.apache.groovy.groovysh
import groovy.mock.interceptor.MockFor
import groovy.test.GroovyTestCase
-import org.codehaus.groovy.tools.shell.IO
import org.apache.groovy.groovysh.completion.antlr4.IdentifierCompleter
import org.apache.groovy.groovysh.completion.antlr4.ReflectionCompleter
-import org.apache.groovy.groovysh.util.PackageHelper
import org.apache.groovy.groovysh.util.PackageHelperImpl
+import org.codehaus.groovy.tools.shell.IO
abstract class CompleterTestSupport extends GroovyTestCase {
- BufferManager bufferManager = new BufferManager()
- IO testio
ByteArrayOutputStream mockOut
ByteArrayOutputStream mockErr
- MockFor groovyshMocker
- MockFor packageHelperMocker
- PackageHelper mockPackageHelper
+ IO testio
+
MockFor reflectionCompleterMocker
+ MockFor packageHelperMocker
MockFor idCompleterMocker
+ MockFor groovyshMocker
@Override
- void setUp() {
+ protected void setUp() {
super.setUp()
mockOut = new ByteArrayOutputStream()
mockErr = new ByteArrayOutputStream()
testio = new IO(new ByteArrayInputStream(), mockOut, mockErr)
+
reflectionCompleterMocker = new MockFor(ReflectionCompleter)
+ packageHelperMocker = new MockFor(PackageHelperImpl)
idCompleterMocker = new MockFor(IdentifierCompleter)
groovyshMocker = new MockFor(Groovysh)
- groovyshMocker.demand.getClass(0..1) { Groovysh }
- groovyshMocker.demand.createDefaultRegistrar { { shell -> null } }
- groovyshMocker.demand.getIo(0..2) { testio }
- packageHelperMocker = new MockFor(PackageHelperImpl)
- def registry = new CommandRegistry()
- groovyshMocker.demand.getRegistry(0..1) { registry }
- packageHelperMocker.demand.getContents(6) { ['java', 'test'] }
- groovyshMocker.demand.getIo(0..2) { testio }
- for (i in 1..19) {
- groovyshMocker.demand.getIo(0..1) { testio }
- groovyshMocker.demand.add(0..1) {}
- groovyshMocker.demand.getIo(0..1) { testio }
- }
- groovyshMocker.demand.getRegistry(0..1) { registry }
- groovyshMocker.demand.getBuffers(0..2) { bufferManager }
+ // no-arg constructor
+ groovyshMocker.demand.getClass( 1) { Groovysh }
+ groovyshMocker.demand.getIo(0..21) { testio }
+ groovyshMocker.demand.register(18) { it }
+ // new command
+ groovyshMocker.demand.getIo( 0..3) { testio }
}
}
diff --git a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/ErrorDisplayTest.groovy b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/ErrorDisplayTest.groovy
index 25717f8b32..9bb8ce7d19 100644
--- a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/ErrorDisplayTest.groovy
+++ b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/ErrorDisplayTest.groovy
@@ -18,55 +18,43 @@
*/
package org.apache.groovy.groovysh
-import jline.console.ConsoleReader
import jline.console.completer.CandidateListCompletionHandler
class ErrorDisplayTest extends ShellRunnerTestSupport {
void testInput() {
- readerStubber.demand.readLine { 'foo' }
+ readerStubber.demand.readLine {'foo'}
readerStubber.demand.getCompletionHandler {new CandidateListCompletionHandler()}
- shellMocker.use {
- readerStubber.use {
- Groovysh shellMock = new Groovysh()
- ConsoleReader readerStub = new ConsoleReader()
-
- InteractiveShellRunner shellRunner = new InteractiveShellRunner(shellMock, { '>' })
- shellRunner.reader = readerStub
- // assert no exception
+ readerStubber.use {
+ shellMocker.use {
+ def shellRunner = new InteractiveShellRunner(new Groovysh(), {'>'})
shellRunner.run()
+ // no exception
}
}
}
void testError() {
- readerStubber.demand.readLine { throw new StringIndexOutOfBoundsException() }
+ readerStubber.demand.readLine {throw new StringIndexOutOfBoundsException()}
readerStubber.demand.getCompletionHandler {new CandidateListCompletionHandler()}
- shellMocker.use {
- readerStubber.use {
- Groovysh shellMock = new Groovysh()
- ConsoleReader readerStub = new ConsoleReader()
-
- InteractiveShellRunner shellRunner = new InteractiveShellRunner(shellMock, { '>' })
- shellRunner.reader = readerStub
- // assert no exception
+ readerStubber.use {
+ shellMocker.use {
+ def shellRunner = new InteractiveShellRunner(new Groovysh(), {'>'})
shellRunner.run()
+ // no exception
}
}
}
void testError2() {
- readerStubber.demand.readLine { throw new Throwable('MockException') }
+ readerStubber.demand.readLine {throw new Throwable('MockException')}
readerStubber.demand.getCompletionHandler {new CandidateListCompletionHandler()}
- shellMocker.use { readerStubber.use {
- Groovysh shellMock = new Groovysh()
- ConsoleReader readerStub = new ConsoleReader()
-
- InteractiveShellRunner shellRunner = new InteractiveShellRunner(shellMock, {'>'})
- shellRunner.reader = readerStub
- // assert no exception
- shellRunner.run()
- }}
+ readerStubber.use {
+ shellMocker.use {
+ def shellRunner = new InteractiveShellRunner(new Groovysh(), {'>'})
+ shellRunner.run()
+ // no exception
+ }
+ }
}
-
}
diff --git a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/ImportCompleterTest.groovy b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/ImportCompleterTest.groovy
index f052999f2f..de1bc1d9c2 100644
--- a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/ImportCompleterTest.groovy
+++ b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/ImportCompleterTest.groovy
@@ -20,8 +20,11 @@ package org.apache.groovy.groovysh
import jline.console.completer.Completer
import org.apache.groovy.groovysh.commands.ImportCommand
+import org.apache.groovy.groovysh.util.PackageHelper
-class ImportCompleterTest extends CompleterTestSupport {
+final class ImportCompleterTest extends CompleterTestSupport {
+
+ private PackageHelper mockPackageHelper
void testEmpty() {
mockPackageHelper = new MockPackageHelper(['java', 'test'])
diff --git a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/ShellRunnerTest.groovy b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/ShellRunnerTest.groovy
index 6ec455a8df..a54e9e9889 100644
--- a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/ShellRunnerTest.groovy
+++ b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/ShellRunnerTest.groovy
@@ -28,43 +28,49 @@ import org.codehaus.groovy.tools.shell.util.Preferences
class ShellRunnerTest extends GroovyTestCase {
private Groovysh groovysh
+ private MockFor readerMocker
@Override
- void setUp() {
+ protected void setUp() {
super.setUp()
ByteArrayOutputStream mockOut = new ByteArrayOutputStream()
ByteArrayOutputStream mockErr = new ByteArrayOutputStream()
+ IO testio = new IO(new ByteArrayInputStream(), mockOut, mockErr)
- IO testio = new IO(new ByteArrayInputStream(),
- mockOut,
- mockErr)
groovysh = new Groovysh(testio)
+
+ readerMocker = new MockFor(ConsoleReader)
+ readerMocker.demand.getCompletionHandler(1) {new CandidateListCompletionHandler(stripAnsi: true)}
+ readerMocker.demand.setExpandEvents {}
+ readerMocker.demand.addCompleter(2) {}
}
+ //--------------------------------------------------------------------------
+
void testReadLineIndentPreferenceOff() {
groovysh.buffers.buffers.add(['Foo {'])
groovysh.buffers.select(1)
- MockFor readerMocker = primedMockForConsoleReader()
- readerMocker.demand.readLine(1) {'Foo {'}
- MockFor preferencesMocker = new MockFor(Preferences)
+ def preferencesMocker = new MockFor(Preferences)
preferencesMocker.demand.get(1) {'false'}
- preferencesMocker.use {readerMocker.use {
- InteractiveShellRunner runner = new InteractiveShellRunner(groovysh, {'>'})
+ readerMocker.demand.readLine(1) {'Foo {'}
+ preferencesMocker.use { readerMocker.use {
+ def runner = new InteractiveShellRunner(groovysh, {'>'})
runner.readLine()
- assertEquals(0, runner.wrappedInputStream.inserted.available())
+
+ assert runner.wrappedInputStream.inserted.available() == 0
}}
}
void testReadLineIndentNone() {
- MockFor readerMocker = primedMockForConsoleReader()
- readerMocker.demand.readLine(1) {'Foo {'}
- MockFor preferencesMocker = new MockFor(Preferences)
+ def preferencesMocker = new MockFor(Preferences)
preferencesMocker.demand.get(1) {'true'}
- preferencesMocker.use {readerMocker.use {
- InteractiveShellRunner runner = new InteractiveShellRunner(groovysh, {'>'})
+ readerMocker.demand.readLine(1) {'Foo {'}
+ preferencesMocker.use { readerMocker.use {
+ def runner = new InteractiveShellRunner(groovysh, {'>'})
runner.readLine()
- assertEquals(0, runner.wrappedInputStream.inserted.available())
+
+ assert runner.wrappedInputStream.inserted.available() == 0
}}
}
@@ -72,66 +78,54 @@ class ShellRunnerTest extends GroovyTestCase {
groovysh.buffers.buffers.add(['Foo {'])
groovysh.buffers.select(1)
- MockFor readerMocker = primedMockForConsoleReader()
- readerMocker.demand.readLine(1) {'Foo {'}
- MockFor preferencesMocker = new MockFor(Preferences)
+ def preferencesMocker = new MockFor(Preferences)
preferencesMocker.demand.get(1) {'true'}
- preferencesMocker.use {readerMocker.use {
- InteractiveShellRunner runner = new InteractiveShellRunner(groovysh, {'>'})
+ readerMocker.demand.readLine(1) {'Foo {'}
+ preferencesMocker.use { readerMocker.use {
+ def runner = new InteractiveShellRunner(groovysh, {'>'})
runner.readLine()
- assertEquals(groovysh.indentSize, runner.wrappedInputStream.inserted.available())
+
+ assert runner.wrappedInputStream.inserted.available() == groovysh.indentSize
}}
}
void testReadLineIndentTwo() {
groovysh.buffers.buffers.add(['Foo { {'])
groovysh.buffers.select(1)
- MockFor readerMocker = primedMockForConsoleReader()
- readerMocker.demand.readLine(1) {'Foo { {'}
- MockFor preferencesMocker = new MockFor(Preferences)
+
+ def preferencesMocker = new MockFor(Preferences)
preferencesMocker.demand.get(1) {'true'}
- preferencesMocker.use {readerMocker.use {
- InteractiveShellRunner runner = new InteractiveShellRunner(groovysh, {'>'})
+ readerMocker.demand.readLine(1) {'Foo { {'}
+ preferencesMocker.use { readerMocker.use {
+ def runner = new InteractiveShellRunner(groovysh, {'>'})
runner.readLine()
- assertEquals(groovysh.indentSize * 2, runner.wrappedInputStream.inserted.available())
- }}
- }
- private MockFor primedMockForConsoleReader() {
- def readerMocker = new MockFor(ConsoleReader)
- CandidateListCompletionHandler clch = new CandidateListCompletionHandler()
- clch.stripAnsi = true
- readerMocker.demand.getCompletionHandler(1) {clch}
- readerMocker.demand.setExpandEvents {}
- readerMocker.demand.addCompleter(2) {}
- readerMocker
+ assert runner.wrappedInputStream.inserted.available() == groovysh.indentSize * 2
+ }}
}
}
class ShellRunnerTest2 extends GroovyTestCase {
void testReadLinePaste() {
- ByteArrayOutputStream mockOut = new ByteArrayOutputStream()
- ByteArrayOutputStream mockErr = new ByteArrayOutputStream()
-
- IO testio = new IO(new ByteArrayInputStream('Some Clipboard Content'.bytes),
- mockOut,
- mockErr)
- Groovysh groovysh = new Groovysh(testio)
+ Groovysh groovysh = new Groovysh(new IO(new ByteArrayInputStream('Some Clipboard Content'.bytes),
+ new ByteArrayOutputStream(), new ByteArrayOutputStream()))
groovysh.buffers.buffers.add(['Foo { {'])
groovysh.buffers.select(1)
+ MockFor preferencesMocker = new MockFor(Preferences)
+ preferencesMocker.demand.get(1) {'true'}
MockFor readerMocker = new MockFor(ConsoleReader)
readerMocker.demand.getCompletionHandler {new CandidateListCompletionHandler()}
readerMocker.demand.setExpandEvents {}
readerMocker.demand.addCompleter(2) {}
readerMocker.demand.readLine(1) {'Foo { {'}
- MockFor preferencesMocker = new MockFor(Preferences)
- preferencesMocker.demand.get(1) {'true'}
- preferencesMocker.use {readerMocker.use {
- InteractiveShellRunner runner = new InteractiveShellRunner(groovysh, {'>'})
+
+ preferencesMocker.use { readerMocker.use {
+ def runner = new InteractiveShellRunner(groovysh, {'>'})
runner.readLine()
- assertEquals(0, runner.wrappedInputStream.inserted.available())
+
+ assert runner.wrappedInputStream.inserted.available() == 0
}}
}
}
diff --git a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/ShellRunnerTestSupport.groovy b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/ShellRunnerTestSupport.groovy
index d1565b1f59..9759a6cfd5 100644
--- a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/ShellRunnerTestSupport.groovy
+++ b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/ShellRunnerTestSupport.groovy
@@ -25,41 +25,39 @@ import jline.console.ConsoleReader
import org.codehaus.groovy.tools.shell.IO
/**
- * Support for testing {@link Command} instances.
+ * Support for testing {@link ShellRunner} instances.
*/
abstract class ShellRunnerTestSupport extends GroovyTestCase {
- protected IO testio
protected BufferedOutputStream mockOut
protected BufferedOutputStream mockErr
+ protected IO testio
protected MockFor shellMocker
protected StubFor readerStubber
@Override
- void setUp() {
+ protected void setUp() {
super.setUp()
+
mockOut = new BufferedOutputStream(new ByteArrayOutputStream())
mockErr = new BufferedOutputStream(new ByteArrayOutputStream())
testio = new IO(new ByteArrayInputStream(), mockOut, mockErr)
testio.verbosity = IO.Verbosity.QUIET
- // setup mock and stub with calls expected from InteractiveShellRunner Constructor
shellMocker = new MockFor(Groovysh)
- // when run with compileStatic
- shellMocker.demand.getClass(0..1) {Groovysh}
- shellMocker.demand.createDefaultRegistrar(1) { {Shell shell -> null} }
+ // Groovysh constructor
+ shellMocker.demand.getClass( 1) { Groovysh }
+ shellMocker.demand.getIo(0..21) { testio }
+ shellMocker.demand.register(18) { it }
+ // InteractiveShellRunner constructor
shellMocker.demand.getIo(2) { testio }
- shellMocker.demand.getRegistry(1) {new Object() {def commands() {[]} }}
- shellMocker.demand.getHistory(1) {new Serializable(){def size() {0}; def getMaxSize() {1}}}
- shellMocker.demand.setHistoryFull(1) {}
- shellMocker.demand.getHistoryFull(1) {false}
- // adding number of commands from xml file
- for (i in 1..19) {
- shellMocker.demand.getIo(0..1) { testio }
- shellMocker.demand.add(0..1) { testio }
- shellMocker.demand.getIo(0..1) { testio }
- }
+ // InteractiveShellRunner run
+ shellMocker.demand.getRegistry(0..1) { new CommandRegistry() }
+ // InteractiveShellRunner adjustHistory
+ shellMocker.demand.getHistory(0..1) { null }
+ shellMocker.demand.setHistoryFull(0..1) { }
+ shellMocker.demand.isHistoryFull(0..1) { }
readerStubber = new StubFor(ConsoleReader)
readerStubber.demand.setExpandEvents {}
@@ -68,7 +66,5 @@ abstract class ShellRunnerTestSupport extends GroovyTestCase {
readerStubber.demand.addCompleter {}
readerStubber.demand.printNewline {}
readerStubber.demand.addCompleter {}
- shellMocker.demand.getIo(0..1) { testio }
}
-
}
diff --git a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/completion/GroovySyntaxCompleterTest.groovy b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/completion/GroovySyntaxCompleterTest.groovy
index af1a6f9fd6..591f2d93e5 100644
--- a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/completion/GroovySyntaxCompleterTest.groovy
+++ b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/completion/GroovySyntaxCompleterTest.groovy
@@ -19,208 +19,159 @@
package org.apache.groovy.groovysh.completion
import groovy.mock.interceptor.MockFor
+import org.apache.groovy.groovysh.BufferManager
import org.apache.groovy.groovysh.CommandRegistry
import org.apache.groovy.groovysh.CompleterTestSupport
import org.apache.groovy.groovysh.Groovysh
-import org.apache.groovy.groovysh.commands.ImportCommand
import org.apache.groovy.groovysh.completion.antlr4.GroovySyntaxCompleter
import org.apache.groovy.groovysh.completion.antlr4.IdentifierCompleter
import org.apache.groovy.groovysh.completion.antlr4.ReflectionCompleter
-class GroovySyntaxCompleterTest extends CompleterTestSupport {
+final class GroovySyntaxCompleterTest extends CompleterTestSupport {
- void testEmpty() {
- IdentifierCompleter mockIdCompleter = idCompleterMocker.proxyDelegateInstance()
+ private final BufferManager bufferManager = new BufferManager()
+ private final List<CharSequence> candidates = []
+
+ private int runTest(String buffer, int cursor = buffer.length(), FileNameCompleter fileNameCompleter = null) {
+ if (buffer) {
+ def registry = new CommandRegistry()
+ groovyshMocker.demand.getRegistry(1) { registry }
+ groovyshMocker.demand.getBuffers(0..1) { bufferManager }
+ }
+
+ int result = Integer.MIN_VALUE
groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompleter mockReflComp = reflectionCompleterMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovyshMock, mockReflComp, mockIdCompleter, [mockIdCompleter], null)
- assert -1 == completer.complete('', 0, [])
+ Groovysh groovysh = new Groovysh()
+ IdentifierCompleter identifierCompleter = idCompleterMocker.proxyDelegateInstance()
+ ReflectionCompleter reflectionCompleter = reflectionCompleterMocker.proxyInstance(groovysh)
+ GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovysh, reflectionCompleter, identifierCompleter, [identifierCompleter], fileNameCompleter)
+
+ result = completer.complete(buffer, cursor, candidates)
}
+ return result
+ }
+
+ void testEmpty() {
+ int result = runTest('')
+
+ assert result == -1
+ assert candidates.isEmpty()
}
void testIdentifier() {
idCompleterMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['jav']); candidates << 'javup'; candidates << 'java.lang.String' ; true}
- IdentifierCompleter mockIdCompleter = idCompleterMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompleter mockReflComp = reflectionCompleterMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovyshMock, mockReflComp, mockIdCompleter, [mockIdCompleter], null)
- def candidates = []
- String buffer = 'jav'
- // in the shell, only Classes in the default package occur,but well...
- assert 0 == completer.complete(buffer, buffer.length(), candidates)
- assert ['javup', 'java.lang.String'] == candidates
- }
+
+ int result = runTest('jav')
+
+ assert result == 0
+ assert candidates == ['javup', 'java.lang.String']
}
void testIdentifierAfterLCurly() {
idCompleterMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['{', 'jav']); candidates << 'javup'; candidates << 'java.lang.String' ; true}
- IdentifierCompleter mockIdCompleter = idCompleterMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompleter mockReflComp = reflectionCompleterMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovyshMock, mockReflComp, mockIdCompleter, [mockIdCompleter], null)
- def candidates = []
- String buffer = '{jav'
- // in the shell, only Classes in the default package occur,but well...
- assert 1 == completer.complete(buffer, buffer.length(), candidates)
- assert ['javup', 'java.lang.String'] == candidates
- }
+
+ int result = runTest('{jav')
+
+ assert result == 1
+ assert candidates == ['javup', 'java.lang.String']
}
void testMember() {
reflectionCompleterMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['Math', '.', 'ma']); candidates << 'max('; 5}
- IdentifierCompleter mockIdCompleter = idCompleterMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompleter mockReflComp = reflectionCompleterMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovyshMock, mockReflComp, mockIdCompleter, [mockIdCompleter], null)
- def candidates = []
- String buffer = 'Math.ma'
- assert 5 == completer.complete(buffer, buffer.length(), candidates)
- assert ['max('] == candidates
- }
+
+ int result = runTest('Math.ma')
+
+ assert result == 5
+ assert candidates == ['max(']
}
void testMemberOptionalDot() {
reflectionCompleterMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['Math', '?.', 'ma']); candidates << 'max('; 6}
- IdentifierCompleter mockIdCompleter = idCompleterMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompleter mockReflComp = reflectionCompleterMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovyshMock, mockReflComp, mockIdCompleter, [mockIdCompleter], null)
- def candidates = []
- String buffer = 'Math?.ma'
- assert 6 == completer.complete(buffer, buffer.length(), candidates)
- assert ['max('] == candidates
- }
+
+ int result = runTest('Math?.ma')
+
+ assert result == 6
+ assert candidates == ['max(']
}
void testMemberSpreadDot() {
reflectionCompleterMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['[', '\'foo\'', ']', '*.', 'len']); candidates << 'length()'; 9}
- IdentifierCompleter mockIdCompleter = idCompleterMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompleter mockReflComp = reflectionCompleterMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovyshMock, mockReflComp, mockIdCompleter, [mockIdCompleter], null)
- def candidates = []
- String buffer = '[\'foo\']*.len'
- assert 9 == completer.complete(buffer, buffer.length(), candidates)
- assert ['length()'] == candidates
- }
+
+ int result = runTest('[\'foo\']*.len')
+
+ assert result == 9
+ assert candidates == ['length()']
}
void testMemberAfterMethod() {
reflectionCompleterMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['Fo', '.', 'ba', '(', ')', '.', 'xyz']); candidates << 'xyzabc'; 0}
- IdentifierCompleter mockIdCompleter = idCompleterMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompleter mockReflComp = reflectionCompleterMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovyshMock, mockReflComp, mockIdCompleter, [mockIdCompleter], null)
- def candidates = []
- String buffer = 'Fo.ba().xyz'
- // xyz cannot be not a var here
- assert 0 == completer.complete(buffer, buffer.length(), candidates)
- assert ['xyzabc'] == candidates
- }
+
+ // xyz cannot be not a var here
+ int result = runTest('Fo.ba().xyz')
+
+ assert result == 0
+ assert candidates == ['xyzabc']
}
void testIdentfierAfterDotAfterParens() {
idCompleterMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['Foo', '.', 'bar', '(', 'xyz']); candidates << 'xyzabc'; true}
- IdentifierCompleter mockIdCompleter = idCompleterMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompleter mockReflComp = reflectionCompleterMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovyshMock, mockReflComp, mockIdCompleter, [mockIdCompleter], null)
- def candidates = []
- String buffer = 'Foo.bar(xyz'
- assert 8 == completer.complete(buffer, buffer.length(), candidates)
- assert ['xyzabc'] == candidates
- }
+
+ int result = runTest('Foo.bar(xyz')
+
+ assert result == 8
+ assert candidates == ['xyzabc']
}
void testIndentifierAfterParensBeforeDot() {
idCompleterMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['Foo', '.', 'bar', '(', 'xyz']); candidates << 'xyzabc'; true}
- IdentifierCompleter mockIdCompleter = idCompleterMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompleter mockReflComp = reflectionCompleterMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovyshMock, mockReflComp, mockIdCompleter, [mockIdCompleter], null)
- def candidates = []
- // cursor is BEFORE dot
- assert 8 == completer.complete('Foo.bar(xyz.', 'Foo.bar(xyz'.length(), candidates)
- assert ['xyzabc'] == candidates
- }
+
+ int result = runTest('Foo.bar(xyz.', 'Foo.bar(xyz'.length()) // cursor is BEFORE dot
+
+ assert result == 8
+ assert candidates == ['xyzabc']
}
void testDoubleIdentifier() {
- IdentifierCompleter mockIdCompleter = idCompleterMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompleter mockReflComp = reflectionCompleterMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovyshMock, mockReflComp, mockIdCompleter, [mockIdCompleter], null)
- def candidates = []
- String buffer = 'String jav'
- assert -1 == completer.complete(buffer, buffer.length(), candidates)
- assert [] == candidates
- }
+ int result = runTest('String jav')
+
+ assert result == -1
+ assert candidates == []
}
void testInfixKeyword() {
- IdentifierCompleter mockIdCompleter = idCompleterMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompleter mockReflComp = reflectionCompleterMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovyshMock, mockReflComp, mockIdCompleter, [mockIdCompleter], null)
- def candidates = []
- String buffer = 'class Foo ext'
- assert 10 == completer.complete(buffer, buffer.length(), candidates)
- assert ['extends'] == candidates
- }
+ int result = runTest('class Foo ext')
+
+ assert result == 10
+ assert candidates == ['extends']
}
void testInstanceof() {
idCompleterMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['x', 'instanceof', 'P']); candidates << 'Property'; 13}
- IdentifierCompleter mockIdCompleter = idCompleterMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompleter mockReflComp = reflectionCompleterMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovyshMock, mockReflComp, mockIdCompleter, [mockIdCompleter], null)
- def candidates = []
- String buffer = 'x instanceof P'
- assert 13 == completer.complete(buffer, buffer.length(), candidates)
- assert 'Property' in candidates
- }
- }
+ int result = runTest('x instanceof P')
+ assert result == 13
+ assert candidates.contains('Property')
+ }
void testAfterSemi() {
// evaluation of all is dangerous, but the reflectionCompleter has to deal with this
reflectionCompleterMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['deletehardDisk', '(', ')', ';', 'foo', '.', 'subs']); candidates << 'substring('; 22}
- IdentifierCompleter mockIdCompleter = idCompleterMocker.proxyDelegateInstance()
- // mock doing the right thing
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompleter mockReflComp = reflectionCompleterMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovyshMock, mockReflComp, mockIdCompleter, [mockIdCompleter], null)
- def candidates = []
- String buffer = 'deletehardDisk(); foo.subs'
- assert 22 == completer.complete(buffer, buffer.length(), candidates)
- assert ['substring('] == candidates
- }
+ int result = runTest('deletehardDisk(); foo.subs')
+
+ assert result == 22
+ assert candidates == ['substring(']
}
void testAfterOperator() {
@@ -228,108 +179,74 @@ class GroovySyntaxCompleterTest extends CompleterTestSupport {
reflectionCompleterMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['a', '=', 'foo', '.', 'subs']); candidates << 'substring('; 9}
- IdentifierCompleter mockIdCompleter = idCompleterMocker.proxyDelegateInstance()
- // mock doing the right thing
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompleter mockReflComp = reflectionCompleterMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovyshMock, mockReflComp, mockIdCompleter, [mockIdCompleter], null)
- def candidates = []
- String buffer = 'a = foo.subs'
- assert 9 == completer.complete(buffer, buffer.length(), candidates)
- assert ['substring('] == candidates
- }
+ int result = runTest('a = foo.subs')
+
+ assert result == 9
+ assert candidates == ['substring(']
}
void testDontEvaluateAfterCommand() {
- CommandRegistry registry = new CommandRegistry()
- IdentifierCompleter mockIdCompleter = idCompleterMocker.proxyDelegateInstance()
- // mock asserting nothing gets evaluated
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompleter mockReflComp = reflectionCompleterMocker.proxyInstance(groovyshMock)
- // import command prevents reflection completion
- registry.register(new ImportCommand(groovyshMock))
- GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovyshMock, mockReflComp, mockIdCompleter, [mockIdCompleter], null)
- def candidates = []
- String buffer = 'import foo'
- assert -1 == completer.complete(buffer, buffer.length(), candidates)
- assert [] == candidates
- }
+ // import command prevents reflection completion
+ int result = runTest('import foo')
+
+ assert result == -1
+ assert candidates == []
}
void _disabled_testAfterGString() { // should we prohibit this?
- IdentifierCompleter mockIdCompleter = idCompleterMocker.proxyDelegateInstance()
- // mock asserting GString is not evaluated
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompleter mockReflComp = reflectionCompleterMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovyshMock, mockReflComp, mockIdCompleter, [mockIdCompleter], null)
- def candidates = []
- String buffer = '"\${foo.delete()}".subs'
- assert candidates == [] && -1 == completer.complete(buffer, buffer.length(), candidates)
- }
+ int result = runTest('"\${foo.delete()}".subs') // GString not evaluated
+
+ assert result == -1
+ assert candidates == []
}
void _fixme_testInStringFilename() {
- IdentifierCompleter mockIdCompleter = idCompleterMocker.proxyDelegateInstance()
- MockFor filenameCompleterMocker = new MockFor(FileNameCompleter)
- String linestart = /foo('/ // ends with single hyphen
+ def filenameCompleterMocker = new MockFor(FileNameCompleter)
+ String linestart = "foo('" // ends with apostrophe
String pathstart = '/usr/foobar'
- String buffer = linestart + pathstart
+
filenameCompleterMocker.demand.complete(2) { bufferline, cursor, candidates ->
- assert(bufferline == pathstart)
- assert(cursor == pathstart.length())
+ assert bufferline == pathstart
+ assert cursor == pathstart.length()
candidates << 'foobar'
5
}
- groovyshMocker.use { filenameCompleterMocker.use {
- FileNameCompleter mockFileComp = new FileNameCompleter()
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompleter mockReflComp = reflectionCompleterMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovyshMock, mockReflComp, mockIdCompleter, [mockIdCompleter], mockFileComp)
- def candidates = []
- assert 'foo(\'/usr/'.length() == completer.complete(buffer, buffer.length(), candidates)
- assert ['foobar'] == candidates
- }}
+
+ String buffer = linestart + pathstart
+ int result = runTest(buffer, buffer.length(), filenameCompleterMocker.proxyDelegateInstance())
+
+ assert result == "foo('/usr/".length()
+ assert candidates == ['foobar']
}
void _fixme_testInStringFilenameBlanks() {
- // test with blanks (non-tokens) before the first hyphen
- IdentifierCompleter mockIdCompleter = idCompleterMocker.proxyDelegateInstance()
- MockFor filenameCompleterMocker = new MockFor(FileNameCompleter)
- String linestart = 'x = \'' // ends with single hyphen
+ // test with blanks (non-tokens) before the apostrophe
+ def filenameCompleterMocker = new MockFor(FileNameCompleter)
+ String linestart = 'x = \'' // ends with apostrophe
String pathstart = '/usr/foobar'
- String buffer = linestart + pathstart
+
filenameCompleterMocker.demand.complete(1) {bufferline, cursor, candidates ->
assert bufferline == pathstart
assert cursor == pathstart.length()
- candidates << 'foobar'; 5}
- groovyshMocker.use { filenameCompleterMocker.use {
- FileNameCompleter mockFileComp = new FileNameCompleter()
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompleter mockReflComp = reflectionCompleterMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovyshMock, mockReflComp, mockIdCompleter, [mockIdCompleter], mockFileComp)
- def candidates = []
- assert 'x = \'/usr/'.length() == completer.complete(buffer, buffer.length(), candidates)
- assert ['foobar'] == candidates
- }}
+ candidates << 'foobar'
+ 5
+ }
+
+ String buffer = linestart + pathstart
+ int result = runTest(buffer, buffer.length(), filenameCompleterMocker.proxyDelegateInstance())
+
+ assert result == "x = '/usr/".length()
+ assert candidates == ['foobar']
}
void testInGString() {
idCompleterMocker.demand.complete(1) { tokens, candidates ->
assert(tokens*.text == ['"$', '{', 'foo']); candidates << 'foobar'; true}
- IdentifierCompleter mockIdCompleter = idCompleterMocker.proxyDelegateInstance()
- // mock asserting GString is not evaluated
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompleter mockReflComp = reflectionCompleterMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovyshMock, mockReflComp, mockIdCompleter, [mockIdCompleter], null)
- def candidates = []
- String buffer = '"\${foo'
- assert 3 == completer.complete(buffer, buffer.length(), candidates)
- assert ['foobar'] == candidates
- }
+
+ int result = runTest('"\${foo')
+
+ assert result == 3
+ assert candidates == ['foobar']
}
void testMultilineComplete() {
@@ -337,16 +254,10 @@ class GroovySyntaxCompleterTest extends CompleterTestSupport {
assert(tokens*.text == ['"""xyz\nabc"""', '.', 'subs']); candidates << 'substring('; 7}
bufferManager.buffers.add(['"""xyz'])
bufferManager.setSelected(1)
- IdentifierCompleter mockIdCompleter = idCompleterMocker.proxyDelegateInstance()
- groovyshMocker.use {
- Groovysh groovyshMock = new Groovysh()
- ReflectionCompleter mockReflComp = reflectionCompleterMocker.proxyInstance(groovyshMock)
- GroovySyntaxCompleter completer = new GroovySyntaxCompleter(groovyshMock, mockReflComp, mockIdCompleter, [mockIdCompleter], null)
- def candidates = []
- String buffer = 'abc""".subs'
- assert 7 == completer.complete(buffer, buffer.length(), candidates)
- assert ['substring('] == candidates
- }
+
+ int result = runTest('abc""".subs')
+
+ assert result == 7
+ assert candidates == ['substring(']
}
}
-