github.com/rajeev159/opa@v0.45.0/topdown/json_test.go (about) 1 // Copyright 2019 The OPA Authors. All rights reserved. 2 // Use of this source code is governed by an Apache2 3 // license that can be found in the LICENSE file. 4 5 package topdown 6 7 import ( 8 "testing" 9 10 "github.com/open-policy-agent/opa/ast" 11 ) 12 13 func TestFiltersToObject(t *testing.T) { 14 cases := []struct { 15 note string 16 filters []string 17 expected string 18 }{ 19 { 20 note: "base", 21 filters: []string{`"a/b/c"`}, 22 expected: `{"a": {"b": {"c": null}}}`, 23 }, 24 { 25 note: "root prefixed", 26 filters: []string{`"a/b/c"`}, 27 expected: `{"a": {"b": {"c": null}}}`, 28 }, 29 { 30 note: "trailing slash", 31 filters: []string{`"a/b/c"`}, 32 expected: `{"a": {"b": {"c": null}}}`, 33 }, 34 { 35 note: "different roots", 36 filters: []string{`"a/b/c"`, `"d/e/f"`}, 37 expected: `{"a": {"b": {"c": null}}, "d": {"e": {"f": null}}}`, 38 }, 39 { 40 note: "shared root", 41 filters: []string{`"a/b/c"`, `"a/b/d"`}, 42 expected: `{"a": {"b": {"c": null, "d": null}}}`, 43 }, 44 { 45 note: "multiple shares at different points", 46 filters: []string{`"a/b/c"`, `"a/b/d"`, `"a/e/f"`}, 47 expected: `{"a": {"b": {"c": null, "d": null}, "e": {"f": null}}}`, 48 }, 49 { 50 note: "conflict with one ordering", 51 filters: []string{`"a"`, `"a/b"`}, 52 expected: `{"a": null}`, 53 }, 54 { 55 note: "conflict with reverse ordering", 56 filters: []string{`"a/b"`, `"a"`}, 57 expected: `{"a": null}`, 58 }, 59 { 60 note: "arrays", 61 filters: []string{`"a/1/c"`, `"a/1/b"`}, 62 expected: `{"a": {"1": {"c": null, "b": null}}}`, 63 }, 64 { 65 note: "non string keys", 66 filters: []string{`[[1], {2}]`, `"a/1/b"`}, 67 expected: `{"a": {"1": {"b": null}}, [1]: {{2}: null}}`, 68 }, 69 { 70 note: "escaped tilde", 71 filters: []string{`"a/~0b~0/c~0"`}, 72 expected: `{"a": {"~b~": {"c~": null}}}`, 73 }, 74 { 75 note: "escaped slash", 76 filters: []string{`"a/~1b~1c/d~1"`}, 77 expected: `{"a": {"/b/c": {"d/": null}}}`, 78 }, 79 { 80 note: "mixed escapes", 81 filters: []string{`"a/~0b~1c/d~1~0"`}, 82 expected: `{"a": {"~b/c": {"d/~": null}}}`, 83 }, 84 } 85 86 for _, tc := range cases { 87 t.Run(tc.note, func(t *testing.T) { 88 var paths []ast.Ref 89 for _, path := range tc.filters { 90 parsedPath, err := parsePath(ast.MustParseTerm(path)) 91 if err != nil { 92 t.Errorf("unexpected error parsing path %s: %s", path, err) 93 } 94 paths = append(paths, parsedPath) 95 } 96 actual := pathsToObject(paths) 97 expected := ast.MustParseTerm(tc.expected) 98 if actual.Compare(expected.Value) != 0 { 99 t.Errorf("Unexpected object from filters:\n\nExpected:\n\t%s\n\nActual:\n\t%s\n\n", expected.Value.String(), actual.String()) 100 } 101 }) 102 } 103 }