Skip to content

Commit

Permalink
refactor: Consolidate test cases for checking the type of commands an…
Browse files Browse the repository at this point in the history
…d handling invalid commands in shell testing stages.
  • Loading branch information
andy1li committed Dec 26, 2024
1 parent cc85446 commit 8b1ebbd
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 104 deletions.
2 changes: 1 addition & 1 deletion internal/stage2.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func testInvalidCommand(stageHarness *test_case_harness.TestCaseHarness) error {
testCase := test_cases.InvalidCommandTestCase{
Command: getRandomInvalidCommand(),
}
if err := testCase.RunAndTestReflection(asserter, shell, logger); err != nil {
if err := testCase.RunWithoutNextPromptAssertion(asserter, shell, logger); err != nil {
return err
}

Expand Down
2 changes: 1 addition & 1 deletion internal/stage3.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func testREPL(stageHarness *test_case_harness.TestCaseHarness) error {
testCase := test_cases.InvalidCommandTestCase{
Command: "invalid_command_" + strconv.Itoa(i+1),
}
if err := testCase.RunAndTestResponse(asserter, shell, logger); err != nil {
if err := testCase.Run(asserter, shell, logger); err != nil {
return err
}
}
Expand Down
2 changes: 1 addition & 1 deletion internal/stage4.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func testExit(stageHarness *test_case_harness.TestCaseHarness) error {
testCase := test_cases.InvalidCommandTestCase{
Command: getRandomInvalidCommand(),
}
if err := testCase.RunAndTestResponse(asserter, shell, logger); err != nil {
if err := testCase.Run(asserter, shell, logger); err != nil {
return err
}

Expand Down
18 changes: 5 additions & 13 deletions internal/stage6.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package internal

import (
"fmt"
"regexp"

"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 All @@ -22,26 +19,21 @@ func testType1(stageHarness *test_case_harness.TestCaseHarness) error {
}

for _, builtIn := range builtIns {
command := fmt.Sprintf("type %s", builtIn)

testCase := test_cases.CommandResponseTestCase{
Command: command,
ExpectedOutput: fmt.Sprintf(`%s is a shell builtin`, builtIn),
FallbackPatterns: []*regexp.Regexp{regexp.MustCompile(fmt.Sprintf(`^%s is a( special)? shell builtin$`, builtIn))},
SuccessMessage: "✓ Received expected response",
testCase := test_cases.TypeOfCommandTestCase{
Command: builtIn,
}
if err := testCase.Run(asserter, shell, logger); err != nil {
if err := testCase.RunForBuiltin(asserter, shell, logger); err != nil {
return err
}
}

invalidCommands := getRandomInvalidCommands(2)

for _, invalidCommand := range invalidCommands {
testCase := test_cases.InvalidCommandTypeTestCase{
testCase := test_cases.TypeOfCommandTestCase{
Command: invalidCommand,
}
if err := testCase.Run(asserter, shell, logger); err != nil {
if err := testCase.RunForInvalidCommand(asserter, shell, logger); err != nil {
return err
}
}
Expand Down
33 changes: 7 additions & 26 deletions internal/stage7.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ package internal
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"regexp"

"github.com/codecrafters-io/shell-tester/internal/custom_executable"
"github.com/codecrafters-io/shell-tester/internal/logged_shell_asserter"
Expand Down Expand Up @@ -41,38 +39,21 @@ func testType2(stageHarness *test_case_harness.TestCaseHarness) error {
availableExecutables := []string{"cat", "cp", "mkdir", "my_exe"}

for _, executable := range availableExecutables {
command := fmt.Sprintf("type %s", executable)

var expectedPath string
if executable == "my_exe" {
expectedPath = customExecutablePath
} else {
path, err := exec.LookPath(executable)
if err != nil {
return fmt.Errorf("CodeCrafters internal error. Error finding %s in PATH", executable)
}

expectedPath = path
}

testCase := test_cases.CommandResponseTestCase{
Command: command,
ExpectedOutput: fmt.Sprintf(`%s is %s`, executable, expectedPath),
FallbackPatterns: []*regexp.Regexp{regexp.MustCompile(fmt.Sprintf(`^(%s is )?%s$`, executable, expectedPath))},
SuccessMessage: "✓ Received expected response",
testCase := test_cases.TypeOfCommandTestCase{
Command: executable,
}
if err := testCase.Run(asserter, shell, logger); err != nil {
if err := testCase.RunForExecutable(asserter, shell, logger, customExecutablePath); err != nil {
return err
}
}

invalidCommands := getRandomInvalidCommands(2)

for _, command := range invalidCommands {
testCase := test_cases.InvalidCommandTypeTestCase{
Command: command,
for _, invalidCommand := range invalidCommands {
testCase := test_cases.TypeOfCommandTestCase{
Command: invalidCommand,
}
if err := testCase.Run(asserter, shell, logger); err != nil {
if err := testCase.RunForInvalidCommand(asserter, shell, logger); err != nil {
return err
}
}
Expand Down
15 changes: 6 additions & 9 deletions internal/stage9.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"
"os"
"os/exec"
"regexp"
"runtime"

"github.com/codecrafters-io/shell-tester/internal/logged_shell_asserter"
Expand All @@ -27,13 +26,11 @@ func testpwd(stageHarness *test_case_harness.TestCaseHarness) error {
return fmt.Errorf("CodeCrafters internal error. Error getting cwd: %v", err)
}

testCase := test_cases.CommandResponseTestCase{
Command: "type pwd",
ExpectedOutput: `pwd is a shell builtin`,
FallbackPatterns: []*regexp.Regexp{regexp.MustCompile(`^pwd is a( special)? shell builtin$`)},
SuccessMessage: "✓ Received 'pwd is a shell builtin'",
typeOfPwdTestCase := test_cases.TypeOfCommandTestCase{
Command: "pwd",
SuccessMessage: "✓ Received 'pwd is a shell builtin'",
}
if err := testCase.Run(asserter, shell, logger); err != nil {
if err := typeOfPwdTestCase.RunForBuiltin(asserter, shell, logger); err != nil {
return err
}

Expand Down Expand Up @@ -64,13 +61,13 @@ func testpwd(stageHarness *test_case_harness.TestCaseHarness) error {
}(exec.Command("sh", "-c", revertCommand))
}

testCase = test_cases.CommandResponseTestCase{
pwdTestCase := test_cases.CommandResponseTestCase{
Command: "pwd",
ExpectedOutput: cwd,
FallbackPatterns: nil,
SuccessMessage: "✓ Received current working directory response",
}
if err := testCase.Run(asserter, shell, logger); err != nil {
if err := pwdTestCase.Run(asserter, shell, logger); err != nil {
return err
}

Expand Down
32 changes: 16 additions & 16 deletions internal/test_cases/invalid_command_test_case.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,22 @@ type InvalidCommandTestCase struct {
Command string
}

func (t *InvalidCommandTestCase) RunAndTestReflection(asserter *logged_shell_asserter.LoggedShellAsserter, shell *shell_executable.ShellExecutable, logger *logger.Logger) error {
func (t *InvalidCommandTestCase) Run(asserter *logged_shell_asserter.LoggedShellAsserter, shell *shell_executable.ShellExecutable, logger *logger.Logger) error {
testCase := CommandResponseTestCase{
Command: t.Command,
ExpectedOutput: t.getExpectedOutput(),
FallbackPatterns: t.getFallbackPatterns(),
SuccessMessage: "✓ Received command not found message",
}

if err := testCase.Run(asserter, shell, logger); err != nil {
return err
}

return nil
}

func (t *InvalidCommandTestCase) RunWithoutNextPromptAssertion(asserter *logged_shell_asserter.LoggedShellAsserter, shell *shell_executable.ShellExecutable, logger *logger.Logger) error {
testCase := CommandReflectionTestCase{
Command: t.Command,
SkipPromptAssertion: true,
Expand All @@ -35,21 +50,6 @@ func (t *InvalidCommandTestCase) RunAndTestReflection(asserter *logged_shell_ass
return nil
}

func (t *InvalidCommandTestCase) RunAndTestResponse(asserter *logged_shell_asserter.LoggedShellAsserter, shell *shell_executable.ShellExecutable, logger *logger.Logger) error {
testCase := CommandResponseTestCase{
Command: t.Command,
ExpectedOutput: t.getExpectedOutput(),
FallbackPatterns: t.getFallbackPatterns(),
SuccessMessage: "✓ Received command not found message",
}

if err := testCase.Run(asserter, shell, logger); err != nil {
return err
}

return nil
}

func (t *InvalidCommandTestCase) getExpectedOutput() string {
return fmt.Sprintf("%s: command not found", t.Command)
}
Expand Down
37 changes: 0 additions & 37 deletions internal/test_cases/invalid_command_type_test_case.go

This file was deleted.

76 changes: 76 additions & 0 deletions internal/test_cases/type_of_command_test_case.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package test_cases

import (
"fmt"
"os/exec"
"regexp"

"github.com/codecrafters-io/shell-tester/internal/logged_shell_asserter"
"github.com/codecrafters-io/shell-tester/internal/shell_executable"
"github.com/codecrafters-io/tester-utils/logger"
)

type TypeOfCommandTestCase struct {
Command string
SuccessMessage string
}

func (t *TypeOfCommandTestCase) RunForBuiltin(asserter *logged_shell_asserter.LoggedShellAsserter, shell *shell_executable.ShellExecutable, logger *logger.Logger) error {
if t.SuccessMessage == "" {
t.SuccessMessage = "✓ Received expected response"
}

testCase := CommandResponseTestCase{
Command: fmt.Sprintf("type %s", t.Command),
ExpectedOutput: fmt.Sprintf(`%s is a shell builtin`, t.Command),
FallbackPatterns: []*regexp.Regexp{regexp.MustCompile(fmt.Sprintf(`^%s is a( special)? shell builtin$`, t.Command))},
SuccessMessage: t.SuccessMessage,
}

if err := testCase.Run(asserter, shell, logger); err != nil {
return err
}

return nil
}

func (t *TypeOfCommandTestCase) RunForExecutable(asserter *logged_shell_asserter.LoggedShellAsserter, shell *shell_executable.ShellExecutable, logger *logger.Logger, customExecutablePath string) error {
var expectedPath string

if t.Command == "my_exe" {
expectedPath = customExecutablePath
} else {
path, err := exec.LookPath(t.Command)
if err != nil {
return fmt.Errorf("CodeCrafters internal error. Error finding %s in PATH", t.Command)
}
expectedPath = path
}

testCase := CommandResponseTestCase{
Command: fmt.Sprintf("type %s", t.Command),
ExpectedOutput: fmt.Sprintf(`%s is %s`, t.Command, expectedPath),
FallbackPatterns: []*regexp.Regexp{regexp.MustCompile(fmt.Sprintf(`^(%s is )?%s$`, t.Command, expectedPath))},
SuccessMessage: "✓ Received expected response",
}
if err := testCase.Run(asserter, shell, logger); err != nil {
return err
}

return nil
}

func (t *TypeOfCommandTestCase) RunForInvalidCommand(asserter *logged_shell_asserter.LoggedShellAsserter, shell *shell_executable.ShellExecutable, logger *logger.Logger) error {
testCase := CommandResponseTestCase{
Command: fmt.Sprintf("type %s", t.Command),
ExpectedOutput: fmt.Sprintf(`%s: not found`, t.Command),
FallbackPatterns: []*regexp.Regexp{regexp.MustCompile(fmt.Sprintf(`^(bash: type: )?%s[:]? not found$`, t.Command))},
SuccessMessage: "✓ Received expected response",
}

if err := testCase.Run(asserter, shell, logger); err != nil {
return err
}

return nil
}

0 comments on commit 8b1ebbd

Please sign in to comment.