Skip to content

Commit

Permalink
add pop operation
Browse files Browse the repository at this point in the history
  • Loading branch information
can3p committed Apr 15, 2024
1 parent 79bd193 commit 844e948
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Available operations:
| set(path, value) | assign field to a particular value |
| del(path) | delete a key |
| merge(path, value) | merge json value into the path. Only JSON values are allowed |
| pop(path) | remove last element from an array |

## Examples:

Expand Down
1 change: 1 addition & 0 deletions pkg/operations/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ var operations = map[string]Operation{
"set": Set,
"del": Delete,
"merge": Merge,
"pop": Pop,
}

//nolint:govet
Expand Down
26 changes: 26 additions & 0 deletions pkg/operations/pop.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package operations

import (
"github.com/can3p/sackmesser/pkg/traverse/types"
)

func Pop(root types.Node, path []types.PathElement, args ...any) error {
node, lastChunk, err := traverseButOne(root, path)

if err != nil {
return err
}

val, err := node.GetField(lastChunk)

if err != nil {
return err
}

typed, ok := val.([]any)
if !ok {
return types.ErrWrongVisit
}

return node.SetField(lastChunk, typed[:len(typed)-1])
}
49 changes: 49 additions & 0 deletions pkg/operations/pop_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package operations

import (
"testing"

"github.com/alecthomas/assert/v2"
"github.com/can3p/sackmesser/pkg/traverse/simplejson"
"github.com/can3p/sackmesser/pkg/traverse/types"
)

func TestPopOperation(t *testing.T) {
jstr := `{ "abc": [ 1, 2, 3 ] }`

examples := []struct {
description string
path []types.PathElement
expected string
isErr bool
}{
{
description: "pop array item",
path: testPath("abc"),
expected: `{ "abc": [ 1, 2 ]}`,
},
{
description: "pop scalar",
path: testPath("abc", 0),
isErr: true,
},
}

for idx, ex := range examples {
node := simplejson.MustParse([]byte(jstr))

err := Pop(node, ex.path)

if ex.isErr {
assert.Error(t, err, "[Ex %d - %s]", idx+1, ex.description)
continue
} else {
assert.NoError(t, err, "[Ex %d - %s]", idx+1, ex.description)
}

expected := simplejson.MustParse([]byte(ex.expected))

assert.Equal(t, expected.Value(), node.Value(), "[Ex %d - %s]", idx+1, ex.description)
}

}

0 comments on commit 844e948

Please sign in to comment.