Skip to content

Commit f8d9cbf

Browse files
authored
Merge pull request #120 from codecrafters-io/arpan/cc-1667-fix-incorrect-shell-tester-message-for-stage-pn5
The error messages should be more descriptive now
2 parents ccb05ad + 509220b commit f8d9cbf

File tree

9 files changed

+73
-12
lines changed

9 files changed

+73
-12
lines changed

internal/logged_shell_asserter/logged_shell_asserter.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -116,19 +116,20 @@ func (a *LoggedShellAsserter) onAssertionSuccess(startRowIndex int, processedRow
116116
}
117117

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

124124
func (a *LoggedShellAsserter) LogRemainingOutput() {
125125
startRowIndex := a.lastLoggedRowIndex + 1
126-
endRowIndex := len(a.Shell.GetScreenState())
126+
endRowIndex := len(a.Shell.GetScreenState()) - 1
127127
a.logRows(startRowIndex, endRowIndex)
128+
a.lastLoggedRowIndex = endRowIndex
128129
}
129130

130131
func (a *LoggedShellAsserter) logRows(startRowIndex int, endRowIndex int) {
131-
for i := startRowIndex; i < endRowIndex; i++ {
132+
for i := startRowIndex; i <= endRowIndex; i++ {
132133
rawRow := a.Shell.GetScreenState()[i]
133134
cleanedRow := virtual_terminal.BuildCleanedRow(rawRow)
134135
if len(cleanedRow) > 0 {

internal/stage4.go

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"strings"
77

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

47+
asserter.LogRemainingOutput()
48+
4649
// We're expecting EOF since the program should've terminated
4750
if !errors.Is(readErr, shell_executable.ErrProgramExited) {
51+
4852
if readErr == nil {
4953
return fmt.Errorf("Expected program to exit with 0 exit code, program is still running.")
54+
} else if errors.Is(readErr, condition_reader.ErrConditionNotMet) {
55+
return fmt.Errorf("Expected program to exit with 0 exit code, program is still running.")
5056
} else {
5157
// TODO: Other than ErrProgramExited, what other errors could we get? Are they user errors or internal errors?
5258
return fmt.Errorf("Error reading output: %v", readErr)

internal/stages_test.go

+7
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ func TestStages(t *testing.T) {
3434
StdoutFixturePath: "./test_helpers/fixtures/escape_codes",
3535
NormalizeOutputFunc: normalizeTesterOutput,
3636
},
37+
"exit_error_fail": {
38+
UntilStageSlug: "pn5",
39+
CodePath: "./test_helpers/scenarios/exit_error",
40+
ExpectedExitCode: 1,
41+
StdoutFixturePath: "./test_helpers/fixtures/exit_error",
42+
NormalizeOutputFunc: normalizeTesterOutput,
43+
},
3744
"base_pass_bash": {
3845
UntilStageSlug: "ip1",
3946
CodePath: "./test_helpers/bash",

internal/test_helpers/fixtures/bash/base/pass

+4-4
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ Debug = true
2121
[stage-7] [setup] - my_exe
2222
[stage-7] Running ./your_shell.sh
2323
[your-program] $ type cat
24-
[your-program] cat is /bin/cat
24+
[your-program] cat is /usr/bin/cat
2525
[stage-7] ✓ Received expected response
2626
[your-program] $ type cp
27-
[your-program] cp is /bin/cp
27+
[your-program] cp is /usr/bin/cp
2828
[stage-7] ✓ Received expected response
2929
[your-program] $ type mkdir
30-
[your-program] mkdir is /bin/mkdir
30+
[your-program] mkdir is /usr/bin/mkdir
3131
[stage-7] ✓ Received expected response
3232
[your-program] $ type my_exe
3333
[your-program] my_exe is /tmp/foo/my_exe
@@ -78,9 +78,9 @@ Debug = true
7878
[your-program] bash: invalid_strawberry_command: command not found
7979
[stage-4] ✓ Received command not found message
8080
[your-program] $ exit 0
81+
[your-program] exit
8182
[stage-4] ✓ Program exited successfully
8283
[stage-4] ✓ No output after exit command
83-
[your-program] exit
8484
[stage-4] Test passed.
8585

8686
[stage-3] Running tests for Stage #3: ff0

internal/test_helpers/fixtures/bash/navigation/pass

+4-4
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,13 @@ Debug = true
7474
[stage-7] [setup] - my_exe
7575
[stage-7] Running ./your_shell.sh
7676
[your-program] $ type cat
77-
[your-program] cat is /bin/cat
77+
[your-program] cat is /usr/bin/cat
7878
[stage-7] ✓ Received expected response
7979
[your-program] $ type cp
80-
[your-program] cp is /bin/cp
80+
[your-program] cp is /usr/bin/cp
8181
[stage-7] ✓ Received expected response
8282
[your-program] $ type mkdir
83-
[your-program] mkdir is /bin/mkdir
83+
[your-program] mkdir is /usr/bin/mkdir
8484
[stage-7] ✓ Received expected response
8585
[your-program] $ type my_exe
8686
[your-program] my_exe is /tmp/quz/my_exe
@@ -134,9 +134,9 @@ Debug = true
134134
[your-program] bash: invalid_mango_command: command not found
135135
[stage-4] ✓ Received command not found message
136136
[your-program] $ exit 0
137+
[your-program] exit
137138
[stage-4] ✓ Program exited successfully
138139
[stage-4] ✓ No output after exit command
139-
[your-program] exit
140140
[stage-4] Test passed.
141141

142142
[stage-3] Running tests for Stage #3: ff0
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Debug = true
2+
3+
[stage-4] Running tests for Stage #4: pn5
4+
[stage-4] Running ./your_shell.sh
5+
[your-program] $ invalid_apple_command
6+
[your-program] invalid_apple_command: command not found
7+
[stage-4] ✓ Received command not found message
8+
[your-program] $ exit 0
9+
[your-program] exit: command not found
10+
[your-program] $
11+
[stage-4] Expected program to exit with 0 exit code, program is still running.
12+
[stage-4] Test failed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Set this to true if you want debug logs.
2+
#
3+
# These can be VERY verbose, so we suggest turning them off
4+
# unless you really need them.
5+
debug: true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import sys
2+
3+
4+
def main():
5+
while True:
6+
sys.stdout.write("$ ")
7+
sys.stdout.flush()
8+
9+
command = input().strip()
10+
parts = command.split(" ")
11+
cmd = parts[0]
12+
args = parts[1:]
13+
14+
if cmd == "exitt":
15+
sys.exit(0)
16+
else:
17+
sys.stdout.write(f"{cmd}: command not found\n")
18+
sys.stdout.flush()
19+
20+
21+
if __name__ == "__main__":
22+
main()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/sh
2+
#
3+
# DON'T EDIT THIS!
4+
#
5+
# CodeCrafters uses this file to test your code. Don't make any changes here!
6+
#
7+
# DON'T EDIT THIS!
8+
exec python3 $(dirname "$0")/main.py "$@"

0 commit comments

Comments
 (0)