v01.config accepts and applies json patch

This commit is contained in:
bel
2023-03-26 10:20:19 -06:00
parent f9dc4cff9f
commit af42db6803
4 changed files with 110 additions and 0 deletions

View File

@@ -1,5 +1,11 @@
package v01
import (
"encoding/json"
patch "github.com/evanphx/json-patch/v5"
)
type config struct {
Feedback struct {
Addr string
@@ -14,3 +20,24 @@ type config struct {
}
Quiet bool
}
func (cfg config) WithJSONPatch(v interface{}) config {
originalData, _ := json.Marshal(cfg)
patchData, err := json.Marshal(v)
if err != nil {
return cfg
}
patcher, err := patch.DecodePatch(patchData)
if err != nil {
return cfg
}
patchedData, err := patcher.Apply(originalData)
if err != nil {
return cfg
}
var patched config
if err := json.Unmarshal(patchedData, &patched); err != nil {
return cfg
}
return patched
}

View File

@@ -0,0 +1,79 @@
package v01
import (
"fmt"
"testing"
)
func TestConfigPatch(t *testing.T) {
cases := map[string]struct {
cfg config
patch interface{}
want config
}{
"nil patch": {
cfg: config{Quiet: true},
patch: nil,
want: config{Quiet: true},
},
"[] patch": {
cfg: config{Quiet: true},
patch: []interface{}{},
want: config{Quiet: true},
},
"set fake field": {
cfg: config{Quiet: true},
patch: []interface{}{
map[string]interface{}{"op": "add", "path": "/Fake", "value": true},
},
want: config{Quiet: true},
},
"remove field": {
cfg: config{Quiet: true},
patch: []interface{}{
map[string]interface{}{"op": "remove", "path": "/Quiet"},
},
want: config{Quiet: false},
},
"replace field with valid": {
cfg: config{Quiet: true},
patch: []interface{}{
map[string]interface{}{"op": "replace", "path": "/Quiet", "value": false},
},
want: config{Quiet: false},
},
"replace field with invalid": {
cfg: config{Quiet: true},
patch: []interface{}{
map[string]interface{}{"op": "replace", "path": "/Quiet", "value": "teehee"},
},
want: config{Quiet: true},
},
"test and noop": {
cfg: config{Quiet: true},
patch: []interface{}{
map[string]interface{}{"op": "test", "path": "/Quiet", "value": false},
map[string]interface{}{"op": "replace", "path": "/Quiet", "value": false},
},
want: config{Quiet: true},
},
"test and apply": {
cfg: config{Quiet: true},
patch: []interface{}{
map[string]interface{}{"op": "test", "path": "/Quiet", "value": true},
map[string]interface{}{"op": "replace", "path": "/Quiet", "value": false},
},
want: config{Quiet: false},
},
}
for name, d := range cases {
c := d
t.Run(name, func(t *testing.T) {
got := c.cfg.WithJSONPatch(c.patch)
if fmt.Sprintf("%+v", got) != fmt.Sprintf("%+v", c.want) {
t.Errorf("(%+v).Patch(%+v) want %+v, got %+v", c.cfg, c.patch, c.want, got)
}
})
}
}