From de27ea6095f3f36f8939af0aaeaf9362e3c61490 Mon Sep 17 00:00:00 2001
From: Harold Mciver <haroldmciver@google.com>
Date: Fri, 18 Jul 2025 00:55:29 -0400
Subject: feat(cli): allow executing commands on perfect match (#4397)

Co-authored-by: Jenna Inouye <jinouye@google.com>
---
 .../cli/src/ui/components/InputPrompt.test.tsx     | 33 +++++++++++-----------
 1 file changed, 17 insertions(+), 16 deletions(-)

(limited to 'packages/cli/src/ui/components/InputPrompt.test.tsx')

diff --git a/packages/cli/src/ui/components/InputPrompt.test.tsx b/packages/cli/src/ui/components/InputPrompt.test.tsx
index e1d68125..1a100c36 100644
--- a/packages/cli/src/ui/components/InputPrompt.test.tsx
+++ b/packages/cli/src/ui/components/InputPrompt.test.tsx
@@ -9,7 +9,7 @@ import { InputPrompt, InputPromptProps } from './InputPrompt.js';
 import type { TextBuffer } from './shared/text-buffer.js';
 import { Config } from '@google/gemini-cli-core';
 import { CommandContext, SlashCommand } from '../commands/types.js';
-import { vi } from 'vitest';
+import { describe, it, expect, beforeEach, vi } from 'vitest';
 import { useShellHistory } from '../hooks/useShellHistory.js';
 import { useCompletion } from '../hooks/useCompletion.js';
 import { useInputHistory } from '../hooks/useInputHistory.js';
@@ -341,7 +341,7 @@ describe('InputPrompt', () => {
     });
   });
 
-  it('should complete a partial parent command and add a space', async () => {
+  it('should complete a partial parent command', async () => {
     // SCENARIO: /mem -> Tab
     mockedUseCompletion.mockReturnValue({
       ...mockCompletion,
@@ -357,12 +357,12 @@ describe('InputPrompt', () => {
     stdin.write('\t'); // Press Tab
     await wait();
 
-    expect(props.buffer.setText).toHaveBeenCalledWith('/memory ');
+    expect(props.buffer.setText).toHaveBeenCalledWith('/memory');
     unmount();
   });
 
-  it('should append a sub-command when the parent command is already complete with a space', async () => {
-    // SCENARIO: /memory  -> Tab (to accept 'add')
+  it('should append a sub-command when the parent command is already complete', async () => {
+    // SCENARIO: /memory -> Tab (to accept 'add')
     mockedUseCompletion.mockReturnValue({
       ...mockCompletion,
       showSuggestions: true,
@@ -380,13 +380,12 @@ describe('InputPrompt', () => {
     stdin.write('\t'); // Press Tab
     await wait();
 
-    expect(props.buffer.setText).toHaveBeenCalledWith('/memory add ');
+    expect(props.buffer.setText).toHaveBeenCalledWith('/memory add');
     unmount();
   });
 
   it('should handle the "backspace" edge case correctly', async () => {
-    // SCENARIO: /memory  -> Backspace -> /memory -> Tab (to accept 'show')
-    // This is the critical bug we fixed.
+    // SCENARIO: /memory -> Backspace -> /memory -> Tab (to accept 'show')
     mockedUseCompletion.mockReturnValue({
       ...mockCompletion,
       showSuggestions: true,
@@ -405,8 +404,8 @@ describe('InputPrompt', () => {
     stdin.write('\t'); // Press Tab
     await wait();
 
-    // It should NOT become '/show '. It should correctly become '/memory show '.
-    expect(props.buffer.setText).toHaveBeenCalledWith('/memory show ');
+    // It should NOT become '/show'. It should correctly become '/memory show'.
+    expect(props.buffer.setText).toHaveBeenCalledWith('/memory show');
     unmount();
   });
 
@@ -426,7 +425,7 @@ describe('InputPrompt', () => {
     stdin.write('\t'); // Press Tab
     await wait();
 
-    expect(props.buffer.setText).toHaveBeenCalledWith('/chat resume fix-foo ');
+    expect(props.buffer.setText).toHaveBeenCalledWith('/chat resume fix-foo');
     unmount();
   });
 
@@ -446,7 +445,7 @@ describe('InputPrompt', () => {
     await wait();
 
     // The app should autocomplete the text, NOT submit.
-    expect(props.buffer.setText).toHaveBeenCalledWith('/memory ');
+    expect(props.buffer.setText).toHaveBeenCalledWith('/memory');
 
     expect(props.onSubmit).not.toHaveBeenCalled();
     unmount();
@@ -471,10 +470,10 @@ describe('InputPrompt', () => {
     const { stdin, unmount } = render(<InputPrompt {...props} />);
     await wait();
 
-    stdin.write('\t'); // Press Tab
+    stdin.write('\t'); // Press Tab for autocomplete
     await wait();
 
-    expect(props.buffer.setText).toHaveBeenCalledWith('/help ');
+    expect(props.buffer.setText).toHaveBeenCalledWith('/help');
     unmount();
   });
 
@@ -505,7 +504,6 @@ describe('InputPrompt', () => {
     await wait();
 
     expect(props.onSubmit).toHaveBeenCalledWith('/clear');
-    expect(props.buffer.setText).not.toHaveBeenCalledWith('/clear ');
     unmount();
   });
 
@@ -530,7 +528,10 @@ describe('InputPrompt', () => {
   });
 
   it('should add a newline on enter when the line ends with a backslash', async () => {
-    props.buffer.setText('first line\\');
+    // This test simulates multi-line input, not submission
+    mockBuffer.text = 'first line\\';
+    mockBuffer.cursor = [0, 11];
+    mockBuffer.lines = ['first line\\'];
 
     const { stdin, unmount } = render(<InputPrompt {...props} />);
     await wait();
-- 
cgit v1.2.3

