Skip to content

Send usage message from /pl add instead of throwing on empty args - #15

Merged
dmccoystephenson merged 1 commit into
mainfrom
feature/add-command-empty-args-guard
Aug 7, 2026
Merged

Send usage message from /pl add instead of throwing on empty args#15
dmccoystephenson merged 1 commit into
mainfrom
feature/add-command-empty-args-guard

Conversation

@dmccoystephenson

Copy link
Copy Markdown
Member

Summary

  • An args.length == 0 guard is added to AddCommand.execute(CommandSender, String[]). Previously the empty array was passed straight into ArgumentParser.getArgumentsInsideDoubleQuotes(args), which throws IllegalArgumentException: Arguments not valid.; the usage message Usage: /pl add "line of lore" is now sent and false returned instead.
  • The guard mirrors the pattern already present in EditCommand and RemoveCommand, restoring parity across the add/edit/remove trio for empty-argument handling.
  • The characterization test execute_missingArgs_throwsInsteadOfSendingUsageMessage, which asserted the buggy behaviour, is replaced by execute_rejectsMissingArgs, named and shaped to match the equivalent tests in EditCommandTest and RemoveCommandTest. The exact usage string is asserted so that drift is caught.
  • A [Unreleased] / Fixed entry is added to CHANGELOG.md.

Test plan

  • mvn -o clean test — 19 tests, 0 failures, 0 errors.
  • Regression evidence collected empirically: with the AddCommand.java change stashed, execute_rejectsMissingArgs errors with IllegalArgumentException: Arguments not valid.; with the change restored, it passes.
  • Documentation sources of truth re-checked against the implementation. HelpCommand.java, COMMANDS.md, USER_GUIDE.md, and CONFIG.md describe no syntax, permission, or config surface that this change alters, so only CHANGELOG.md required updating.
  • In-game smoke test of /pl add with no arguments on a live Spigot server. The CI workflow builds and runs the unit suite only; no server-backed test exists in this repository.

Notes on unquoted arguments

ArgumentParser.getArgumentsInsideDoubleQuotes was probed directly to confirm the guard is placed correctly. Inputs {"foo"}, {"foo", "bar"}, and {"\"unterminated"} all return an empty list rather than throwing, so the pre-existing doubleQuoteArgs.size() == 0 branch already handles those cases. Only the genuinely empty array threw, which is exactly what this guard now intercepts.

Issues deferred this cycle

Three findings were filed during triage and deliberately not implemented here, so that this PR stays scoped to a single bug fix:

Closes #10


This PR description was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).

AddCommand passed args straight into ArgumentParser.getArgumentsInsideDoubleQuotes,
which throws IllegalArgumentException when the array is empty. EditCommand and
RemoveCommand already guard against an empty args array before parsing; AddCommand
now does the same and sends its usage message.

The characterization test that asserted the thrown exception is replaced with a
regression test matching the sibling execute_rejectsMissingArgs tests.

Closes #10

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@dmccoystephenson

Copy link
Copy Markdown
Member Author

Self-review rubric

Scored against the diff and against command output, on head bf88b7b.

  • Scope: PASS — three files are touched, and each is required: AddCommand.java carries the fix, AddCommandTest.java carries its regression test, and CHANGELOG.md is a mandated documentation source of truth. The removal of the assertThrows static import is a direct consequence of removing its only remaining use; no unrelated formatting, rename, or comment churn is present.
  • Tests-new: PASS — no new public method is introduced. The modified method AddCommand.execute(CommandSender, String[]) is exercised by execute_rejectsMissingArgs plus the four pre-existing tests in the class.
  • Tests-fix: PASS — confirmed empirically rather than by reasoning. With src/main/java/dansplugins/playerlore/commands/AddCommand.java stashed, execute_rejectsMissingArgs errored with java.lang.IllegalArgumentException: Arguments not valid. at AddCommandTest.java:69 and the build failed; after the stash was popped, mvn -o clean test reported 19 tests, 0 failures, 0 errors.
  • Sibling structure: PASS (vacuous) — no new file is created by this PR, so the directory-convention rule has nothing to apply to. Recorded rather than silently skipped.
  • Sibling renames: PASS — the test method was renamed from execute_missingArgs_throwsInsteadOfSendingUsageMessage to execute_rejectsMissingArgs. That name is the existing member of a parallel series: EditCommandTest.execute_rejectsMissingArgs and RemoveCommandTest.execute_rejectsMissingArgs already exist under it. The rename joins the series rather than diverging from it, so no sibling requires a matching rename.
  • Docs: PASS — every row of the documentation sources-of-truth table was checked against the implementation. HelpCommand.java advertises /pl add "line of lore", which the new guard's message reproduces verbatim. COMMANDS.md documents /pl add "<line of lore>", unchanged by this PR and internally consistent with its own <lineIndex> placeholder convention. USER_GUIDE.md (workflow and permissions table) and CONFIG.md describe no surface this change alters. CHANGELOG.md gains one [Unreleased] / Fixed entry describing the change accurately.
  • Issue resolution: PASS — the surface area named in AddCommand throws uncaught exception instead of usage message when args are missing #10 is AddCommand.execute(CommandSender, String[]) and its missing args.length == 0 guard, which is exactly what changed. The issue offered Line of lore must be designated between double quotes. "or similar" as the message; the usage string was chosen instead, because the issue's own stated goal was to match the EditCommand/RemoveCommand pattern, and both of those send their usage strings from the equivalent guard.
  • CI: PASS — the build check passed in 26s on head bf88b7b (run 31163937734). This is the external anchor and it was confirmed green before the rubric was started.
  • Command trio parity: PASS — validation logic changed in AddCommand.java, so EditCommand.java and RemoveCommand.java were both read in full. Each already contains the equivalent if (args.length == 0) guard sending its own usage string, so neither requires a corresponding change. This PR closes the gap rather than opening one.

Findings not scored as rubric failures

An all-PASS rubric warrants scrutiny, so the following were looked for specifically and are recorded as observations rather than blockers.

  • src/main/java/dansplugins/playerlore/commands/AddCommand.java:42 — the literal "Usage: /pl add \"line of lore\"" is now duplicated, appearing both here and at line 28 in execute(CommandSender). A future edit to one occurrence can silently drift from the other. This was left as-is deliberately: the identical duplication already exists in EditCommand and RemoveCommand, so extracting a constant in AddCommand alone would break trio consistency, and extracting it across all three is a refactor outside the scope of AddCommand throws uncaught exception instead of usage message when args are missing #10. A follow-up issue is suggested if the duplication is considered worth removing.
  • src/test/java/dansplugins/playerlore/commands/AddCommandTest.java — no test covers the non-empty-but-unquoted input path (the doubleQuoteArgs.size() == 0 branch at AddCommand.java:43), such as /pl add hello. That branch was confirmed reachable and correct by probing ArgumentParser.getArgumentsInsideDoubleQuotes directly, which returned an empty list for {"foo"}, {"foo", "bar"}, and {"\"unterminated"} rather than throwing. The same gap exists in EditCommandTest. Adding this coverage was left out to keep the PR scoped to one bug fix; a follow-up issue is being filed.
  • No automated coverage exists for the real in-game invocation path. The build workflow compiles and runs the unit suite only; a player typing /pl add reaches this method through Ponder's CommandService, which no test exercises. A live Spigot smoke test remains the only way to verify that end of the path, and it is listed unchecked in the PR's test plan.

Verdict: every rubric item passes with evidence, and the three observations above are maintainability and coverage notes rather than defects in this change.


This review was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).

@dmccoystephenson
dmccoystephenson merged commit 47b8f19 into main Aug 7, 2026
1 check passed
@dmccoystephenson
dmccoystephenson deleted the feature/add-command-empty-args-guard branch August 7, 2026 09:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AddCommand throws uncaught exception instead of usage message when args are missing

1 participant