public void DoNotRemoveHistoricalCommandWhenUnderLimitTest() { var terminalState = new TerminalState(); var terminalCommand = new TerminalCommand { TerminalCommandInput = "testInput", TerminalCommandOutput = "testOutput" }; var isHistoryLimitSet = terminalState.TrySetCommandHistoryLimit(5); var isAddSuccess = terminalState.TryAddHistoricalCommand(terminalCommand); var isRemoveSuccess = terminalState.TryRemoveOldestHistoricalCommand(); var previousCommands = terminalState.GetPreviousTerminalCommands(); Assert.IsTrue(isHistoryLimitSet); Assert.IsTrue(isAddSuccess); Assert.IsFalse(isRemoveSuccess); Assert.IsTrue(previousCommands.Contains(terminalCommand)); Assert.IsNotEmpty(previousCommands); }
// Game Loop - Executed Once Per Frame public void Update() { // First, figure out if the user has done anything to modify the input var isUpArrowPressed = Input.GetKeyDown(KeyCode.UpArrow); var isDownArrowPressed = Input.GetKeyDown(KeyCode.DownArrow); var userInputString = Input.inputString; var userInteraction = _userInterfaceController.GetUserInteraction(userInputString, isUpArrowPressed, isDownArrowPressed, _terminalState); // Next, if the user submitted input as part of their interactions, attempt to validate and execute what they submitted if (userInteraction.IsInputSubmitted) { // Need to get the current directory before we execute the command since it could change the current directory var currentDirectory = _fileSystemState.GetCurrentDirectory(); var userInteractionResponse = new StringBuilder(); // Since the user submitted input, we now need to parse that input Debug.Log($"User input submitted: `{userInteraction.SubmittedInput}`"); var isParseInputSuccess = _userInputParser.TryParseUserInput(userInteraction.SubmittedInput, out var parsedUserSubmittedInput); if (!isParseInputSuccess) { Debug.Log($"Failed to parse user input: `{userInteraction.SubmittedInput}`"); } // Extract the arguments into a parameterized array var args = parsedUserSubmittedInput.Arguments?.ToArray(); // Check to see that the we can retrieve the command the user wants to execute from the parsed input var isCommandRetrievedSuccess = _commandController.TryGetCommand(_commandState, parsedUserSubmittedInput.CommandName, out var command); if (!isCommandRetrievedSuccess) { userInteractionResponse.AppendLine($"Command `{parsedUserSubmittedInput.CommandName}` not found."); userInteractionResponse.AppendLine($"Run `{_helpCommandName}` for a list of available commands"); } // Execute the command if we successfully retrieved it // Note - Each command is in charge of its own validation and if / how it executes after succeeding or failing validation else { var commandResponse = command.ExecuteCommand(args); userInteractionResponse.AppendLine(commandResponse); } // Mark that the user's output will change based on this latest terminal command userInteraction.IsOutputModified = true; var terminalCommand = new TerminalCommand { TerminalCommandNumber = _terminalState.GetTerminalCommandSubmissionNumber(), TerminalCommandPath = _directoryController.GetDirectoryPath(currentDirectory), TerminalCommandInput = userInteraction.SubmittedInput, TerminalCommandOutput = userInteractionResponse.ToString(), // If the command was a valid `clear` command, we do not want to show output for it, otherwise we do want output visible IsVisibleInTerminal = command == null || command.GetType() != typeof(ClearCommand) || !command.TryValidateArguments(out _, args) }; _terminalState.IncrementTerminalCommandSubmissionNumber(); // Add the input to the list of historical inputs if it is a valid input (not empty, null, or over the character limit) if (_terminalState.TryValidateInput(userInteraction.SubmittedInput, out var validSubmittedInput)) { var isAddHistoricalInputSuccess = _terminalState.TryAddHistoricalCommand(terminalCommand); if (!isAddHistoricalInputSuccess && _terminalState.TryRemoveOldestHistoricalCommand()) { isAddHistoricalInputSuccess = _terminalState.TryAddHistoricalCommand(terminalCommand); } Debug.Assert(isAddHistoricalInputSuccess, $"Failed to add valid historical input: {validSubmittedInput} with output: {userInteractionResponse}"); } } // Next, if the user has modified input, make sure that is reflected back in the UI if (userInteraction.IsInputModified) { // Grab the current directory after the command has executed, because the command could have changed the current directory var currentDirectory = _fileSystemState.GetCurrentDirectory(); var currentDirectoryPath = _directoryController.GetDirectoryPath(currentDirectory); _userInterfaceController.SetUserInterfaceTextWithInputPrompt(InputTextObject, userInteraction.ModifiedInput, currentDirectoryPath); } // Finally, if the user's input requires a corresponding change in output, reflect that in the UI if (userInteraction.IsOutputModified) { // If a command was submitted, it has already been added to the previous commands with relevant output // We can construct full output to the user with the list of previous commands var previousTerminalCommands = _terminalState.GetPreviousTerminalCommands(); userInteraction.ModifiedOutput = _userInterfaceController.BuildUserInterfaceText(previousTerminalCommands); _userInterfaceController.SetUserInterfaceText(OutputTextObject, userInteraction.ModifiedOutput); } }