Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions internal/logged_shell_asserter/logged_shell_asserter.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,19 +116,20 @@ func (a *LoggedShellAsserter) onAssertionSuccess(startRowIndex int, processedRow
}

func (a *LoggedShellAsserter) logAssertionError(err assertions.AssertionError) {
a.logRows(a.lastLoggedRowIndex+1, err.ErrorRowIndex+1)
a.logRows(a.lastLoggedRowIndex+1, err.ErrorRowIndex)
a.Shell.GetLogger().Errorf("%s", err.Message)
a.logRows(err.ErrorRowIndex+1, len(a.Shell.GetScreenState()))
a.logRows(err.ErrorRowIndex+1, len(a.Shell.GetScreenState())-1)
}

func (a *LoggedShellAsserter) LogRemainingOutput() {
startRowIndex := a.lastLoggedRowIndex + 1
endRowIndex := len(a.Shell.GetScreenState())
endRowIndex := len(a.Shell.GetScreenState()) - 1
a.logRows(startRowIndex, endRowIndex)
a.lastLoggedRowIndex = endRowIndex
}

func (a *LoggedShellAsserter) logRows(startRowIndex int, endRowIndex int) {
for i := startRowIndex; i < endRowIndex; i++ {
for i := startRowIndex; i <= endRowIndex; i++ {
rawRow := a.Shell.GetScreenState()[i]
cleanedRow := virtual_terminal.BuildCleanedRow(rawRow)
if len(cleanedRow) > 0 {
Expand Down
6 changes: 6 additions & 0 deletions internal/stage4.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"strings"

"github.com/codecrafters-io/shell-tester/internal/condition_reader"
"github.com/codecrafters-io/shell-tester/internal/logged_shell_asserter"
"github.com/codecrafters-io/shell-tester/internal/shell_executable"
"github.com/codecrafters-io/shell-tester/internal/test_cases"
Expand Down Expand Up @@ -43,10 +44,15 @@ func testExit(stageHarness *test_case_harness.TestCaseHarness) error {
readErr := shell.ReadUntilConditionOrTimeout(utils.AsBool(assertFn), logged_shell_asserter.SUBSEQUENT_READ_TIMEOUT)
output := virtual_terminal.BuildCleanedRow(shell.GetScreenState()[asserter.GetLastLoggedRowIndex()+1])

asserter.LogRemainingOutput()

// We're expecting EOF since the program should've terminated
if !errors.Is(readErr, shell_executable.ErrProgramExited) {

if readErr == nil {
return fmt.Errorf("Expected program to exit with 0 exit code, program is still running.")
} else if errors.Is(readErr, condition_reader.ErrConditionNotMet) {
return fmt.Errorf("Expected program to exit with 0 exit code, program is still running.")
} else {
// TODO: Other than ErrProgramExited, what other errors could we get? Are they user errors or internal errors?
return fmt.Errorf("Error reading output: %v", readErr)
Expand Down
7 changes: 7 additions & 0 deletions internal/stages_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ func TestStages(t *testing.T) {
StdoutFixturePath: "./test_helpers/fixtures/escape_codes",
NormalizeOutputFunc: normalizeTesterOutput,
},
"exit_error_fail": {
UntilStageSlug: "pn5",
CodePath: "./test_helpers/scenarios/exit_error",
ExpectedExitCode: 1,
StdoutFixturePath: "./test_helpers/fixtures/exit_error",
NormalizeOutputFunc: normalizeTesterOutput,
},
"base_pass_bash": {
UntilStageSlug: "ip1",
CodePath: "./test_helpers/bash",
Expand Down
8 changes: 4 additions & 4 deletions internal/test_helpers/fixtures/bash/base/pass
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ Debug = true
[stage-7] [setup] - my_exe
[stage-7] Running ./your_shell.sh
[your-program] $ type cat
[your-program] cat is /bin/cat
[your-program] cat is /usr/bin/cat
[stage-7] ✓ Received expected response
[your-program] $ type cp
[your-program] cp is /bin/cp
[your-program] cp is /usr/bin/cp
[stage-7] ✓ Received expected response
[your-program] $ type mkdir
[your-program] mkdir is /bin/mkdir
[your-program] mkdir is /usr/bin/mkdir
[stage-7] ✓ Received expected response
[your-program] $ type my_exe
[your-program] my_exe is /tmp/foo/my_exe
Expand Down Expand Up @@ -78,9 +78,9 @@ Debug = true
[your-program] bash: invalid_strawberry_command: command not found
[stage-4] ✓ Received command not found message
[your-program] $ exit 0
[your-program] exit
[stage-4] ✓ Program exited successfully
[stage-4] ✓ No output after exit command
[your-program] exit
[stage-4] Test passed.

[stage-3] Running tests for Stage #3: ff0
Expand Down
8 changes: 4 additions & 4 deletions internal/test_helpers/fixtures/bash/navigation/pass
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@ Debug = true
[stage-7] [setup] - my_exe
[stage-7] Running ./your_shell.sh
[your-program] $ type cat
[your-program] cat is /bin/cat
[your-program] cat is /usr/bin/cat
[stage-7] ✓ Received expected response
[your-program] $ type cp
[your-program] cp is /bin/cp
[your-program] cp is /usr/bin/cp
[stage-7] ✓ Received expected response
[your-program] $ type mkdir
[your-program] mkdir is /bin/mkdir
[your-program] mkdir is /usr/bin/mkdir
[stage-7] ✓ Received expected response
[your-program] $ type my_exe
[your-program] my_exe is /tmp/quz/my_exe
Expand Down Expand Up @@ -134,9 +134,9 @@ Debug = true
[your-program] bash: invalid_mango_command: command not found
[stage-4] ✓ Received command not found message
[your-program] $ exit 0
[your-program] exit
[stage-4] ✓ Program exited successfully
[stage-4] ✓ No output after exit command
[your-program] exit
[stage-4] Test passed.

[stage-3] Running tests for Stage #3: ff0
Expand Down
12 changes: 12 additions & 0 deletions internal/test_helpers/fixtures/exit_error
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Debug = true

[stage-4] Running tests for Stage #4: pn5
[stage-4] Running ./your_shell.sh
[your-program] $ invalid_apple_command
[your-program] invalid_apple_command: command not found
[stage-4] ✓ Received command not found message
[your-program] $ exit 0
[your-program] exit: command not found
[your-program] $
[stage-4] Expected program to exit with 0 exit code, program is still running.
[stage-4] Test failed
5 changes: 5 additions & 0 deletions internal/test_helpers/scenarios/exit_error/codecrafters.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Set this to true if you want debug logs.
#
# These can be VERY verbose, so we suggest turning them off
# unless you really need them.
debug: true
22 changes: 22 additions & 0 deletions internal/test_helpers/scenarios/exit_error/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import sys


def main():
while True:
sys.stdout.write("$ ")
sys.stdout.flush()

command = input().strip()
parts = command.split(" ")
cmd = parts[0]
args = parts[1:]

if cmd == "exitt":
sys.exit(0)
else:
sys.stdout.write(f"{cmd}: command not found\n")
sys.stdout.flush()


if __name__ == "__main__":
main()
8 changes: 8 additions & 0 deletions internal/test_helpers/scenarios/exit_error/your_shell.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh
#
# DON'T EDIT THIS!
#
# CodeCrafters uses this file to test your code. Don't make any changes here!
#
# DON'T EDIT THIS!
exec python3 $(dirname "$0")/main.py "$@"