diff --git a/go.mod b/go.mod index 95c299aa..1cedfcd3 100644 --- a/go.mod +++ b/go.mod @@ -5,9 +5,9 @@ go 1.22 toolchain go1.22.3 require ( - github.com/codecrafters-io/tester-utils v0.2.38 + github.com/codecrafters-io/tester-utils v0.2.40 github.com/creack/pty v1.1.23 - github.com/fatih/color v1.17.0 + github.com/fatih/color v1.18.0 go.chromium.org/luci v0.0.0-20240530183920-783ca64715fa ) @@ -21,7 +21,7 @@ require ( github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/stretchr/testify v1.8.4 // indirect - golang.org/x/sys v0.25.0 // indirect + golang.org/x/sys v0.28.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 0e6a3a09..960c9128 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,11 @@ -github.com/codecrafters-io/tester-utils v0.2.38 h1:rKxm02A4Ll6gGrwcsGKDHxZExjH4hMbtu2ra7r/E7Lk= -github.com/codecrafters-io/tester-utils v0.2.38/go.mod h1:VgP0WmmRsA8L1urWGMXPW4Zv5jcwHwR0LdKZ8ZAEFT4= +github.com/codecrafters-io/tester-utils v0.2.40 h1:5YIQjgenDbLf5HH0hhqN0jumBGnbrjXdR0DryaKUu/I= +github.com/codecrafters-io/tester-utils v0.2.40/go.mod h1:VgP0WmmRsA8L1urWGMXPW4Zv5jcwHwR0LdKZ8ZAEFT4= github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0= github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= -github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= @@ -29,8 +29,8 @@ go.chromium.org/luci v0.0.0-20240530183920-783ca64715fa h1:sZ9n8QZFY+5BtW1npPD51 go.chromium.org/luci v0.0.0-20240530183920-783ca64715fa/go.mod h1:GXUVIlaVLS5HxpePdP1BndBFd68QByEyuZhwfJ4DwRk= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= diff --git a/internal/stage_q1.go b/internal/stage_q1.go index bcb4a898..acee1a84 100644 --- a/internal/stage_q1.go +++ b/internal/stage_q1.go @@ -22,10 +22,11 @@ func testQ1(stageHarness *test_case_harness.TestCaseHarness) error { } defer os.RemoveAll(randomDir) + randomUniqueFileNames := random.RandomInts(1, 100, 3) filePaths := []string{ - path.Join(randomDir, fmt.Sprintf("f %d", getUniqueRandomIntegerFileNames(1, 100, 3)[0])), - path.Join(randomDir, fmt.Sprintf("f %d", getUniqueRandomIntegerFileNames(1, 100, 3)[1])), - path.Join(randomDir, fmt.Sprintf("f %d", getUniqueRandomIntegerFileNames(1, 100, 3)[2])), + path.Join(randomDir, fmt.Sprintf("f %d", randomUniqueFileNames[0])), + path.Join(randomDir, fmt.Sprintf("f %d", randomUniqueFileNames[1])), + path.Join(randomDir, fmt.Sprintf("f %d", randomUniqueFileNames[2])), } fileContents := []string{ strings.Join(random.RandomWords(2), " ") + ".", diff --git a/internal/stage_q2.go b/internal/stage_q2.go index b26bd11b..6661e828 100644 --- a/internal/stage_q2.go +++ b/internal/stage_q2.go @@ -22,10 +22,11 @@ func testQ2(stageHarness *test_case_harness.TestCaseHarness) error { } defer os.RemoveAll(randomDir) + randomUniqueFileNames := random.RandomInts(1, 100, 3) filePaths := []string{ - path.Join(randomDir, fmt.Sprintf("f %d", getUniqueRandomIntegerFileNames(1, 100, 3)[0])), - path.Join(randomDir, fmt.Sprintf("f %d", getUniqueRandomIntegerFileNames(1, 100, 3)[1])), - path.Join(randomDir, fmt.Sprintf("f's%d", getUniqueRandomIntegerFileNames(1, 100, 3)[2])), + path.Join(randomDir, fmt.Sprintf("f %d", randomUniqueFileNames[0])), + path.Join(randomDir, fmt.Sprintf("f %d", randomUniqueFileNames[1])), + path.Join(randomDir, fmt.Sprintf("f's%d", randomUniqueFileNames[2])), } fileContents := []string{ strings.Join(random.RandomWords(2), " ") + ".", diff --git a/internal/stage_q3.go b/internal/stage_q3.go index 0e2defe9..66ce3710 100644 --- a/internal/stage_q3.go +++ b/internal/stage_q3.go @@ -22,10 +22,11 @@ func testQ3(stageHarness *test_case_harness.TestCaseHarness) error { } defer os.RemoveAll(randomDir) + randomUniqueFileNames := random.RandomInts(1, 100, 3) filePaths := []string{ - path.Join(randomDir, fmt.Sprintf("f\\n%d", getUniqueRandomIntegerFileNames(1, 100, 3)[0])), - path.Join(randomDir, fmt.Sprintf("f\\%d", getUniqueRandomIntegerFileNames(1, 100, 3)[1])), - path.Join(randomDir, fmt.Sprintf("f'\\'%d", getUniqueRandomIntegerFileNames(1, 100, 3)[2])), + path.Join(randomDir, fmt.Sprintf("f\\n%d", randomUniqueFileNames[0])), + path.Join(randomDir, fmt.Sprintf("f\\%d", randomUniqueFileNames[1])), + path.Join(randomDir, fmt.Sprintf("f'\\'%d", randomUniqueFileNames[2])), } fileContents := []string{ strings.Join(random.RandomWords(2), " ") + ".", diff --git a/internal/stage_q4.go b/internal/stage_q4.go index 8e9888fc..c7ab6ad3 100644 --- a/internal/stage_q4.go +++ b/internal/stage_q4.go @@ -26,11 +26,12 @@ func testQ4(stageHarness *test_case_harness.TestCaseHarness) error { } defer os.RemoveAll(randomDir) + randomUniqueFileNames := random.RandomInts(1, 100, 3) L := random.RandomElementsFromArray(LARGE_WORDS, 6) filePaths := []string{ - path.Join(randomDir, fmt.Sprintf(`'f %d'`, getUniqueRandomIntegerFileNames(1, 100, 3)[0])), - path.Join(randomDir, fmt.Sprintf(`'f \%d'`, getUniqueRandomIntegerFileNames(1, 100, 3)[1])), - path.Join(randomDir, fmt.Sprintf(`'f \%d\'`, getUniqueRandomIntegerFileNames(1, 100, 3)[2])), + path.Join(randomDir, fmt.Sprintf(`'f %d'`, randomUniqueFileNames[0])), + path.Join(randomDir, fmt.Sprintf(`'f \%d'`, randomUniqueFileNames[1])), + path.Join(randomDir, fmt.Sprintf(`'f \%d\'`, randomUniqueFileNames[2])), } fileContents := []string{ strings.Join(random.RandomWords(2), " ") + ".", diff --git a/internal/stage_q5.go b/internal/stage_q5.go index c7450a20..57b4089c 100644 --- a/internal/stage_q5.go +++ b/internal/stage_q5.go @@ -22,10 +22,11 @@ func testQ5(stageHarness *test_case_harness.TestCaseHarness) error { } defer os.RemoveAll(randomDir) + randomUniqueFileNames := random.RandomInts(1, 100, 3) filePaths := []string{ - path.Join(randomDir, fmt.Sprintf("\"f %d\"", getUniqueRandomIntegerFileNames(1, 100, 3)[0])), - path.Join(randomDir, fmt.Sprintf("\"f\\%d\"", getUniqueRandomIntegerFileNames(1, 100, 3)[1])), - path.Join(randomDir, fmt.Sprintf("f%d", getUniqueRandomIntegerFileNames(1, 100, 3)[2])), + path.Join(randomDir, fmt.Sprintf("\"f %d\"", randomUniqueFileNames[0])), + path.Join(randomDir, fmt.Sprintf("\"f\\%d\"", randomUniqueFileNames[1])), + path.Join(randomDir, fmt.Sprintf("f%d", randomUniqueFileNames[2])), } fileContents := []string{ strings.Join(random.RandomWords(2), " ") + ".", diff --git a/internal/test_helpers/fixtures/quoting/pass b/internal/test_helpers/fixtures/quoting/pass index 69c9cc1e..81928d21 100644 --- a/internal/test_helpers/fixtures/quoting/pass +++ b/internal/test_helpers/fixtures/quoting/pass @@ -3,23 +3,23 @@ Debug = true [stage-6] Running tests for Stage #6: ni6 [stage-6] Running ./your_shell.sh [your-program] $ -[stage-6] > echo 'example world' -[your-program] example world +[stage-6] > echo 'test world' +[your-program] test world [stage-6] ✓ Received expected response [your-program] $ -[stage-6] > echo world hello -[your-program] world hello +[stage-6] > echo world script +[your-program] world script [stage-6] ✓ Received expected response [your-program] $ -[stage-6] > echo 'shell script' -[your-program] shell script +[stage-6] > echo 'shell example' +[your-program] shell example [stage-6] ✓ Received expected response -[stage-6] Writing file "/tmp/foo/f 30" with content "pineapple grape." -[stage-6] Writing file "/tmp/foo/f 61" with content "banana apple." -[stage-6] Writing file "/tmp/foo/f 26" with content "blueberry orange." +[stage-6] Writing file "/tmp/foo/f 30" with content "grape banana." +[stage-6] Writing file "/tmp/foo/f 67" with content "strawberry apple." +[stage-6] Writing file "/tmp/foo/f 12" with content "blueberry pineapple." [your-program] $ -[stage-6] > cat '/tmp/foo/f 30' '/tmp/foo/f 61' '/tmp/foo/f 26' -[your-program] pineapple grape.banana apple.blueberry orange. +[stage-6] > cat '/tmp/foo/f 30' '/tmp/foo/f 67' '/tmp/foo/f 12' +[your-program] grape banana.strawberry apple.blueberry pineapple. [stage-6] ✓ Received expected response [your-program] $ [stage-6] Test passed. @@ -27,23 +27,23 @@ Debug = true [stage-5] Running tests for Stage #5: tg6 [stage-5] Running ./your_shell.sh [your-program] $ -[stage-5] > echo "world test" -[your-program] world test +[stage-5] > echo "world shell" +[your-program] world shell [stage-5] ✓ Received expected response [your-program] $ -[stage-5] > echo "test script" "example" -[your-program] test script example +[stage-5] > echo "shell script" "hello" +[your-program] shell script hello [stage-5] ✓ Received expected response [your-program] $ -[stage-5] > echo "example" "shell's" "test" -[your-program] example shell's test +[stage-5] > echo "hello" "test's" "shell" +[your-program] hello test's shell [stage-5] ✓ Received expected response -[stage-5] Writing file "/tmp/bar/f 58" with content "strawberry orange." -[stage-5] Writing file "/tmp/bar/f 80" with content "strawberry pear." -[stage-5] Writing file "/tmp/bar/f's54" with content "raspberry mango." +[stage-5] Writing file "/tmp/qux/f 55" with content "orange mango." +[stage-5] Writing file "/tmp/qux/f 98" with content "grape pear." +[stage-5] Writing file "/tmp/qux/f's68" with content "raspberry pineapple." [your-program] $ -[stage-5] > cat "/tmp/bar/f 58" "/tmp/bar/f 80" "/tmp/bar/f's54" -[your-program] strawberry orange.strawberry pear.raspberry mango. +[stage-5] > cat "/tmp/qux/f 55" "/tmp/qux/f 98" "/tmp/qux/f's68" +[your-program] orange mango.grape pear.raspberry pineapple. [stage-5] ✓ Received expected response [your-program] $ [stage-5] Test passed. @@ -55,19 +55,19 @@ Debug = true [your-program] before\ after [stage-4] ✓ Received expected response [your-program] $ -[stage-4] > echo shell\ \ \ \ \ \ test -[your-program] shell test +[stage-4] > echo script\ \ \ \ \ \ example +[your-program] script example [stage-4] ✓ Received expected response [your-program] $ -[stage-4] > echo example\nscript -[your-program] examplenscript +[stage-4] > echo world\nhello +[your-program] worldnhello [stage-4] ✓ Received expected response -[stage-4] Writing file "/tmp/baz/f\n80" with content "apple pear." -[stage-4] Writing file "/tmp/baz/f\19" with content "pineapple apple." -[stage-4] Writing file "/tmp/baz/f'\'26" with content "pear mango." +[stage-4] Writing file "/tmp/quz/f\n19" with content "orange apple." +[stage-4] Writing file "/tmp/quz/f\42" with content "apple grape." +[stage-4] Writing file "/tmp/quz/f'\'39" with content "raspberry strawberry." [your-program] $ -[stage-4] > cat "/tmp/baz/f\n80" "/tmp/baz/f\19" "/tmp/baz/f'\'26" -[your-program] apple pear.pineapple apple.pear mango. +[stage-4] > cat "/tmp/quz/f\n19" "/tmp/quz/f\42" "/tmp/quz/f'\'39" +[your-program] orange apple.apple grape.raspberry strawberry. [stage-4] ✓ Received expected response [your-program] $ [stage-4] Test passed. @@ -75,23 +75,23 @@ Debug = true [stage-3] Running tests for Stage #3: le5 [stage-3] Running ./your_shell.sh [your-program] $ -[stage-3] > echo 'example\\\nworld' -[your-program] example\\\nworld +[stage-3] > echo 'test\\\nworld' +[your-program] test\\\nworld [stage-3] ✓ Received expected response [your-program] $ -[stage-3] > echo 'hello\"testscript\"example' -[your-program] hello\"testscript\"example +[stage-3] > echo 'shell\"examplescript\"test' +[your-program] shell\"examplescript\"test [stage-3] ✓ Received expected response [your-program] $ [stage-3] > echo 'script\\nworld' [your-program] script\\nworld [stage-3] ✓ Received expected response -[stage-3] Writing file "/tmp/qux/'f 92'" with content "apple mango." -[stage-3] Writing file "/tmp/qux/'f \5'" with content "orange strawberry." -[stage-3] Writing file "/tmp/qux/'f \16\'" with content "raspberry orange." +[stage-3] Writing file "/tmp/quz/'f 24'" with content "orange mango." +[stage-3] Writing file "/tmp/quz/'f \46'" with content "blueberry orange." +[stage-3] Writing file "/tmp/quz/'f \68\'" with content "pineapple strawberry." [your-program] $ -[stage-3] > cat "/tmp/qux/'f 92'" "/tmp/qux/'f \5'" "/tmp/qux/'f \16\'" -[your-program] apple mango.orange strawberry.raspberry orange. +[stage-3] > cat "/tmp/quz/'f 24'" "/tmp/quz/'f \46'" "/tmp/quz/'f \68\'" +[your-program] orange mango.blueberry orange.pineapple strawberry. [stage-3] ✓ Received expected response [your-program] $ [stage-3] Test passed. @@ -99,52 +99,52 @@ Debug = true [stage-2] Running tests for Stage #2: gu3 [stage-2] Running ./your_shell.sh [your-program] $ -[stage-2] > echo "example'world'\\n'hello" -[your-program] example'world'\n'hello +[stage-2] > echo "shell'example'\\n'test" +[your-program] shell'example'\n'test [stage-2] ✓ Received expected response [your-program] $ -[stage-2] > echo "example\"insidequotes"world\" -[your-program] example"insidequotesworld" +[stage-2] > echo "shell\"insidequotes"example\" +[your-program] shell"insidequotesexample" [stage-2] ✓ Received expected response [your-program] $ -[stage-2] > echo "mixed\"quote'script'\\" -[your-program] mixed"quote'script'\ +[stage-2] > echo "mixed\"quote'world'\\" +[your-program] mixed"quote'world'\ [stage-2] ✓ Received expected response -[stage-2] Writing file "/tmp/foo/"f 58"" with content "banana pineapple." -[stage-2] Writing file "/tmp/foo/"f\87"" with content "raspberry blueberry." -[stage-2] Writing file "/tmp/foo/f57" with content "apple pineapple." +[stage-2] Writing file "/tmp/qux/"f 74"" with content "grape pineapple." +[stage-2] Writing file "/tmp/qux/"f\32"" with content "pineapple orange." +[stage-2] Writing file "/tmp/qux/f29" with content "strawberry raspberry." [your-program] $ -[stage-2] > cat '/tmp/foo/"f 58"' '/tmp/foo/"f\87"' '/tmp/foo/f57' -[your-program] banana pineapple.raspberry blueberry.apple pineapple. +[stage-2] > cat '/tmp/qux/"f 74"' '/tmp/qux/"f\32"' '/tmp/qux/f29' +[your-program] grape pineapple.pineapple orange.strawberry raspberry. [stage-2] ✓ Received expected response [your-program] $ [stage-2] Test passed. [stage-1] Running tests for Stage #1: qj0 [stage-1] Running ./your_shell.sh -[stage-1] Copying /tmp/custom_cat_executable to /tmp/bar/'exe with space' -[stage-1] Copying /tmp/custom_cat_executable to /tmp/bar/'exe with "quotes"' -[stage-1] Copying /tmp/custom_cat_executable to /tmp/bar/"exe with \'single quotes\'" -[stage-1] Copying /tmp/custom_cat_executable to /tmp/bar/'exe with \n newline' -[stage-1] Writing file "/tmp/bar/f1" with content "grape orange." -[stage-1] Writing file "/tmp/bar/f2" with content "mango orange." -[stage-1] Writing file "/tmp/bar/f3" with content "apple banana." -[stage-1] Writing file "/tmp/bar/f4" with content "apple mango." -[your-program] $ -[stage-1] > 'exe with space' /tmp/bar/f1 -[your-program] grape orange. +[stage-1] Copying /tmp/custom_cat_executable to /tmp/foo/'exe with space' +[stage-1] Copying /tmp/custom_cat_executable to /tmp/foo/'exe with "quotes"' +[stage-1] Copying /tmp/custom_cat_executable to /tmp/foo/"exe with \'single quotes\'" +[stage-1] Copying /tmp/custom_cat_executable to /tmp/foo/'exe with \n newline' +[stage-1] Writing file "/tmp/foo/f1" with content "raspberry blueberry." +[stage-1] Writing file "/tmp/foo/f2" with content "apple pineapple." +[stage-1] Writing file "/tmp/foo/f3" with content "strawberry raspberry." +[stage-1] Writing file "/tmp/foo/f4" with content "raspberry mango." +[your-program] $ +[stage-1] > 'exe with space' /tmp/foo/f1 +[your-program] raspberry blueberry. [stage-1] ✓ Received expected response [your-program] $ -[stage-1] > 'exe with "quotes"' /tmp/bar/f2 -[your-program] mango orange. +[stage-1] > 'exe with "quotes"' /tmp/foo/f2 +[your-program] apple pineapple. [stage-1] ✓ Received expected response [your-program] $ -[stage-1] > "exe with \'single quotes\'" /tmp/bar/f3 -[your-program] apple banana. +[stage-1] > "exe with \'single quotes\'" /tmp/foo/f3 +[your-program] strawberry raspberry. [stage-1] ✓ Received expected response [your-program] $ -[stage-1] > 'exe with \n newline' /tmp/bar/f4 -[your-program] apple mango. +[stage-1] > 'exe with \n newline' /tmp/foo/f4 +[your-program] raspberry mango. [stage-1] ✓ Received expected response [your-program] $ [stage-1] Test passed. diff --git a/internal/utils.go b/internal/utils.go index dc4e92cc..79648e99 100644 --- a/internal/utils.go +++ b/internal/utils.go @@ -4,7 +4,6 @@ import ( "fmt" "os" "path" - "slices" "strings" "github.com/codecrafters-io/shell-tester/internal/shell_executable" @@ -75,18 +74,6 @@ func getRandomName() string { return names[random.RandomInt(0, len(names))] } -func getUniqueRandomIntegerFileNames(min, max, count int) []int { - randomInts := []int{} - for i := 0; i < count; i++ { - randomInt := random.RandomInt(min, max) - for slices.Contains(randomInts, randomInt) { - randomInt = random.RandomInt(min, max) - } - randomInts = append(randomInts, randomInt) - } - return randomInts -} - // writeFile writes a file to the given path with the given content func writeFile(path string, content string) error { return os.WriteFile(path, []byte(content), 0644)