cuelang.org/go@v0.10.1/encoding/json/json_test.go (about) 1 // Copyright 2019 CUE Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package json 16 17 import ( 18 "bytes" 19 "fmt" 20 "io" 21 "strings" 22 "testing" 23 24 "github.com/go-quicktest/qt" 25 26 "cuelang.org/go/cue/ast" 27 "cuelang.org/go/cue/format" 28 ) 29 30 func TestExtract(t *testing.T) { 31 testCases := []struct { 32 name string 33 in string 34 out string 35 }{{ 36 name: "no expand as JSON is not compact", 37 in: `{"a": 32}`, 38 out: `{a: 32}`, 39 }, { 40 name: "break across new lines", 41 in: `{"a":32,"b":[1,2],"c-d":"foo-bar-baz"}`, 42 out: `{ 43 a: 32 44 b: [1, 2] 45 "c-d": "foo-bar-baz" 46 }`, 47 }, { 48 name: "multiline string", 49 in: `"a\nb\uD803\uDE6D\nc\\\t\nd\/"`, 50 out: `""" 51 a 52 b` + "\U00010E6D" + ` 53 c\\\t 54 d/ 55 """`, 56 }, { 57 name: "multiline string indented", 58 in: `{"x":{"y":"a\nb\nc\nd"}}`, 59 out: `{ 60 x: { 61 y: """ 62 a 63 b 64 c 65 d 66 """ 67 } 68 }`, 69 }, { 70 name: "don't create multiline string for label", 71 in: `{"foo\nbar\nbaz\n": 2}`, 72 out: `{"foo\nbar\nbaz\n": 2}`, 73 }, { 74 name: "don't cap indentation", 75 in: `{"a":{"b":{"c":{"d":"a\nb\nc\nd"}}}}`, 76 out: `{ 77 a: { 78 b: { 79 c: { 80 d: """ 81 a 82 b 83 c 84 d 85 """ 86 } 87 } 88 } 89 }`, 90 }, { 91 name: "keep list formatting", 92 in: `[1,2, 93 3]`, 94 out: "[1, 2,\n\t3]", 95 }, { 96 // TODO: format.Node doesn't break large lists, it probably should. 97 name: "large list", 98 in: `[11111111111,2222222222,3333333333,4444444444,5555555555,6666666666]`, 99 out: "[11111111111, 2222222222, 3333333333, 4444444444, 5555555555, 6666666666]", 100 }, { 101 name: "reflow large values unconditionally", 102 in: `{"a": "11111111112222222222333333333344444444445555555555"}`, 103 out: "{\n\ta: \"11111111112222222222333333333344444444445555555555\"\n}", 104 }, { 105 name: "invalid JSON", 106 in: `[3_]`, 107 out: "invalid JSON for file \"invalid JSON\": invalid character '_' after array element", 108 }, { 109 name: "numeric keys: Issue #219", 110 in: `{"20": "a"}`, 111 out: `{"20": "a"}`, 112 }, { 113 name: "legacy: hidden fields", 114 in: `{"_legacy": 1}`, 115 out: `{"_legacy": 1}`, 116 }} 117 for _, tc := range testCases { 118 t.Run(tc.name, func(t *testing.T) { 119 out := &bytes.Buffer{} 120 e, err := Extract(tc.name, []byte(tc.in)) 121 toString(out, e, err) 122 qt.Assert(t, qt.Equals(out.String(), tc.out)) 123 124 out = &bytes.Buffer{} 125 d := NewDecoder(nil, tc.name, strings.NewReader(tc.in)) 126 for { 127 e, err := d.Extract() 128 if err == io.EOF { 129 break 130 } 131 toString(out, e, err) 132 if err != nil { 133 break 134 } 135 } 136 qt.Assert(t, qt.Equals(out.String(), tc.out)) 137 }) 138 } 139 } 140 141 func toString(w *bytes.Buffer, e ast.Expr, err error) { 142 if err != nil { 143 fmt.Fprint(w, err) 144 return 145 } 146 b, err := format.Node(e) 147 if err != nil { 148 fmt.Fprint(w, err) 149 return 150 } 151 fmt.Fprint(w, string(b)) 152 }