Skip to content

Commit

Permalink
Merge branch 'master' into id-prefix-delete-command
Browse files Browse the repository at this point in the history
  • Loading branch information
jessica2828 authored Oct 23, 2024
2 parents 328e203 + 6b2f31f commit 5d50380
Show file tree
Hide file tree
Showing 3 changed files with 199 additions and 0 deletions.
34 changes: 34 additions & 0 deletions src/main/java/seedu/address/ui/CommandBox.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.Region;
import seedu.address.logic.commands.CommandResult;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.ui.util.CommandHistory;

/**
* The UI component that is responsible for receiving user command inputs.
Expand All @@ -17,6 +20,7 @@ public class CommandBox extends UiPart<Region> {
private static final String FXML = "CommandBox.fxml";

private final CommandExecutor commandExecutor;
private final CommandHistory commandHistory;

@FXML
private TextField commandTextField;
Expand All @@ -27,8 +31,13 @@ public class CommandBox extends UiPart<Region> {
public CommandBox(CommandExecutor commandExecutor) {
super(FXML);
this.commandExecutor = commandExecutor;
this.commandHistory = new CommandHistory();

// calls #setStyleToDefault() whenever there is a change to the text of the command box.
commandTextField.textProperty().addListener((unused1, unused2, unused3) -> setStyleToDefault());

// Add key press event handler
commandTextField.addEventFilter(KeyEvent.KEY_PRESSED, this::handleKeyPressed);
}

/**
Expand All @@ -43,12 +52,37 @@ private void handleCommandEntered() {

try {
commandExecutor.execute(commandText);
commandHistory.addCommand(commandText); // Add to history
commandTextField.setText("");
} catch (CommandException | ParseException e) {
setStyleToIndicateCommandFailure();
}
}

/**
* Handles key press events for navigating command history.
* @param event The KeyEvent to handle.
*/
private void handleKeyPressed(KeyEvent event) {
if (event.getCode() == KeyCode.UP) {
String previousCommand = commandHistory.getPreviousCommand();
if (previousCommand != null) {
commandTextField.setText(previousCommand);
commandTextField.positionCaret(commandTextField.getText().length());
}
event.consume();
} else if (event.getCode() == KeyCode.DOWN) {
String nextCommand = commandHistory.getNextCommand();
if (nextCommand != null) {
commandTextField.setText(nextCommand);
commandTextField.positionCaret(commandTextField.getText().length());
} else {
commandTextField.clear();
}
event.consume();
}
}

/**
* Sets the command box style to use the default style.
*/
Expand Down
60 changes: 60 additions & 0 deletions src/main/java/seedu/address/ui/util/CommandHistory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package seedu.address.ui.util;

import java.util.ArrayList;
import java.util.List;

/**
* Manages the history of commands entered by the user.
*/
public class CommandHistory {
private final List<String> commandHistory;
private int historyIndex;

/**
* Constructs a {@code CommandHistory} object.
*/
public CommandHistory() {
commandHistory = new ArrayList<>();
historyIndex = -1; // Start with no commands
}

/**
* Adds a command to the history.
* Resets the index to point to the latest command.
*
* @param command The command to be added to the history.
*/
public void addCommand(String command) {
commandHistory.add(command);
historyIndex = commandHistory.size(); // Reset to end of list
}

/**
* Returns the previous command in history.
* If at the start, it returns null.
*
* @return The previous command, or null if at the start of the list.
*/
public String getPreviousCommand() {
if (historyIndex > 0) {
historyIndex--;
return commandHistory.get(historyIndex);
}
return null; // No previous command
}

/**
* Returns the next command in history.
* If at the end, it returns null.
*
* @return The next command, or null if at the end of the list.
*/
public String getNextCommand() {
if (historyIndex < commandHistory.size() - 1) {
historyIndex++;
return commandHistory.get(historyIndex);
}
historyIndex = commandHistory.size(); // Reset to end
return null; // No next command
}
}
105 changes: 105 additions & 0 deletions src/test/java/seedu/address/ui/CommandHistoryTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package seedu.address.ui;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import seedu.address.ui.util.CommandHistory;

/**
* Unit tests for {@code CommandHistory}.
*/
public class CommandHistoryTest {

private CommandHistory commandHistory;

@BeforeEach
public void setUp() {
commandHistory = new CommandHistory();
}

@Test
public void addCommand_singleCommand_success() {
commandHistory.addCommand("first command");
assertEquals("first command", commandHistory.getPreviousCommand());
}

@Test
public void addCommand_multipleCommands_success() {
commandHistory.addCommand("first command");
commandHistory.addCommand("second command");
commandHistory.addCommand("third command");

assertEquals("third command", commandHistory.getPreviousCommand());
assertEquals("second command", commandHistory.getPreviousCommand());
assertEquals("first command", commandHistory.getPreviousCommand());
}

@Test
public void getPreviousCommand_noHistory_returnsNull() {
assertNull(commandHistory.getPreviousCommand());
}

@Test
public void getPreviousCommand_atStartOfHistory_returnsNull() {
commandHistory.addCommand("first command");

// Move to the start of the history
commandHistory.getPreviousCommand();
assertNull(commandHistory.getPreviousCommand());
}

@Test
public void getNextCommand_noHistory_returnsNull() {
assertNull(commandHistory.getNextCommand());
}

@Test
public void getNextCommand_atEndOfHistory_returnsNull() {
commandHistory.addCommand("first command");
commandHistory.addCommand("second command");

// Move to the start of history
commandHistory.getPreviousCommand();
commandHistory.getPreviousCommand();

// Move forward to the end of history
commandHistory.getNextCommand();
commandHistory.getNextCommand();
assertNull(commandHistory.getNextCommand());
}

@Test
public void getNextCommand_fromMiddleOfHistory_success() {
commandHistory.addCommand("first command");
commandHistory.addCommand("second command");
commandHistory.addCommand("third command");

// Move to the start of history
commandHistory.getPreviousCommand();
commandHistory.getPreviousCommand();
commandHistory.getPreviousCommand();

// Move forward one step in history
assertEquals("second command", commandHistory.getNextCommand());
}

@Test
public void addCommand_afterNavigatingHistory_resetsHistoryIndex() {
commandHistory.addCommand("first command");
commandHistory.addCommand("second command");

// Move to the start of history
commandHistory.getPreviousCommand();
commandHistory.getPreviousCommand();

// Add a new command
commandHistory.addCommand("new command");

// New command should be at the end of history
assertEquals("new command", commandHistory.getPreviousCommand());
assertNull(commandHistory.getNextCommand()); // At the end of history
}
}

0 comments on commit 5d50380

Please sign in to comment.