diff --git a/internal/test_streams_type.go b/internal/test_streams_type.go index e648be1..4813a79 100644 --- a/internal/test_streams_type.go +++ b/internal/test_streams_type.go @@ -2,9 +2,13 @@ package internal import ( "fmt" + + "github.com/codecrafters-io/redis-tester/internal/instrumented_resp_connection" "github.com/codecrafters-io/redis-tester/internal/redis_executable" + "github.com/codecrafters-io/redis-tester/internal/resp_assertions" + "github.com/codecrafters-io/redis-tester/internal/test_cases" - testerutils_random "github.com/codecrafters-io/tester-utils/random" + "github.com/codecrafters-io/tester-utils/random" "github.com/codecrafters-io/tester-utils/test_case_harness" ) @@ -16,53 +20,28 @@ func testStreamsType(stageHarness *test_case_harness.TestCaseHarness) error { logger := stageHarness.Logger - client := NewRedisClient("localhost:6379") - - randomKey := testerutils_random.RandomWord() - randomValue := testerutils_random.RandomWord() - - logger.Infof("$ redis-cli set %q %q", randomKey, randomValue) - resp, err := client.Set(randomKey, randomValue, 0).Result() - + client, err := instrumented_resp_connection.NewFromAddr(stageHarness, "localhost:6379", "client") if err != nil { logFriendlyError(logger, err) return err } - - if resp != "OK" { - logger.Infof("Received response: \"%q\"", resp) - return fmt.Errorf("Expected \"OK\", got %q", resp) - } else { - logger.Successf("Received response: \"%q\"", resp) - } - - logger.Infof("$ redis-cli type %q", randomKey) - resp, err = client.Type(randomKey).Result() - - if err != nil { - logFriendlyError(logger, err) - return err - } - - if resp != "string" { - return fmt.Errorf("Expected \"string\", got %q", resp) - } else { - logger.Successf("Type of %q is %q", randomKey, resp) - } - - logger.Infof("$ redis-cli type %q", "missing_key"+"_"+randomValue) - resp, err = client.Type("missing_key" + "_" + randomValue).Result() - - if err != nil { - logFriendlyError(logger, err) - return err - } - - if resp != "none" { - return fmt.Errorf("Expected \"none\", got %q", resp) - } else { - logger.Successf("Type of missing_key_%q is %q", randomValue, resp) + defer client.Close() + + randomKey := random.RandomWord() + randomValue := random.RandomWord() + + multiCommandTestCase := test_cases.MultiCommandTestCase{ + Commands: [][]string{ + {"SET", randomKey, randomValue}, + {"TYPE", randomKey}, + {"TYPE", fmt.Sprintf("missing_key_%s", randomValue)}, + }, + Assertions: []resp_assertions.RESPAssertion{ + resp_assertions.NewStringAssertion("OK"), + resp_assertions.NewStringAssertion("string"), + resp_assertions.NewStringAssertion("none"), + }, } - return nil + return multiCommandTestCase.RunAll(client, logger) } diff --git a/internal/test_streams_xadd.go b/internal/test_streams_xadd.go index d4c290d..bf03fec 100644 --- a/internal/test_streams_xadd.go +++ b/internal/test_streams_xadd.go @@ -2,11 +2,15 @@ package internal import ( "fmt" - "github.com/codecrafters-io/redis-tester/internal/redis_executable" "strings" + "github.com/codecrafters-io/redis-tester/internal/instrumented_resp_connection" + "github.com/codecrafters-io/redis-tester/internal/redis_executable" + "github.com/codecrafters-io/redis-tester/internal/resp_assertions" + "github.com/codecrafters-io/redis-tester/internal/test_cases" + "github.com/codecrafters-io/tester-utils/logger" - testerutils_random "github.com/codecrafters-io/tester-utils/random" + "github.com/codecrafters-io/tester-utils/random" "github.com/codecrafters-io/tester-utils/test_case_harness" "github.com/go-redis/redis" ) @@ -68,36 +72,26 @@ func testStreamsXadd(stageHarness *test_case_harness.TestCaseHarness) error { } logger := stageHarness.Logger - client := NewRedisClient("localhost:6379") - - randomKey := testerutils_random.RandomWord() - - xaddTest := &XADDTest{ - streamKey: randomKey, - id: "0-1", - values: map[string]interface{}{"foo": "bar"}, - expectedResponse: "0-1", - } - - err := xaddTest.Run(client, logger) - - if err != nil { - return err - } - - logger.Infof("$ redis-cli type %q", randomKey) - resp, err := client.Type(randomKey).Result() + client, err := instrumented_resp_connection.NewFromAddr(stageHarness, "localhost:6379", "client") if err != nil { logFriendlyError(logger, err) return err } - - if resp != "stream" { - return fmt.Errorf("Expected \"stream\", got %q", resp) - } else { - logger.Successf("Type of %q is %q", randomKey, resp) + defer client.Close() + + randomKey := random.RandomWord() + + multiCommandTestCase := test_cases.MultiCommandTestCase{ + Commands: [][]string{ + {"XADD", randomKey, "0-1", "foo", "bar"}, + {"TYPE", randomKey}, + }, + Assertions: []resp_assertions.RESPAssertion{ + resp_assertions.NewStringAssertion("0-1"), + resp_assertions.NewStringAssertion("stream"), + }, } - return nil + return multiCommandTestCase.RunAll(client, logger) } diff --git a/internal/test_streams_xadd_full_autoid.go b/internal/test_streams_xadd_full_autoid.go index ce5a8de..f27a8a9 100644 --- a/internal/test_streams_xadd_full_autoid.go +++ b/internal/test_streams_xadd_full_autoid.go @@ -2,14 +2,18 @@ package internal import ( "fmt" - "github.com/codecrafters-io/redis-tester/internal/redis_executable" "strconv" "strings" "time" - testerutils_random "github.com/codecrafters-io/tester-utils/random" + "github.com/codecrafters-io/redis-tester/internal/instrumented_resp_connection" + "github.com/codecrafters-io/redis-tester/internal/redis_executable" + resp_value "github.com/codecrafters-io/redis-tester/internal/resp/value" + "github.com/codecrafters-io/redis-tester/internal/resp_assertions" + "github.com/codecrafters-io/redis-tester/internal/test_cases" + + "github.com/codecrafters-io/tester-utils/random" "github.com/codecrafters-io/tester-utils/test_case_harness" - "github.com/go-redis/redis" ) func testStreamsXaddFullAutoid(stageHarness *test_case_harness.TestCaseHarness) error { @@ -19,31 +23,37 @@ func testStreamsXaddFullAutoid(stageHarness *test_case_harness.TestCaseHarness) } logger := stageHarness.Logger - client := NewRedisClient("localhost:6379") - randomKey := testerutils_random.RandomWord() + client, err := instrumented_resp_connection.NewFromAddr(stageHarness, "localhost:6379", "client") + if err != nil { + logFriendlyError(logger, err) + return err + } + defer client.Close() - logger.Infof("$ redis-cli xadd %q * foo bar", randomKey) + randomKey := random.RandomWord() - resp, err := client.XAdd(&redis.XAddArgs{ - Stream: randomKey, - ID: "*", - Values: map[string]interface{}{ - "foo": "bar", - }, - }).Result() + commandTestCase := &test_cases.SendCommandTestCase{ + Command: "XADD", + Args: []string{randomKey, "*", "foo", "bar"}, + Assertion: resp_assertions.NewNoopAssertion(), + ShouldSkipUnreadDataCheck: true, + } - if err != nil { - logFriendlyError(logger, err) + if err := commandTestCase.Run(client, logger); err != nil { return err } - logger.Infof("Received response: \"%q\"", resp) + responseValue := commandTestCase.ReceivedResponse + + if responseValue.Type != resp_value.BULK_STRING { + return fmt.Errorf("Expected bulk string, got %s", responseValue.Type) + } - parts := strings.Split(resp, "-") + parts := strings.Split(responseValue.String(), "-") if len(parts) != 2 { - return fmt.Errorf("Expected a string in the form \"-\", got %q", resp) + return fmt.Errorf("Expected a string in the form \"-\", got %q", responseValue) } timeStr, sequenceNumber := parts[0], parts[1] @@ -54,7 +64,7 @@ func testStreamsXaddFullAutoid(stageHarness *test_case_harness.TestCaseHarness) if len(timeStr) != 13 { return fmt.Errorf("Expected the first part of the ID to be a unix timestamp (%d characters), got %d characters", len(strconv.FormatInt(now, 10)), len(timeStr)) - } else if !(timeInt64 > oneSecondAgo && timeInt64 < oneSecondLater) { + } else if timeInt64 <= oneSecondAgo || timeInt64 >= oneSecondLater { return fmt.Errorf("Expected the first part of the ID to be a valid unix timestamp, got %q", timeStr) } else { logger.Successf("The first part of the ID is a valid unix milliseconds timestamp") diff --git a/internal/test_streams_xadd_partial_autoid.go b/internal/test_streams_xadd_partial_autoid.go index d74c560..6e20910 100644 --- a/internal/test_streams_xadd_partial_autoid.go +++ b/internal/test_streams_xadd_partial_autoid.go @@ -1,8 +1,11 @@ package internal import ( + "github.com/codecrafters-io/redis-tester/internal/instrumented_resp_connection" "github.com/codecrafters-io/redis-tester/internal/redis_executable" - testerutils_random "github.com/codecrafters-io/tester-utils/random" + "github.com/codecrafters-io/redis-tester/internal/resp_assertions" + "github.com/codecrafters-io/redis-tester/internal/test_cases" + "github.com/codecrafters-io/tester-utils/random" "github.com/codecrafters-io/tester-utils/test_case_harness" ) @@ -13,23 +16,29 @@ func testStreamsXaddPartialAutoid(stageHarness *test_case_harness.TestCaseHarnes } logger := stageHarness.Logger - client := NewRedisClient("localhost:6379") - randomKey := testerutils_random.RandomWord() - - tests := []XADDTest{ - {streamKey: randomKey, id: "0-*", values: map[string]interface{}{"foo": "bar"}, expectedResponse: "0-1"}, - {streamKey: randomKey, id: "1-*", values: map[string]interface{}{"foo": "bar"}, expectedResponse: "1-0"}, - {streamKey: randomKey, id: "1-*", values: map[string]interface{}{"bar": "baz"}, expectedResponse: "1-1"}, + client, err := instrumented_resp_connection.NewFromAddr(stageHarness, "localhost:6379", "client") + if err != nil { + logFriendlyError(logger, err) + return err } - - for _, test := range tests { - err := test.Run(client, logger) - - if err != nil { - return err - } + defer client.Close() + + randomKey := random.RandomWord() + randomValues := random.RandomWords(3) + + multiCommandTestCase := test_cases.MultiCommandTestCase{ + Commands: [][]string{ + {"XADD", randomKey, "0-*", randomValues[0], randomValues[1]}, + {"XADD", randomKey, "1-*", randomValues[0], randomValues[1]}, + {"XADD", randomKey, "1-*", randomValues[1], randomValues[2]}, + }, + Assertions: []resp_assertions.RESPAssertion{ + resp_assertions.NewStringAssertion("0-1"), + resp_assertions.NewStringAssertion("1-0"), + resp_assertions.NewStringAssertion("1-1"), + }, } - return nil + return multiCommandTestCase.RunAll(client, logger) } diff --git a/internal/test_streams_xadd_validate_id.go b/internal/test_streams_xadd_validate_id.go index 61f9fc9..cf69723 100644 --- a/internal/test_streams_xadd_validate_id.go +++ b/internal/test_streams_xadd_validate_id.go @@ -1,8 +1,11 @@ package internal import ( + "github.com/codecrafters-io/redis-tester/internal/instrumented_resp_connection" "github.com/codecrafters-io/redis-tester/internal/redis_executable" - testerutils_random "github.com/codecrafters-io/tester-utils/random" + "github.com/codecrafters-io/redis-tester/internal/resp_assertions" + "github.com/codecrafters-io/redis-tester/internal/test_cases" + "github.com/codecrafters-io/tester-utils/random" "github.com/codecrafters-io/tester-utils/test_case_harness" ) @@ -13,25 +16,33 @@ func testStreamsXaddValidateID(stageHarness *test_case_harness.TestCaseHarness) } logger := stageHarness.Logger - client := NewRedisClient("localhost:6379") - randomKey := testerutils_random.RandomWord() - - tests := []XADDTest{ - {streamKey: randomKey, id: "1-1", values: map[string]interface{}{"foo": "bar"}, expectedResponse: "1-1", expectedError: ""}, - {streamKey: randomKey, id: "1-2", values: map[string]interface{}{"bar": "baz"}, expectedResponse: "1-2", expectedError: ""}, - {streamKey: randomKey, id: "1-2", values: map[string]interface{}{"baz": "foo"}, expectedResponse: "", expectedError: "ERR The ID specified in XADD is equal or smaller than the target stream top item"}, - {streamKey: randomKey, id: "0-3", values: map[string]interface{}{"baz": "foo"}, expectedResponse: "", expectedError: "ERR The ID specified in XADD is equal or smaller than the target stream top item"}, - {streamKey: randomKey, id: "0-0", values: map[string]interface{}{"baz": "foo"}, expectedResponse: "", expectedError: "ERR The ID specified in XADD must be greater than 0-0"}, + client, err := instrumented_resp_connection.NewFromAddr(stageHarness, "localhost:6379", "client") + if err != nil { + logFriendlyError(logger, err) + return err } - - for _, test := range tests { - err := test.Run(client, logger) - - if err != nil { - return err - } + defer client.Close() + + randomKey := random.RandomWord() + randomValues := random.RandomWords(10) + + multiCommandTestCase := test_cases.MultiCommandTestCase{ + Commands: [][]string{ + {"XADD", randomKey, "1-1", randomValues[0], randomValues[1]}, + {"XADD", randomKey, "1-2", randomValues[2], randomValues[3]}, + {"XADD", randomKey, "1-2", randomValues[4], randomValues[5]}, + {"XADD", randomKey, "0-3", randomValues[6], randomValues[7]}, + {"XADD", randomKey, "0-0", randomValues[8], randomValues[9]}, + }, + Assertions: []resp_assertions.RESPAssertion{ + resp_assertions.NewStringAssertion("1-1"), + resp_assertions.NewStringAssertion("1-2"), + resp_assertions.NewErrorAssertion("ERR The ID specified in XADD is equal or smaller than the target stream top item"), + resp_assertions.NewErrorAssertion("ERR The ID specified in XADD is equal or smaller than the target stream top item"), + resp_assertions.NewErrorAssertion("ERR The ID specified in XADD must be greater than 0-0"), + }, } - return nil + return multiCommandTestCase.RunAll(client, logger) }