Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore!: check newChunk size #172

Merged
merged 5 commits into from
Jun 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions datasquare.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,22 +286,31 @@ func (ds *dataSquare) GetCell(x uint, y uint) []byte {
return cell
}

// SetCell sets a specific cell. Cell to set must be `nil`.
// Panics if attempting to set a cell that is not `nil`.
func (ds *dataSquare) SetCell(x uint, y uint, newChunk []byte) {
// SetCell sets a specific cell. The cell to set must be `nil`. Returns an error
// if the cell to set is not `nil` or newChunk is not the correct size.
func (ds *dataSquare) SetCell(x uint, y uint, newChunk []byte) error {
if ds.squareRow[x][y] != nil {
panic(fmt.Sprintf("cannot set cell (%d, %d) as it already has a value %x", x, y, ds.squareRow[x][y]))
return fmt.Errorf("cannot set cell (%d, %d) as it already has a value %x", x, y, ds.squareRow[x][y])
}
if len(newChunk) != int(ds.chunkSize) {
return fmt.Errorf("cannot set cell with chunk size %d because dataSquare chunk size is %d", len(newChunk), ds.chunkSize)
}
ds.squareRow[x][y] = newChunk
ds.squareCol[y][x] = newChunk
ds.resetRoots()
return nil
}

// setCell sets a specific cell.
func (ds *dataSquare) setCell(x uint, y uint, newChunk []byte) {
// setCell sets a specific cell. setCell will overwrite any existing value.
// Returns an error if the newChunk is not the correct size.
func (ds *dataSquare) setCell(x uint, y uint, newChunk []byte) error {
if len(newChunk) != int(ds.chunkSize) {
return fmt.Errorf("cannot set cell with chunk size %d because dataSquare chunk size is %d", len(newChunk), ds.chunkSize)
Comment on lines +289 to +308
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for having two setters? I don't remember

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My guess is the exported SetCell shouldn't have access to overwrite populated cells but the internal setCell should 🤷‍♂️

}
ds.squareRow[x][y] = newChunk
ds.squareCol[y][x] = newChunk
ds.resetRoots()
return nil
}

// Flattened returns the concatenated rows of the data square.
Expand Down
91 changes: 82 additions & 9 deletions datasquare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,92 @@ func TestInvalidDataSquareCreation(t *testing.T) {
}

func TestSetCell(t *testing.T) {
ds, err := newDataSquare([][]byte{{1}, {2}, {3}, {4}}, NewDefaultTree)
if err != nil {
panic(err)
type testCase struct {
name string
originalCell []byte
newCell []byte
wantErr bool
}

// SetCell can only write to nil cells
assert.Panics(t, func() { ds.SetCell(0, 0, []byte{0}) })
testCases := []testCase{
{
name: "can set cell if originally nil",
originalCell: nil,
newCell: []byte{42},
wantErr: false,
},
{
name: "expect error if cell is not originally nil",
originalCell: []byte{1},
wantErr: true,
},
{
name: "expect error if new cell is not the correct chunk size",
originalCell: nil,
newCell: []byte{1, 2}, // incorrect chunk size
wantErr: true,
},
}

// Set the cell to nil to allow modification
ds.setCell(0, 0, nil)
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
ds, err := newDataSquare([][]byte{tc.originalCell, {2}, {3}, {4}}, NewDefaultTree)
assert.NoError(t, err)

err = ds.SetCell(0, 0, tc.newCell)
if tc.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equal(t, tc.newCell, ds.GetCell(0, 0))
}
})
}
}

ds.SetCell(0, 0, []byte{42})
assert.Equal(t, []byte{42}, ds.GetCell(0, 0))
func Test_setCell(t *testing.T) {
type testCase struct {
name string
originalCell []byte
newCell []byte
wantErr bool
}

testCases := []testCase{
{
name: "can set cell if originally nil",
originalCell: nil,
newCell: []byte{42},
wantErr: false,
},
{
name: "can set cell if originally some value",
originalCell: []byte{1},
newCell: []byte{42},
wantErr: false,
},
{
name: "expect error if new cell is not the correct chunk size",
originalCell: nil,
newCell: []byte{1, 2}, // incorrect chunk size
wantErr: true,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
ds, err := newDataSquare([][]byte{tc.originalCell, {2}, {3}, {4}}, NewDefaultTree)
assert.NoError(t, err)

err = ds.setCell(0, 0, tc.newCell)
if tc.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equal(t, tc.newCell, ds.GetCell(0, 0))
}
})
}
}

func TestGetCell(t *testing.T) {
Expand Down