Repository: DiceDB/dice
File: internal/eval/eval_test.go (Go)

Code before:
		},
		"key exists but expired": {
			setup: func() {
				key := "EXISTING_EXPIRED_KEY"
				value := "mock_value"
				obj := &dstore.Obj{
					Value:          value,
					LastAccessedAt: uint32(time.Now().Unix()),
				}
				store.Put(key, obj)

				store.SetExpiry(obj, int64(-2*time.Millisecond))
			},
			input:  []string{"EXISTING_KEY"},
			output: clientio.RespMinusTwo,
		},
	}

	runEvalTests(t, tests, evalTTL, store)
}

func testEvalDel(t *testing.T, store *dstore.Store) {
	tests := map[string]evalTestCase{
		"nil value": {
			setup:  func() {},
			input:  nil,
			output: []byte(":0\r\n"),
		},
		"empty array": {
			setup:  func() {},
			input:  []string{},
			output: []byte(":0\r\n"),
		},
		"key does not exist": {
			setup:  func() {},
			input:  []string{"NONEXISTENT_KEY"},
			output: []byte(":0\r\n"),
		},
		"key exists": {
			setup: func() {
				key := "EXISTING_KEY"
				value := "mock_value"
				obj := &dstore.Obj{
					Value:          value,
					LastAccessedAt: uint32(time.Now().Unix()),
				}
				store.Put(key, obj)

				dstore.KeyspaceStat[0]["keys"]++
			},
			input:  []string{"EXISTING_KEY"},

Review comment (suggestion):
Add a test case testing the case where the root level object is an array. The implementation which I have provided works for it.
```sh
0.0.0.0:7379> JSON.SET arr $ '[1,2,3,"blue"]'
OK
0.0.0.0:7379> JSON.ARRAPPEND arr $ '["black"]'
1) (integer) 5
0.0.0.0:7379> JSON.GET arr $
"[1,2,3,\"blue\",[\"black\"]]"
0.0.0.0:7379>  JSON.ARRAPPEND arr $ 5
1) (integer) 6
0.0.0.0:7379> JSON.GET arr $
"[1,2,3,\"blue\",[\"black\"],5]"
```

Code after:
		"insufficient args": {
			setup:  func() {},
			input:  []string{},
			output: []byte("-ERR wrong number of arguments for 'json.set' command\r\n"),
		},
		"invalid json path": {
			setup:  func() {},
			input:  []string{"doc", "$", "{\"a\":}"},
			output: nil,
			validator: func(output []byte) {
				assert.Assert(t, output != nil)
				assert.Assert(t, strings.Contains(string(output), "-ERR invalid JSON:"))
			},
		},
		"valid json path": {
			setup: func() {
			},
			input:  []string{"doc", "$", "{\"a\":2}"},
			output: clientio.RespOK,
		},
	}

	runEvalTests(t, tests, evalJSONSET, store)
}

func testEvalJSONARRAPPEND(t *testing.T, store *dstore.Store) {
    tests := map[string]evalTestCase{
        "arr append to non array fields": {
            setup: func() {
				key := "array"
				value := "{\"a\":2}"
				var rootData interface{}
				_ = sonic.Unmarshal([]byte(value), &rootData)
				obj := store.NewObj(rootData, -1, object.ObjTypeJSON, object.ObjEncodingJSON)
				store.Put(key, obj)
            },
            input: []string{"array", "$.a", "6"},
            output: []byte("*1\r\n$-1\r\n"),
        },
        "arr append single element to an array field": {
            setup: func() {
				key := "array"
				value := "{\"a\":[1,2]}"
				var rootData interface{}
				_ = sonic.Unmarshal([]byte(value), &rootData)
				obj := store.NewObj(rootData, -1, object.ObjTypeJSON, object.ObjEncodingJSON)
				store.Put(key, obj)
            },
            input: []string{"array", "$.a", "6"},
            output: []byte("*1\r\n:3\r\n"),
        },