You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2025/07/01 12:16:00 UTC

(groovy) branch jline3 updated: adjust a few tests

This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch jline3
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/jline3 by this push:
     new 5021b8c42b adjust a few tests
5021b8c42b is described below

commit 5021b8c42b18041cb881f89858d7139aa91d8c52
Author: Paul King <pa...@asert.com.au>
AuthorDate: Tue Jul 1 22:15:50 2025 +1000

    adjust a few tests
---
 .../org/apache/groovy/groovysh/CommandAlias.groovy |  85 -------------
 .../apache/groovy/groovysh/CommandSupport.groovy   |   4 -
 .../groovy/groovysh/commands/AliasCommand.groovy   | 134 ---------------------
 .../groovy/groovysh/commands/ExitCommand.groovy    |   2 +-
 .../groovy/groovysh/commands/HelpCommand.groovy    |   2 +-
 .../groovy/groovysh/commands/LoadCommand.groovy    |   2 +-
 .../groovysh/util/DefaultCommandsRegistrar.groovy  |   7 +-
 .../src/main/resources/nanorc/groovy.nanorc        |   4 +-
 .../src/main/resources/nanorc/light.nanorctheme    |  13 ++
 .../groovy/groovysh/AllCompletersTest.groovy       |  20 +--
 .../groovy/groovysh/CommandCompleterTest.groovy    |  18 ++-
 .../{AliasCommandTest.groovy => AliasTest.groovy}  |   2 +-
 ...geCommandTest.groovy => ClassloaderTest.groovy} |  31 ++---
 .../groovysh/commands/ConsoleTestSupport.groovy    |   4 +-
 ...port.groovy => GroovyCommandTestSupport.groovy} |  40 +++---
 .../groovysh/commands/ShowCommandTest.groovy       |   2 +-
 16 files changed, 70 insertions(+), 300 deletions(-)

diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/CommandAlias.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/CommandAlias.groovy
deleted file mode 100644
index e48f85bfc8..0000000000
--- a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/CommandAlias.groovy
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you 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.apache.groovy.groovysh
-
-import org.jline.reader.Completer
-
-/**
- * Provides simple command aliasing.
- */
-class CommandAlias
-    extends CommandSupport
-{
-    final String targetName
-
-    CommandAlias(final Groovysh shell, final String name, final String shortcut, final String target) {
-        super(shell, name, shortcut)
-
-        assert target
-
-        this.targetName = target
-    }
-
-    Command getTarget() {
-        Command command = registry.find(targetName)
-
-        assert command != null
-
-        return command
-    }
-
-    @Override
-    protected List<Completer> createCompleters() {
-        try {
-            // TODO: Use interface with createCompleters()
-            if (target instanceof CommandSupport) {
-                CommandSupport support = (CommandSupport) target
-                return support.createCompleters()
-            }
-
-        } catch (MissingMethodException) {
-            log.warn('Aliased Command without createCompleters Method')
-        }
-    }
-
-    @Override
-    String getDescription() {
-        return messages.format('info.alias_to', targetName)
-    }
-
-    @Override
-    String getUsage() {
-        return target.usage
-    }
-
-    @Override
-    String getHelp() {
-        return target.help
-    }
-
-    @Override
-    boolean getHidden() {
-        return target.hidden
-    }
-
-    @Override
-    Object execute(final List<String> args) {
-        target.execute(args)
-    }
-}
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/CommandSupport.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/CommandSupport.groovy
index 2794b96827..2eed51c5a1 100644
--- a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/CommandSupport.groovy
+++ b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/CommandSupport.groovy
@@ -181,10 +181,6 @@ abstract class CommandSupport implements Command {
     // Helpers
     //
 
-    protected void alias(final String name, final String shortcut) {
-        aliases << new CommandAlias(shell, name, shortcut, this.name)
-    }
-
     protected void fail(final String msg) {
         throw new CommandException(this, render(msg))
     }
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/commands/AliasCommand.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/commands/AliasCommand.groovy
deleted file mode 100644
index 520a426be4..0000000000
--- a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/commands/AliasCommand.groovy
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you 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.apache.groovy.groovysh.commands
-
-import org.apache.groovy.groovysh.Command
-import org.apache.groovy.groovysh.CommandSupport
-import org.apache.groovy.groovysh.Groovysh
-import org.apache.groovy.groovysh.completion.CommandNameCompleter
-import org.jline.reader.Completer
-
-import static org.jline.jansi.AnsiRenderer.render
-
-/**
- * The 'alias' command.
- */
-class AliasCommand
-    extends CommandSupport
-{
-    public static final String COMMAND_NAME = ':alias'
-
-    AliasCommand(final Groovysh shell) {
-        super(shell, COMMAND_NAME, ':a', )
-    }
-
-    @Override
-    protected List<Completer> createCompleters() {
-        return [
-                new CommandNameCompleter(registry, true),
-                null
-        ]
-    }
-
-    @Override
-    Object execute(final List<String> args) {
-        assert args != null
-
-        if (args.size() < 2) {
-            fail("Command 'alias' requires at least 2 arguments") // TODO: i18n
-        }
-
-        String name = args[0]
-        List target = args[1..-1]
-
-        Command command = registry.find(name)
-
-        if (command == null) {
-            command = registry.find(name)
-        }
-        if (command != null) {
-            if (command instanceof AliasTargetProxyCommand) {
-                log.debug("Rebinding alias: $name")
-
-                registry.remove(command)
-            }
-            else {
-                fail("Can not rebind non-user aliased command: ${command.name}") // TODO: i18n
-            }
-        }
-
-        log.debug("Creating alias '$name' to: $target")
-
-        // Register the command
-        command = shell << new AliasTargetProxyCommand(shell, name, target)
-
-        //
-        // TODO: Should this be here... or should this be in the Shell's impl?
-        //
-
-        // Try to install the completer
-        if (shell.runner) {
-            shell.runner.completer.add(command)
-        }
-    }
-}
-
-class AliasTargetProxyCommand
-    extends CommandSupport implements Command
-{
-    private static int counter = 0
-
-    final List<String> args
-
-    AliasTargetProxyCommand(final Groovysh shell, final String name, final List args) {
-        super(shell, name, ':a' + counter++)
-
-        assert args
-
-        this.args = args
-    }
-
-    @Override
-    String getDescription() {
-        return render("User defined alias to: @|bold ${args.join(' ')}|@")
-    }
-
-    @Override
-    String getUsage() {
-        return ''
-    }
-
-    @Override
-    String getHelp() {
-        return description
-    }
-
-    @Override
-    Object execute(final List<String> args) {
-        List<String> allArgs = this.args + args
-
-        log.debug("Executing with args: $allArgs")
-
-        //
-        // FIXME: Should go back through shell.execute() to allow aliases to groovy snips too
-        //
-
-        return shell.executeCommand(allArgs.join(' '))
-    }
-}
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/commands/ExitCommand.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/commands/ExitCommand.groovy
index efc3bcbb2c..4b34ce8de5 100644
--- a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/commands/ExitCommand.groovy
+++ b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/commands/ExitCommand.groovy
@@ -30,7 +30,7 @@ class ExitCommand extends CommandSupport {
 
     ExitCommand(final Groovysh shell) {
         super(shell, COMMAND_NAME, ':x')
-        alias(':quit', ':q')
+//        alias(':quit', ':q')
     }
 
     @Override
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/commands/HelpCommand.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/commands/HelpCommand.groovy
index 343308a060..d754ee828f 100644
--- a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/commands/HelpCommand.groovy
+++ b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/commands/HelpCommand.groovy
@@ -36,7 +36,7 @@ class HelpCommand extends CommandSupport { // TODO for this file: further i18n
     HelpCommand(final Groovysh shell) {
         super(shell, COMMAND_NAME, ':h')
 
-        alias('?', ':?')
+//        alias('?', ':?')
     }
 
     protected List<Completer> createCompleters() {
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/commands/LoadCommand.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/commands/LoadCommand.groovy
index 0754a8026f..cca596cbf4 100644
--- a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/commands/LoadCommand.groovy
+++ b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/commands/LoadCommand.groovy
@@ -32,7 +32,7 @@ class LoadCommand extends CommandSupport {
 
     LoadCommand(final Groovysh shell) {
         super(shell, COMMAND_NAME, ':l')
-        alias('.', ':.')
+//        alias('.', ':.')
     }
 
     @Override
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 746426502e..31eaf20ea3 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
@@ -20,10 +20,8 @@ package org.apache.groovy.groovysh.util
 
 import org.apache.groovy.groovysh.Command
 import org.apache.groovy.groovysh.Shell
-import org.apache.groovy.groovysh.commands.AliasCommand
 
 import org.apache.groovy.groovysh.commands.DisplayCommand
-//import org.apache.groovy.groovysh.commands.DocCommand
 import org.apache.groovy.groovysh.commands.EditCommand
 import org.apache.groovy.groovysh.commands.ExitCommand
 import org.apache.groovy.groovysh.commands.GrabCommand
@@ -60,15 +58,14 @@ class DefaultCommandsRegistrar {
             new DisplayCommand(shell),
             new ResetCommand(shell),
 //            new ClearCommand(shell),
-            new ShowCommand(shell),
-            new InspectCommand(shell),
+//            new ShowCommand(shell),
+//            new InspectCommand(shell),
             new PurgeCommand(shell),
             new EditCommand(shell),
             new LoadCommand(shell),
             new SaveCommand(shell),
             new RecordCommand(shell),
             new HistoryCommand(shell),
-            new AliasCommand(shell),
             new SetCommand(shell),
             new GrabCommand(shell),
             new RegisterCommand(shell),
diff --git a/subprojects/groovy-groovysh/src/main/resources/nanorc/groovy.nanorc b/subprojects/groovy-groovysh/src/main/resources/nanorc/groovy.nanorc
index 7626ab6aba..46ef1a9685 100644
--- a/subprojects/groovy-groovysh/src/main/resources/nanorc/groovy.nanorc
+++ b/subprojects/groovy-groovysh/src/main/resources/nanorc/groovy.nanorc
@@ -35,8 +35,8 @@ BOOLEAN:     "\<(true|false)\>"
 CONSTANT:    "\<[A-Z]+([_]{1}[A-Z]+){0,}\>"
 OPERATOR:    "[-+/*=<>?:!~%&|]"
 ~NUMBER:     "\b-?(([1-9][0-9_]*)|0)\.[0-9_e]+[dfg]?\b" "\b-?([1-9][0-9_]*)?[0-9][ilg]?\b" "\b0[0-7_]*[ilg]?\b" "\b0x([1-9a-f][0-9a-f_]*)?[0-9a-f][lg]?\b" "\b0b([01][01_]*)?[01]\b"
-STRING:      "['][^']*[^\\][']" "[']{3}.*[^\\][']{3}"
-$BALANCED_DELIMITERS:  "", """"
+#STRING:      "['][^']*[^\\][']" "[']{3}.*[^\\][']{3}"
+$BALANCED_DELIMITERS:  """", ''', ', ""
 $LINE_COMMENT:         "//"
 $BLOCK_COMMENT:        "/*, */"
 REGEXP:      "~/[^/]*/"
diff --git a/subprojects/groovy-groovysh/src/main/resources/nanorc/light.nanorctheme b/subprojects/groovy-groovysh/src/main/resources/nanorc/light.nanorctheme
index 62ae57054c..ae61f14004 100644
--- a/subprojects/groovy-groovysh/src/main/resources/nanorc/light.nanorctheme
+++ b/subprojects/groovy-groovysh/src/main/resources/nanorc/light.nanorctheme
@@ -5,6 +5,7 @@
 PLAIN       black
 FUNCTION    green
 STRING      cyan
+REGEXP      magenta
 COMMENT     brightcyan
 DOC_COMMENT cyan
 TYPE        brightblue
@@ -37,6 +38,18 @@ ROW_NUMBER  bold,!blue,~grey70
 ROW_STYLE   ,~grey82
 LIST_BACKGROUND ,~grey70
 LIST_GROUP      yellow
+RAINBOW1    brightmagenta
+RAINBOW2    brightcyan
+RAINBOW3    brightblue
+RAINBOW4    brightyellow
+RAINBOW5    brightgreen
+RAINBOW6    brightred
+RAINBOW7    magenta
+RAINBOW8    cyan
+RAINBOW9    blue
+RAINBOW10   yellow
+RAINBOW11   green
+RAINBOW12   red
 #
 # mixin
 #
diff --git a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/AllCompletersTest.groovy b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/AllCompletersTest.groovy
index 33559bf0aa..c4c3523bf6 100644
--- a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/AllCompletersTest.groovy
+++ b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/AllCompletersTest.groovy
@@ -109,7 +109,7 @@ class AllCompletersTest extends GroovyTestCase {
         assert HelpCommand.COMMAND_NAME + ' ' in result[0]
         assert ExitCommand.COMMAND_NAME in result[0]
         assert 'import ' in result[0]
-        assert ShowCommand.COMMAND_NAME + ' ' in result[0]
+//        assert ShowCommand.COMMAND_NAME + ' ' in result[0]
         assert SetCommand.COMMAND_NAME + ' ' in result[0]
         assert InspectCommand.COMMAND_NAME + ' ' in result[0]
 //        assert DocCommand.COMMAND_NAME + ' ' in result[0]
@@ -131,23 +131,23 @@ class AllCompletersTest extends GroovyTestCase {
     }
 
     void testShowVariables() {
-        String prompt = ShowCommand.COMMAND_NAME + ' variables '
-        assert [] == complete(prompt, prompt.length())
+//        String prompt = ShowCommand.COMMAND_NAME + ' variables '
+//        assert [] == complete(prompt, prompt.length())
     }
 
     void testImportJava() {
         // tests interaction with ReflectionCompleter
-        String prompt = 'import j'
-        def result = complete(prompt, prompt.length())
-        assert result
-        assert prompt.length() - 1 == result[1]
-        assert 'java.' in result[0]
+//        String prompt = 'import j'
+//        def result = complete(prompt, prompt.length())
+//        assert result
+//        assert prompt.length() - 1 == result[1]
+//        assert 'java.' in result[0]
     }
 
     void testShowVariablesJava() {
         // tests against interaction with ReflectionCompleter
-        String prompt = ShowCommand.COMMAND_NAME + ' variables java'
-        assert [] == complete(prompt, prompt.length())
+//        String prompt = ShowCommand.COMMAND_NAME + ' variables java'
+//        assert [] == complete(prompt, prompt.length())
     }
 
     void testKeyword() {
diff --git a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/CommandCompleterTest.groovy b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/CommandCompleterTest.groovy
index 9fdf2f01ec..a12527cacc 100644
--- a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/CommandCompleterTest.groovy
+++ b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/CommandCompleterTest.groovy
@@ -18,8 +18,6 @@
  */
 package org.apache.groovy.groovysh
 
-import org.apache.groovy.groovysh.commands.AliasCommand
-
 import org.apache.groovy.groovysh.commands.SaveCommand
 import org.apache.groovy.groovysh.commands.SetCommand
 import org.apache.groovy.groovysh.commands.ShowCommand
@@ -40,18 +38,18 @@ class CommandCompleterTest extends CompleterTestSupport {
         CommandRegistry registry = new CommandRegistry()
         groovyshMocker.use {
             Groovysh groovyshMock = new Groovysh()
-            AliasCommand aliasCommand = new AliasCommand(groovyshMock)
+//            AliasCommand aliasCommand = new AliasCommand(groovyshMock)
             registry.register(new SetCommand(groovyshMock))
-            registry.register(new ShowCommand(groovyshMock))
-            aliasCommand.registry = registry
-            completer.add(aliasCommand)
+//            registry.register(new ShowCommand(groovyshMock))
+//            aliasCommand.registry = registry
+//            completer.add(aliasCommand)
             completer.refresh()
 
             assert 0 == completer.complete(':a', ':a'.length(), candidates)
-            assert [':a ', AliasCommand.COMMAND_NAME + ' '] == candidates
+//            assert [':a ', AliasCommand.COMMAND_NAME + ' '] == candidates
             candidates = []
             assert 3 == completer.complete(':a ', ':a '.length(), candidates)
-            assert [':= ', ':S ', SetCommand.COMMAND_NAME + ' ', ShowCommand.COMMAND_NAME + ' '] == candidates
+//            assert [':= ', ':S ', SetCommand.COMMAND_NAME + ' ', ShowCommand.COMMAND_NAME + ' '] == candidates
         }
     }
 
@@ -131,11 +129,11 @@ class CommandCompleterTest extends CompleterTestSupport {
             Groovysh groovyshMock = new Groovysh()
             completer.add(new SaveCommand(groovyshMock))
             completer.add(new SetCommand(groovyshMock))
-            completer.add(new ShowCommand(groovyshMock))
+//            completer.add(new ShowCommand(groovyshMock))
             completer.refresh()
 
             assert 0 == completer.complete(':s', ':s'.length(), candidates)
-            assert [':s ', SaveCommand.COMMAND_NAME + ' ', SetCommand.COMMAND_NAME + ' ', ShowCommand.COMMAND_NAME + ' '] == candidates
+            assert [':s ', SaveCommand.COMMAND_NAME + ' ', SetCommand.COMMAND_NAME + ' '/*, ShowCommand.COMMAND_NAME + ' '*/] == candidates
             candidates = []
             String buffer = SaveCommand.COMMAND_NAME + ' '
             assert 6 == completer.complete(buffer, buffer.length(), candidates)
diff --git a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/AliasCommandTest.groovy b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/AliasTest.groovy
similarity index 95%
rename from subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/AliasCommandTest.groovy
rename to subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/AliasTest.groovy
index 4d38f57f3e..e6a8858b97 100644
--- a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/AliasCommandTest.groovy
+++ b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/AliasTest.groovy
@@ -20,7 +20,7 @@ package org.apache.groovy.groovysh.commands
 /**
  * Tests for the {@code /alias} command.
  */
-class AliasCommandTest extends ConsoleTestSupport {
+class AliasTest extends ConsoleTestSupport {
 
     void testAliasAndUnalias() {
         assert !console.hasAlias('foo')
diff --git a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/PurgeCommandTest.groovy b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/ClassloaderTest.groovy
similarity index 58%
rename from subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/PurgeCommandTest.groovy
rename to subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/ClassloaderTest.groovy
index 10558bae63..fd609e88d4 100644
--- a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/PurgeCommandTest.groovy
+++ b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/ClassloaderTest.groovy
@@ -19,26 +19,17 @@
 package org.apache.groovy.groovysh.commands
 
 /**
- * Tests for the {@link PurgeCommand} class.
+ * Tests for the {@code /classloader} command.
  */
-class PurgeCommandTest extends CommandTestSupport {
-    void testPurgeVariables() {
-        shell.execute(PurgeCommand.COMMAND_NAME + ' variables')
-    }
-
-    void testPurgeClasses() {
-        shell.execute(PurgeCommand.COMMAND_NAME + ' classes')
-    }
-
-    void testPurgeImports() {
-        shell.execute(PurgeCommand.COMMAND_NAME + ' imports')
-    }
-
-    void testPurgePreferences() {
-        shell.execute(PurgeCommand.COMMAND_NAME + ' preferences')
-    }
-
-    void testPurgeAll() {
-        shell.execute(PurgeCommand.COMMAND_NAME + ' all')
+class ClassloaderTest extends GroovyCommandTestSupport {
+    void testAddThenPurgeClass() {
+        assert groovy.hasCommand('/classloader')
+        assert !engine.loader.loadedClasses*.name.contains('Foo')
+        engine.execute("class Foo { }")
+        assert engine.loader.loadedClasses*.name.contains('Foo')
+        groovy.invoke(session, '/classloader', '-v')
+        assert output.find{ it.startsWith('loadedClasses=') }.contains('class Foo')
+        groovy.invoke(session, '/classloader', '-d', 'Foo')
+        assert !engine.loader.loadedClasses*.name.contains('Foo')
     }
 }
diff --git a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/ConsoleTestSupport.groovy b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/ConsoleTestSupport.groovy
index e57df7024e..b2b0ea7b1d 100644
--- a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/ConsoleTestSupport.groovy
+++ b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/ConsoleTestSupport.groovy
@@ -36,14 +36,14 @@ import java.nio.file.Path
  * Support for testing {@link ConsoleEngine} instances.
  */
 abstract class ConsoleTestSupport extends GroovyTestCase {
-    protected GroovyEngine scriptEngine = new GroovyEngine()
+    protected GroovyEngine engine = new GroovyEngine()
     private URL rootURL = Main2.getResource('/nanorc')
     private Path root = ClasspathResourceUtil.getResourcePath(rootURL)
     private Path temp = File.createTempDir().toPath()
     private ConfigurationPath configPath = new ConfigurationPath(root, temp)
     protected List<String> output = []
     protected Printer printer = new DummyPrinter(output)
-    protected ConsoleEngine console = new GroovyConsoleEngine(scriptEngine, printer, null, configPath)
+    protected ConsoleEngine console = new GroovyConsoleEngine(engine, printer, null, configPath)
     protected CommandRegistry.CommandSession session = new CommandRegistry.CommandSession()
 
     @Override
diff --git a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/ConsoleTestSupport.groovy b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/GroovyCommandTestSupport.groovy
similarity index 61%
copy from subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/ConsoleTestSupport.groovy
copy to subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/GroovyCommandTestSupport.groovy
index e57df7024e..82717efa9e 100644
--- a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/ConsoleTestSupport.groovy
+++ b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/GroovyCommandTestSupport.groovy
@@ -19,39 +19,25 @@
 package org.apache.groovy.groovysh.commands
 
 import groovy.test.GroovyTestCase
-import org.apache.groovy.groovysh.Main2
-import org.apache.groovy.groovysh.jline.GroovyConsoleEngine
+import org.apache.groovy.groovysh.jline.GroovyCommands
 import org.apache.groovy.groovysh.jline.GroovyEngine
-import org.jline.builtins.ClasspathResourceUtil
-import org.jline.builtins.ConfigurationPath
 import org.jline.console.CommandRegistry
-import org.jline.console.ConsoleEngine
 import org.jline.console.Printer
-import org.jline.reader.LineReaderBuilder
-import org.jline.reader.impl.DefaultParser
-
-import java.nio.file.Path
 
 /**
- * Support for testing {@link ConsoleEngine} instances.
+ * Support for testing commands from {@link GroovyCommands}.
  */
-abstract class ConsoleTestSupport extends GroovyTestCase {
-    protected GroovyEngine scriptEngine = new GroovyEngine()
-    private URL rootURL = Main2.getResource('/nanorc')
-    private Path root = ClasspathResourceUtil.getResourcePath(rootURL)
-    private Path temp = File.createTempDir().toPath()
-    private ConfigurationPath configPath = new ConfigurationPath(root, temp)
+abstract class GroovyCommandTestSupport extends GroovyTestCase {
+    protected GroovyEngine engine = new GroovyEngine() {
+        def getLoader() {
+            classLoader
+        }
+    }
     protected List<String> output = []
     protected Printer printer = new DummyPrinter(output)
-    protected ConsoleEngine console = new GroovyConsoleEngine(scriptEngine, printer, null, configPath)
+    protected CommandRegistry groovy = new GroovyCommands(engine, printer)
     protected CommandRegistry.CommandSession session = new CommandRegistry.CommandSession()
 
-    @Override
-    void setUp() {
-        super.setUp()
-        console.lineReader = LineReaderBuilder.builder().parser(new DefaultParser()).build()
-    }
-
     static class DummyPrinter implements Printer {
         DummyPrinter(List<String> output) {
             this.output = output
@@ -60,6 +46,14 @@ abstract class ConsoleTestSupport extends GroovyTestCase {
 
         @Override
         void println(Map<String, Object> options, Object object) {
+            // a bit ugly to partially replicate the logic from
+            // DefaultPrinter here, but it isn't easy to mock out
+            if (object instanceof GroovyEngine.EngineClassLoader) {
+                options?.columns?.each { col ->
+                    output << "$col=" + object."$col"
+                }
+                return
+            }
             output << object.toString()
         }
 
diff --git a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/ShowCommandTest.groovy b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/ShowCommandTest.groovy
index 0256730c70..b58380a7b1 100644
--- a/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/ShowCommandTest.groovy
+++ b/subprojects/groovy-groovysh/src/test/groovy/org/apache/groovy/groovysh/commands/ShowCommandTest.groovy
@@ -22,7 +22,7 @@ package org.apache.groovy.groovysh.commands
  * Tests for the /show command.
  */
 class ShowCommandTest extends ConsoleTestSupport {
-    void testShow() {
+    void testShowVariable() {
         assert !console.hasVariable('foo')
         console.execute('dummyName', "foo = 'bar'")
         assert console.hasVariable('foo')