Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'develop' of github.com:bendisposto/probcore into develop

  • Loading branch information...
commit 11cba1175f223f51f09503607df93ecc0a0d425e 2 parents 3a092a4 + 621ddaa
@bendisposto authored
View
167 src/main/groovy/org/codehaus/groovy/tools/shell/PInteractiveShellRunner.groovy
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2003-2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.codehaus.groovy.tools.shell
+
+import jline.Completor
+import jline.ConsoleReader
+import jline.History
+import jline.MultiCompletor
+import org.codehaus.groovy.tools.shell.util.Logger
+
+
+/**
+ * Support for running a {@link Shell} interactively using the JLine library.
+ *
+ * @version $Id$
+ * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
+ */
+class PInteractiveShellRunner
+extends ShellRunner
+implements Runnable {
+ final ConsoleReader reader
+
+ final Closure prompt
+
+ final CommandsMultiCompletor completor
+
+ PInteractiveShellRunner(final Shell shell, final Closure prompt) {
+ super(shell)
+
+ this.prompt = prompt
+
+ this.reader = new ConsoleReader(shell.io.inputStream, new PrintWriter(shell.io.outputStream, true))
+
+ reader.addCompletor(new PReflectionCompletor(shell))
+ this.completor = new CommandsMultiCompletor()
+
+ reader.addCompletor(completor)
+ }
+
+ void run() {
+ for (command in shell.registry) {
+ completor << command
+ }
+
+ // Force things to become clean
+ completor.refresh()
+
+ // And then actually run
+ adjustHistory()
+ super.run()
+ }
+
+ void setHistory(final History history) {
+ reader.history = history
+ }
+
+ void setHistoryFile(final File file) {
+ def dir = file.parentFile
+
+ if (!dir.exists()) {
+ dir.mkdirs()
+
+ log.debug("Created base directory for history file: $dir")
+ }
+
+ log.debug("Using history file: $file")
+
+ reader.history.historyFile = file
+ }
+
+ protected String readLine() {
+ try {
+ return reader.readLine(prompt.call())
+ }
+ catch (StringIndexOutOfBoundsException e) {
+ log.debug("HACK: Try and work around GROOVY-2152 for now", e)
+
+ return "";
+ }
+ }
+
+ @Override
+ protected boolean work() {
+ boolean result= super.work()
+ adjustHistory()
+
+ result
+ }
+
+ private void adjustHistory() {
+ if (shell instanceof Groovysh) {
+ shell.historyFull = shell.history.size() >= shell.history.maxSize
+ if (shell.historyFull) shell.evictedLine = shell.history.historyList[0]
+ }
+ }
+}
+
+/**
+ * Completor for interactive shells.
+ *
+ * @version $Id$
+ * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
+ */
+class CommandsMultiCompletor
+extends MultiCompletor {
+ protected final Logger log = Logger.create(this.class)
+
+ List/*<Completor>*/ list = []
+
+ private boolean dirty = false
+
+ def leftShift(final Command command) {
+ assert command
+
+ //
+ // FIXME: Need to handle completor removal when things like aliases are rebound
+ //
+
+ def c = command.completor
+
+ if (c) {
+ list << c
+
+ log.debug("Added completor[${list.size()}] for command: $command.name")
+
+ dirty = true
+ }
+ }
+
+ void refresh() {
+ log.debug("Refreshing the completor list")
+
+ completors = list as Completor[]
+ dirty = false
+ }
+
+ int complete(final String buffer, final int pos, final List cand) {
+ assert buffer != null
+
+ //
+ // FIXME: This is a bit of a hack, I'm too lazy to rewrite a more efficient
+ // completor impl that is more dynamic than the jline.MultiCompletor version
+ // so just re-use it and reset the list as needed
+ //
+
+ if (dirty) {
+ refresh()
+ }
+
+ return super.complete(buffer, pos, cand)
+ }
+}
+
View
131 src/main/groovy/org/codehaus/groovy/tools/shell/PReflectionCompletor.groovy
@@ -0,0 +1,131 @@
+package org.codehaus.groovy.tools.shell
+
+import jline.Completor
+import org.codehaus.groovy.runtime.InvokerHelper
+
+/**
+ * Implements the Completor interface to provide competions for
+ * GroovyShell by using reflection on global variables.
+ *
+ * @author <a href="mailto:probabilitytrees@gmail.com">Marty Saxton</a>
+ */
+class PReflectionCompletor implements Completor {
+
+ private Shell shell;
+
+ PReflectionCompletor(Shell shell) {
+ this.shell = shell
+ }
+
+ int complete(String buffer, int cursor, List candidates) {
+
+ int identifierStart = findIdentifierStart(buffer, cursor)
+ //FIXME: Figure out a new way to get the identifier prefix
+ //It should be the substring before the last '.' or '('
+ String identifierPrefix = identifierStart != -1 ? buffer.substring(identifierStart, cursor) : ""
+ int lastDot = buffer.lastIndexOf('.')
+
+ // if there are no dots, and there is a valid identifier prefix
+ if (lastDot == -1 || noDotsBeforeParentheses(buffer, cursor) ) {
+ if (identifierStart != -1) {
+ List myCandidates = findMatchingVariables(identifierPrefix)
+ if (myCandidates.size() > 0) {
+ candidates.addAll(myCandidates)
+ return identifierStart
+
+ }
+ }
+ } else {
+ // there are 1 or more dots
+ // if ends in a dot, or if there is a valid identifier prefix
+ if (lastDot == cursor-1 || identifierStart != -1){
+ // evaluate the part before the dot to get an instance
+ int predecessorStart=findIdentifierStart(buffer,lastDot)
+
+ String instanceRefExpression = buffer.substring(predecessorStart, lastDot)
+ def instance = shell.interp.evaluate([instanceRefExpression])
+ if (instance != null) {
+ // look for public methods/fields that match the prefix
+ List myCandidates = getPublicFieldsAndMethods(instance, identifierPrefix)
+ if (myCandidates.size() > 0) {
+ candidates.addAll(myCandidates)
+ return lastDot+1
+ }
+ }
+ }
+ }
+
+ // no candidates
+ return -1
+ }
+
+ /**
+ * Parse a buffer to determine the start index of the groovy identifier
+ * @param buffer the buffer to parse
+ * @param endingAt the end index with the buffer
+ * @return the start index of the identifier, or -1 if the buffer
+ * does not contain a valid identifier that ends at endingAt
+ */
+ int findIdentifierStart(String buffer, int endingAt) {
+ // if the string is empty then there is no expression
+ if (endingAt == 0)
+ return -1
+ // if the last character is not valid then there is no expression
+ char lastChar = buffer.charAt(endingAt-1)
+ if (!Character.isJavaIdentifierPart(lastChar) )
+ return -1
+ // scan backwards until the beginning of the expression is found
+ int startIndex = endingAt-1
+ while (startIndex > 0 && Character.isJavaIdentifierPart(buffer.charAt(startIndex-1)))
+ --startIndex
+ return startIndex
+ }
+
+
+ /**
+ * Build a list of public fields and methods for an object
+ * that match a given prefix.
+ * @param instance the object
+ * @param prefix the prefix that must be matched
+ * @return the list of public methods and fields that begin with the prefix
+ */
+ List getPublicFieldsAndMethods(Object instance, String prefix) {
+ def rv = []
+ instance.class.fields.each {
+ if (it.name.startsWith(prefix))
+ rv << it.name
+ }
+ instance.class.methods.each {
+ if (it.name.startsWith(prefix))
+ rv << it.name + (it.parameterTypes.length == 0 ? "()" : "(")
+ }
+ InvokerHelper.getMetaClass(instance).metaMethods.each {
+ if (it.name.startsWith(prefix))
+ rv << it.name + (it.parameterTypes.length == 0 ? "()" : "(")
+ }
+ return rv.sort().unique()
+ }
+
+ /**
+ * Build a list of variables defined in the shell that
+ * match a given prefix.
+ * @param prefix the prefix to match
+ * @return the list of variables that match the prefix
+ */
+ List findMatchingVariables(String prefix) {
+ def matches = []
+ for (String varName in shell.interp.context.variables.keySet())
+ if (varName.startsWith(prefix))
+ matches << varName
+ return matches
+ }
+
+ Boolean noDotsBeforeParentheses(String buffer, int endingAt) {
+ int lastDotIndex = buffer.lastIndexOf('.')
+ int lastParanIndex = buffer.lastIndexOf('(')
+
+ if(lastDotIndex==-1&&lastParanIndex==-1)
+ return true;
+ return lastDotIndex < lastParanIndex
+ }
+}
View
4 src/main/groovy/org/codehaus/groovy/tools/shell/PShell.groovy
@@ -60,7 +60,7 @@ extends Shell {
final version
- InteractiveShellRunner runner
+ PInteractiveShellRunner runner
History history
@@ -413,7 +413,7 @@ extends Shell {
loadUserScript('groovysh.rc')
// Setup the interactive runner
- runner = new InteractiveShellRunner(this, this.&renderPrompt as Closure)
+ runner = new PInteractiveShellRunner(this, this.&renderPrompt as Closure)
// Setup the history
runner.history = history = new History()
View
6 src/main/java/de/prob/animator/command/GetOperationByPredicateCommand.java
@@ -26,7 +26,7 @@
/**
* Command to execute an event that has not been enumerated by ProB, for further
- * information see ({@link #getOperation})
+ * information see ({@link #getOperations})
*
* @author Jens Bendisposto
*
@@ -58,7 +58,7 @@ public GetOperationByPredicateCommand(final String stateId,
*
* @throws ProBException
*
- * @see de.prob.core.command.IComposableCommand#writeCommand(de.prob.prolog.output.IPrologTermOutput)
+ * @see de.prob.animator.command.ICommand#writeCommand(de.prob.prolog.output.IPrologTermOutput)
*/
@Override
public void writeCommand(final IPrologTermOutput pto) throws ProBException {
@@ -78,7 +78,7 @@ public void writeCommand(final IPrologTermOutput pto) throws ProBException {
*
* @throws ProBException
*
- * @see de.prob.core.command.IComposableCommand#writeCommand(de.prob.prolog.output.IPrologTermOutput)
+ * @see de.prob.animator.command.ICommand#writeCommand(de.prob.prolog.output.IPrologTermOutput)
*/
@Override
public void processResult(
View
5 src/main/java/de/prob/animator/command/notImplemented/ConstraintBasedDeadlockCheckCommand.java
@@ -43,8 +43,7 @@
/**
* @param predicate
* is a parsed predicate or <code>null</code>
- * @see LanguageDependendAnimationPart#parsePredicate(IPrologTermOutput,
- * String, boolean)
+ *
*/
public ConstraintBasedDeadlockCheckCommand(final PrologTerm predicate) {
this.predicate = predicate;
@@ -104,7 +103,7 @@ public void processResult(
logger.error("Result from Prolog was not as expected.", e);
throw new ProBException();
}
-
+
} else {
logger.error("unexpected result from deadlock check: " + resultTerm);
throw new ProBException();
View
171 src/main/java/de/prob/animator/command/notImplemented/EvaluationInsertFormulaCommand.java
@@ -9,7 +9,6 @@
import de.prob.prolog.output.IPrologTermOutput;
import de.prob.prolog.term.PrologTerm;
-
//import de.prob.core.Animator;
//import de.prob.core.LanguageDependendAnimationPart;
//import de.prob.core.domainobjects.EvaluationElement;
@@ -21,104 +20,102 @@
//import de.prob.prolog.term.PrologTerm;
/**
- * This commands registers a formula (given as an already parsed
- * {@link PrologTerm}) in the Prolog core and returns an
- * {@link EvaluationElement} that can be used to evaluate the formula and
- * retrieve its subformulas.
+ * This commands registers a formula (given as an already parsed PrologTerm) in
+ * the Prolog core and returns an EvaluationElement that can be used to evaluate
+ * the formula and retrieve its subformulas.
*
* @author plagge
*/
public class EvaluationInsertFormulaCommand implements ICommand {
-// FIXME: This command must be refactored with EvaluationElement object
-// public static enum FormulaType {
-// PREDICATE, EXPRESSION
-// };
-//
-// private static final String VARNAME_ID = "ID";
-// private final PrologTerm rawExpression;
-// private PrologTerm id;
-//
-// public static EvaluationElement insertPredicate(final String formula)
-// throws ProBException, UnsupportedOperationException,
-// ProBParseException {
-// return insertFormula(getParser().parsePredicate(formula, false));
-// }
-//
-// public static EvaluationElement insertExpression(final String formula)
-// throws ProBException, UnsupportedOperationException,
-// ProBParseException {
-// return insertFormula(getParser().parseExpression(formula, false));
-// }
-//
-// public static EvaluationElement insertFormula(final Animator animator,
-// final FormulaType type, final String formula) throws ProBException,
-// UnsupportedOperationException, ProBParseException {
-// final ProBParserBaseAdapter parser = getParser(animator);
-// final PrologTerm parsed;
-// switch (type) {
-// case EXPRESSION:
-// parsed = parser.parseExpression(formula, false);
-// break;
-// case PREDICATE:
-// parsed = parser.parsePredicate(formula, false);
-// break;
-// default:
-// throw new IllegalArgumentException("Unsupported formula type: "
-// + type);
-// }
-// return insertFormula(parsed);
-// }
-//
-// private static ProBParserBaseAdapter getParser() {
-// return getParser(Animator.getAnimator());
-// }
-//
-// private static ProBParserBaseAdapter getParser(final Animator animator) {
-// final LanguageDependendAnimationPart ldp = animator
-// .getLanguageDependendPart();
-// if (ldp == null) {
-// throw new UnsupportedOperationException(
-// "The current formalism does not allow parsing of formulas");
-// } else {
-// return new ProBParserBaseAdapter(ldp);
-// }
-// }
-//
-// public EvaluationInsertFormulaCommand(final PrologTerm rawExpression) {
-// this.rawExpression = rawExpression;
-// }
-//
-// public void processResult(
-// final ISimplifiedROMap<String, PrologTerm> bindings){
-// //id = bindings.get(VARNAME_ID);
-// }
-//
-// public void writeCommand(final IPrologTermOutput pto) {
-// pto.openTerm("evaluation_insert_formula");
-// rawExpression.toTermOutput(pto);
-// pto.printAtom("user");
-// pto.printVariable(VARNAME_ID);
-// pto.closeTerm();
-// }
-//
-// public PrologTerm getId() {
-// return id;
-// }
-
+ // FIXME: This command must be refactored with EvaluationElement object
+ // public static enum FormulaType {
+ // PREDICATE, EXPRESSION
+ // };
+ //
+ // private static final String VARNAME_ID = "ID";
+ // private final PrologTerm rawExpression;
+ // private PrologTerm id;
+ //
+ // public static EvaluationElement insertPredicate(final String formula)
+ // throws ProBException, UnsupportedOperationException,
+ // ProBParseException {
+ // return insertFormula(getParser().parsePredicate(formula, false));
+ // }
+ //
+ // public static EvaluationElement insertExpression(final String formula)
+ // throws ProBException, UnsupportedOperationException,
+ // ProBParseException {
+ // return insertFormula(getParser().parseExpression(formula, false));
+ // }
+ //
+ // public static EvaluationElement insertFormula(final Animator animator,
+ // final FormulaType type, final String formula) throws ProBException,
+ // UnsupportedOperationException, ProBParseException {
+ // final ProBParserBaseAdapter parser = getParser(animator);
+ // final PrologTerm parsed;
+ // switch (type) {
+ // case EXPRESSION:
+ // parsed = parser.parseExpression(formula, false);
+ // break;
+ // case PREDICATE:
+ // parsed = parser.parsePredicate(formula, false);
+ // break;
+ // default:
+ // throw new IllegalArgumentException("Unsupported formula type: "
+ // + type);
+ // }
+ // return insertFormula(parsed);
+ // }
+ //
+ // private static ProBParserBaseAdapter getParser() {
+ // return getParser(Animator.getAnimator());
+ // }
+ //
+ // private static ProBParserBaseAdapter getParser(final Animator animator) {
+ // final LanguageDependendAnimationPart ldp = animator
+ // .getLanguageDependendPart();
+ // if (ldp == null) {
+ // throw new UnsupportedOperationException(
+ // "The current formalism does not allow parsing of formulas");
+ // } else {
+ // return new ProBParserBaseAdapter(ldp);
+ // }
+ // }
+ //
+ // public EvaluationInsertFormulaCommand(final PrologTerm rawExpression) {
+ // this.rawExpression = rawExpression;
+ // }
+ //
+ // public void processResult(
+ // final ISimplifiedROMap<String, PrologTerm> bindings){
+ // //id = bindings.get(VARNAME_ID);
+ // }
+ //
+ // public void writeCommand(final IPrologTermOutput pto) {
+ // pto.openTerm("evaluation_insert_formula");
+ // rawExpression.toTermOutput(pto);
+ // pto.printAtom("user");
+ // pto.printVariable(VARNAME_ID);
+ // pto.closeTerm();
+ // }
+ //
+ // public PrologTerm getId() {
+ // return id;
+ // }
+
@Override
- public void writeCommand(IPrologTermOutput pto) throws ProBException {
+ public void writeCommand(final IPrologTermOutput pto) throws ProBException {
// TODO Auto-generated method stub
-
+
}
@Override
- public void processResult(ISimplifiedROMap<String, PrologTerm> bindings)
+ public void processResult(
+ final ISimplifiedROMap<String, PrologTerm> bindings)
throws ProBException {
// TODO Auto-generated method stub
-
- }
-
+ }
}
View
7 src/main/java/de/prob/animator/command/notImplemented/GetPrintableAtomsList.java
@@ -2,6 +2,7 @@
import java.util.List;
+import de.prob.ProBException;
import de.prob.animator.command.ICommand;
import de.prob.parser.ISimplifiedROMap;
import de.prob.prolog.output.IPrologTermOutput;
@@ -22,9 +23,7 @@
* Executes the query: prologPredicate(L). Expects L to be a list of
* printable atoms
*
- * @param animator
- * @param prologPredicate
- * @return
+ * @return a list of printable atoms
* @throws ProBException
*/
@@ -36,12 +35,14 @@ private GetPrintableAtomsList(final String prologPredicate) {
this.prologPredicate = prologPredicate;
}
+ @Override
public void processResult(
final ISimplifiedROMap<String, PrologTerm> bindings) {
list = PrologTerm.atomicStrings((ListPrologTerm) bindings
.get(PROLOG_VARIABLE));
}
+ @Override
public void writeCommand(final IPrologTermOutput pto) {
pto.openTerm(prologPredicate);
pto.printVariable(PROLOG_VARIABLE);
View
7 src/main/java/de/prob/scripting/Api.java
@@ -67,7 +67,7 @@ public StateSpace s() throws ProBException {
* Takes path of a Classical B Machine and loads it into the ClassicalBModel
*
* @param file
- * @return
+ * @return classicalBModel
*/
public ClassicalBModel b_load(final String file) {
File f = new File(file);
@@ -80,7 +80,6 @@ public ClassicalBModel b_load(final String file) {
}
}
-
public String getCurrentId(final StateSpace animation) throws ProBException {
// new ICom<GetCurrentStateIdCommand>(new GetCurrentStateIdCommand())
// .executeOn(animation);
@@ -91,7 +90,7 @@ public String getCurrentId(final StateSpace animation) throws ProBException {
* Upgrades the ProB Cli to the given target version
*
* @param targetVersion
- * @return
+ * @return String with the version of the upgrade
*/
public String upgrade(final String targetVersion) {
try {
@@ -107,7 +106,7 @@ public String upgrade(final String targetVersion) {
/**
* Lists the versions of ProB Cli that are available for download
*
- * @return
+ * @return String with list of possible versions
*/
public String listVersions() {
return downloader.listVersions();
View
18 src/main/java/de/prob/statespace/StateSpace.java
@@ -79,7 +79,9 @@ public StateSpace(final IAnimator animator,
this.history = history;
this.info = info;
addVertex("root");
- if (Main.isShellMode()) setUpSignalHandler();
+ if (Main.isShellMode()) {
+ setUpSignalHandler();
+ }
}
// MAKE CHANGES TO THE STATESPACE GRAPH
@@ -128,7 +130,7 @@ public void explore(final int i) throws ProBException {
* @param name
* @param predicate
* @param nrOfSolutions
- * @return
+ * @return list of operations
* @throws BException
* @throws ProBException
*/
@@ -162,7 +164,7 @@ public void explore(final int i) throws ProBException {
*
* @param opName
* @param predicate
- * @return
+ * @return one operations that meets the specifications
* @throws ProBException
* @throws BException
*/
@@ -175,7 +177,7 @@ public Operation findOneOp(final String opName, final String predicate)
* Checks if the state with stateId is a deadlock
*
* @param stateid
- * @return
+ * @return returns if a specific state is deadlocked
* @throws ProBException
*/
public boolean isDeadlock(final String stateid) throws ProBException {
@@ -189,7 +191,7 @@ public boolean isDeadlock(final String stateid) throws ProBException {
* Checks if the state with stateId has been explored yet
*
* @param stateid
- * @return
+ * @return returns if a specific state is explored
*/
private boolean isExplored(final String stateid) {
if (!containsVertex(stateid))
@@ -320,7 +322,7 @@ public void forward() {
/**
* returns the state id of the current state in the animation
*
- * @return
+ * @return returns the current state from the animation
*/
public String getCurrentState() {
return history.getCurrentState();
@@ -414,7 +416,7 @@ public void evaluateFormulas() {
* strings) and returns a list of EvaluationResults for the current state.
*
* @param code
- * @return
+ * @return returns a list of evalutation results
* @throws ProBException
* @throws BException
*/
@@ -446,7 +448,7 @@ public void evaluateFormulas() {
*
* @param state
* @param code
- * @return
+ * @return returns a list of evaluation results
* @throws ProBException
* @throws BException
*/
View
14 src/main/java/de/prob/statespace/StateSpaceInfo.java
@@ -18,7 +18,7 @@
* @param id
* @param op
*/
- public void add(String id, Operation op) {
+ public void add(final String id, final Operation op) {
ops.put(id, op);
}
@@ -28,7 +28,7 @@ public void add(String id, Operation op) {
* @param id
* @param vars
*/
- public void add(String id, HashMap<String, String> vars) {
+ public void add(final String id, final HashMap<String, String> vars) {
variables.put(id, vars);
}
@@ -38,7 +38,7 @@ public void add(String id, HashMap<String, String> vars) {
* @param id
* @param invOK
*/
- public void addInvOk(String id, Boolean invOK) {
+ public void addInvOk(final String id, final Boolean invOK) {
invariantOk.put(id, invOK);
}
@@ -48,7 +48,7 @@ public void addInvOk(String id, Boolean invOK) {
* @param id
* @param tOccured
*/
- public void addTimeOcc(String id, Boolean tOccured) {
+ public void addTimeOcc(final String id, final Boolean tOccured) {
// FIXME is this id a state id or an operation id
timeoutOccured.put(id, tOccured);
}
@@ -60,7 +60,7 @@ public void addTimeOcc(String id, Boolean tOccured) {
* @param id
* @param opsWT
*/
- public void add(String id, Set<String> opsWT) {
+ public void add(final String id, final Set<String> opsWT) {
operationsWithTimeout.put(id, opsWT);
}
@@ -71,7 +71,7 @@ public void add(String id, Set<String> opsWT) {
* @param stateId
* @param command
*/
- public void add(String stateId, ExploreStateCommand command) {
+ public void add(final String stateId, final ExploreStateCommand command) {
variables.put(stateId, command.getVariables());
invariantOk.put(stateId, command.isInvariantOk());
timeoutOccured.put(stateId, command.isTimeoutOccured());
@@ -94,7 +94,7 @@ public void add(String stateId, ExploreStateCommand command) {
* Returns the map representation of the variables for the given state id
*
* @param stateId
- * @return
+ * @return returns the variables at the given state
*/
public HashMap<String, String> getState(final String stateId) {
return variables.get(stateId);
View
21 src/test/groovy/org/codehaus/groovy/tools/shell/CompletorTest.groovy
@@ -0,0 +1,21 @@
+package org.codehaus.groovy.tools.shell
+
+import spock.lang.Specification
+
+class CompletorTest extends Specification {
+
+ def "Is the identifier start what I expect?"() {
+ setup:
+ def completor = new PReflectionCompletor(null)
+
+ expect:
+ completor.findIdentifierStart(a,c) == b
+
+ where:
+ a | b | c
+ "api.println(api" | 12 | 15
+ "api.println(a" | 12 | 13
+ "api.println(api." | 12 | 15 //find substring api
+ "api.println(api.pr"| 12 | 15
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.