Skip to content

Commit

Permalink
refactor: refactor transaction test case to accept an array of assert…
Browse files Browse the repository at this point in the history
…ions

Update tests accordingly
  • Loading branch information
ryan-gang committed Jun 14, 2024
1 parent 634dcce commit 77a2189
Show file tree
Hide file tree
Showing 10 changed files with 21 additions and 46 deletions.
9 changes: 5 additions & 4 deletions internal/resp/value/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ func NewIntegerValue(i int) Value {
return Value{
Type: INTEGER,
integer: i,
bytes: []byte(fmt.Sprintf("%d", i)),
}
}

Expand Down Expand Up @@ -71,8 +70,7 @@ func NewArrayValue(arr []Value) Value {

func NewNilValue() Value {
return Value{
Type: NIL,
bytes: []byte("$-1\r\n"),
Type: NIL,
}
}

Expand All @@ -97,7 +95,10 @@ func (v *Value) Integer() int {
}

func (v *Value) Error() string {
return string(v.String())
if v.Type == ERROR {
return string(v.String())
}
return ""
}

func (v *Value) FormattedString() string {
Expand Down
23 changes: 6 additions & 17 deletions internal/resp_assertions/ordered_array_assertion.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package resp_assertions

import (
"bytes"
"fmt"

resp_value "github.com/codecrafters-io/redis-tester/internal/resp/value"
Expand All @@ -10,11 +9,12 @@ import (
// OrderedArrayAssertion : Order of the actual and expected values matters.
// All RESP values are accepted as elements in this array.
// We don't alter the ordering.
// For each element in the array, we run the corresponding assertion.
type OrderedArrayAssertion struct {
ExpectedValue []resp_value.Value
ExpectedValue []RESPAssertion
}

func NewOrderedArrayAssertion(expectedValue []resp_value.Value) RESPAssertion {
func NewOrderedArrayAssertion(expectedValue []RESPAssertion) RESPAssertion {
return OrderedArrayAssertion{ExpectedValue: expectedValue}
}

Expand All @@ -27,22 +27,11 @@ func (a OrderedArrayAssertion) Run(value resp_value.Value) error {
return fmt.Errorf("Expected %d elements in array, got %d (%s)", len(a.ExpectedValue), len(value.Array()), value.FormattedString())
}

for i, expectedValue := range a.ExpectedValue {
for i, assertion := range a.ExpectedValue {
actualElement := value.Array()[i]

if actualElement.Type != expectedValue.Type {
return fmt.Errorf("Expected element #%d to be a %s, got %s", i+1, expectedValue.Type, actualElement.Type)
}

if expectedValue.Bytes() == nil {
// This should never happen, but just in case
// This is the case for ArrayValues
return fmt.Errorf("CodeCrafters internal error. expectedValue Bytes of type: %s is nil", expectedValue.Type)
}

// ToDo: Equal or EqualFold ?
if !bytes.Equal(actualElement.Bytes(), expectedValue.Bytes()) {
return fmt.Errorf("Expected element #%d to be %s, got %s", i+1, expectedValue.FormattedString(), actualElement.FormattedString())
if err := assertion.Run(actualElement); err != nil {
return err
}
}

Expand Down
8 changes: 4 additions & 4 deletions internal/test_cases/transaction_test_case.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package test_cases

import (
resp_client "github.com/codecrafters-io/redis-tester/internal/resp/connection"
resp_value "github.com/codecrafters-io/redis-tester/internal/resp/value"
"github.com/codecrafters-io/redis-tester/internal/resp_assertions"
"github.com/codecrafters-io/tester-utils/logger"
)
Expand All @@ -19,9 +18,10 @@ type TransactionTestCase struct {
CommandQueue [][]string

// After queueing all the commands,
// if ShouldSkipExec is false, "EXEC" is sent
// And the response is compared with this ExpectedResponseArray
ExpectedResponseArray []resp_value.Value
// if "EXEC" is sent (based on which function is called)
// The elements in the response array are asserted based on the
// assertions in the ExpectedResponseArray
ExpectedResponseArray []resp_assertions.RESPAssertion
}

func (t TransactionTestCase) RunAll(client *resp_client.RespConnection, logger *logger.Logger) error {
Expand Down
2 changes: 0 additions & 2 deletions internal/test_txn_discard.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"

"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/instrumented_resp_connection"
Expand Down Expand Up @@ -47,7 +46,6 @@ func testTxDiscard(stageHarness *test_case_harness.TestCaseHarness) error {
{"SET", key1, fmt.Sprint(randomInt1)},
{"INCR", key1},
},
ExpectedResponseArray: []resp_value.Value{},
}

if err := transactionTestCase.RunWithoutExec(client, logger); err != nil {
Expand Down
6 changes: 1 addition & 5 deletions internal/test_txn_empty.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package internal

import (
"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/instrumented_resp_connection"
Expand All @@ -25,10 +24,7 @@ func testTxEmpty(stageHarness *test_case_harness.TestCaseHarness) error {
}
defer client.Close()

emptyTransactionTestCase := test_cases.TransactionTestCase{
CommandQueue: [][]string{},
ExpectedResponseArray: []resp_value.Value{},
}
emptyTransactionTestCase := test_cases.TransactionTestCase{}

if err := emptyTransactionTestCase.RunAll(client, logger); err != nil {
return err
Expand Down
6 changes: 1 addition & 5 deletions internal/test_txn_multi.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package internal

import (
"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/instrumented_resp_connection"
"github.com/codecrafters-io/redis-tester/internal/test_cases"
Expand All @@ -24,10 +23,7 @@ func testTxMulti(stageHarness *test_case_harness.TestCaseHarness) error {
}
defer client.Close()

transactionTestCase := test_cases.TransactionTestCase{
CommandQueue: [][]string{},
ExpectedResponseArray: []resp_value.Value{},
}
transactionTestCase := test_cases.TransactionTestCase{}

return transactionTestCase.RunMulti(client, logger)
}
3 changes: 1 addition & 2 deletions internal/test_txn_multi_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"

"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"
Expand Down Expand Up @@ -68,7 +67,7 @@ func testTxMultiTx(stageHarness *test_case_harness.TestCaseHarness) error {
// Inside each transaction, we run 1x INCR key1, key2
// So it increases by 1 for each transaction
// `i` here is 0-indexed, so we add 1 to the expected value
ExpectedResponseArray: []resp_value.Value{resp_value.NewIntegerValue(3 + (1 + i)), resp_value.NewIntegerValue(randomIntegerValue + (1 + i))},
ExpectedResponseArray: []resp_assertions.RESPAssertion{resp_assertions.NewIntegerAssertion(3 + (1 + i)), resp_assertions.NewIntegerAssertion(randomIntegerValue + (1 + i))},
}
if err := transactionTestCase.RunExec(client, logger); err != nil {
return err
Expand Down
2 changes: 0 additions & 2 deletions internal/test_txn_queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"

"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"
Expand Down Expand Up @@ -36,7 +35,6 @@ func testTxQueue(stageHarness *test_case_harness.TestCaseHarness) error {
{"SET", key, fmt.Sprint(randomIntegerValue)},
{"INCR", key},
},
ExpectedResponseArray: []resp_value.Value{},
}

if err := transactionTestCase.RunWithoutExec(clients[0], logger); err != nil {
Expand Down
3 changes: 1 addition & 2 deletions internal/test_txn_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"

"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"
Expand Down Expand Up @@ -39,7 +38,7 @@ func testTxSuccess(stageHarness *test_case_harness.TestCaseHarness) error {
{"INCR", key2},
{"GET", key2},
},
ExpectedResponseArray: []resp_value.Value{resp_value.NewSimpleStringValue("OK"), resp_value.NewIntegerValue(randomIntegerValue + 1), resp_value.NewIntegerValue(1), resp_value.NewBulkStringValue("1")},
ExpectedResponseArray: []resp_assertions.RESPAssertion{resp_assertions.NewStringAssertion("OK"), resp_assertions.NewIntegerAssertion(randomIntegerValue + 1), resp_assertions.NewIntegerAssertion(1), resp_assertions.NewStringAssertion("1")},
}

if err := transactionTestCase.RunAll(clients[0], logger); err != nil {
Expand Down
5 changes: 2 additions & 3 deletions internal/test_txn_tx_failure.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"

"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"
Expand Down Expand Up @@ -53,8 +52,8 @@ func testTxErr(stageHarness *test_case_harness.TestCaseHarness) error {
{"INCR", key1},
{"INCR", key2},
},
ExpectedResponseArray: []resp_value.Value{
resp_value.NewErrorValue("ERR value is not an integer or out of range"), resp_value.NewIntegerValue(randomIntegerValue + 1)},
ExpectedResponseArray: []resp_assertions.RESPAssertion{
resp_assertions.NewErrorAssertion("ERR value is not an integer or out of range"), resp_assertions.NewIntegerAssertion(randomIntegerValue + 1)},
}

if err := transactionTestCase.RunAll(clients[0], logger); err != nil {
Expand Down

0 comments on commit 77a2189

Please sign in to comment.