context_spook 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +103 -12
- data/Rakefile +0 -1
- data/bin/context_spook +6 -3
- data/context_spook.gemspec +7 -8
- data/lib/context_spook/generator.rb +75 -45
- data/lib/context_spook/output_context.rb +2 -2
- data/lib/context_spook/toon/encoder.rb +628 -0
- data/lib/context_spook/toon/example.md +36 -66
- data/lib/context_spook/toon.rb +13 -15
- data/lib/context_spook/utils.rb +14 -9
- data/lib/context_spook/version.rb +1 -1
- data/spec/context_spook/generator_spec.rb +63 -2
- data/spec/context_spook/toon_encoder_spec.rb +90 -0
- data/spec/context_spook/toon_spec.rb +15 -16
- data/spec/examples/README.md +79 -0
- data/spec/examples/conversions/keyed-tabular-objects.json +19 -0
- data/spec/examples/conversions/keyed-tabular-objects.toon +4 -0
- data/spec/examples/conversions/nested-field-groups.json +28 -0
- data/spec/examples/conversions/nested-field-groups.toon +4 -0
- data/spec/examples/conversions/tabular-arrays.json +22 -0
- data/spec/examples/conversions/tabular-arrays.toon +4 -0
- data/spec/examples/invalid/delimiter-mismatch.toon +3 -0
- data/spec/examples/invalid/length-mismatch.toon +3 -0
- data/spec/examples/invalid/multiple-root-primitives.toon +2 -0
- data/spec/examples/valid/comments.toon +5 -0
- data/spec/examples/valid/delimiter-scoping.toon +5 -0
- data/spec/examples/valid/mixed-arrays.toon +5 -0
- data/spec/examples/valid/nested-objects.toon +9 -0
- data/spec/examples/valid/objects.toon +6 -0
- data/spec/examples/valid/pipe-delimiter.toon +3 -0
- data/spec/examples/valid/primitive-arrays.toon +3 -0
- data/spec/examples/valid/tab-delimiter.toon +3 -0
- data/spec/fixtures/encode/arrays-nested.json +120 -0
- data/spec/fixtures/encode/arrays-objects.json +160 -0
- data/spec/fixtures/encode/arrays-primitive.json +95 -0
- data/spec/fixtures/encode/arrays-tabular.json +182 -0
- data/spec/fixtures/encode/delimiters.json +214 -0
- data/spec/fixtures/encode/objects-keyed.json +160 -0
- data/spec/fixtures/encode/objects.json +288 -0
- data/spec/fixtures/encode/primitives.json +262 -0
- data/spec/fixtures/encode/whitespace.json +54 -0
- metadata +35 -18
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "4.0",
|
|
3
|
+
"category": "encode",
|
|
4
|
+
"description": "Delimiter options – tab and pipe delimiters, delimiter-aware quoting",
|
|
5
|
+
"tests": [
|
|
6
|
+
{
|
|
7
|
+
"name": "encodes primitive arrays with tab delimiter",
|
|
8
|
+
"input": {
|
|
9
|
+
"tags": ["reading", "gaming", "coding"]
|
|
10
|
+
},
|
|
11
|
+
"expected": "tags[3\t]: reading\tgaming\tcoding",
|
|
12
|
+
"options": {
|
|
13
|
+
"delimiter": "\t"
|
|
14
|
+
},
|
|
15
|
+
"specSection": "11"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "encodes primitive arrays with pipe delimiter",
|
|
19
|
+
"input": {
|
|
20
|
+
"tags": ["reading", "gaming", "coding"]
|
|
21
|
+
},
|
|
22
|
+
"expected": "tags[3|]: reading|gaming|coding",
|
|
23
|
+
"options": {
|
|
24
|
+
"delimiter": "|"
|
|
25
|
+
},
|
|
26
|
+
"specSection": "11"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "encodes primitive arrays with comma delimiter",
|
|
30
|
+
"input": {
|
|
31
|
+
"tags": ["reading", "gaming", "coding"]
|
|
32
|
+
},
|
|
33
|
+
"expected": "tags[3]: reading,gaming,coding",
|
|
34
|
+
"options": {
|
|
35
|
+
"delimiter": ","
|
|
36
|
+
},
|
|
37
|
+
"specSection": "11"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"name": "encodes tabular arrays with tab delimiter",
|
|
41
|
+
"input": {
|
|
42
|
+
"items": [
|
|
43
|
+
{ "sku": "A1", "qty": 2, "price": 9.99 },
|
|
44
|
+
{ "sku": "B2", "qty": 1, "price": 14.5 }
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
"expected": "items[2\t]{sku\tqty\tprice}:\n A1\t2\t9.99\n B2\t1\t14.5",
|
|
48
|
+
"options": {
|
|
49
|
+
"delimiter": "\t"
|
|
50
|
+
},
|
|
51
|
+
"specSection": "11"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"name": "encodes tabular arrays with pipe delimiter",
|
|
55
|
+
"input": {
|
|
56
|
+
"items": [
|
|
57
|
+
{ "sku": "A1", "qty": 2, "price": 9.99 },
|
|
58
|
+
{ "sku": "B2", "qty": 1, "price": 14.5 }
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
"expected": "items[2|]{sku|qty|price}:\n A1|2|9.99\n B2|1|14.5",
|
|
62
|
+
"options": {
|
|
63
|
+
"delimiter": "|"
|
|
64
|
+
},
|
|
65
|
+
"specSection": "11"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"name": "encodes nested arrays with tab delimiter",
|
|
69
|
+
"input": {
|
|
70
|
+
"pairs": [["a", "b"], ["c", "d"]]
|
|
71
|
+
},
|
|
72
|
+
"expected": "pairs[2\t]:\n - [2\t]: a\tb\n - [2\t]: c\td",
|
|
73
|
+
"options": {
|
|
74
|
+
"delimiter": "\t"
|
|
75
|
+
},
|
|
76
|
+
"specSection": "11"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"name": "encodes nested arrays with pipe delimiter",
|
|
80
|
+
"input": {
|
|
81
|
+
"pairs": [["a", "b"], ["c", "d"]],
|
|
82
|
+
"items": [{ "k": [[1, { "x": 1 }]] }]
|
|
83
|
+
},
|
|
84
|
+
"expected": "pairs[2|]:\n - [2|]: a|b\n - [2|]: c|d\nitems[1|]:\n - k[1|]:\n - [2|]:\n - 1\n - x: 1",
|
|
85
|
+
"options": {
|
|
86
|
+
"delimiter": "|"
|
|
87
|
+
},
|
|
88
|
+
"specSection": "11"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"name": "encodes root-level array with tab delimiter",
|
|
92
|
+
"input": ["x", "y", "z"],
|
|
93
|
+
"expected": "[3\t]: x\ty\tz",
|
|
94
|
+
"options": {
|
|
95
|
+
"delimiter": "\t"
|
|
96
|
+
},
|
|
97
|
+
"specSection": "11"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"name": "encodes root-level array with pipe delimiter",
|
|
101
|
+
"input": ["x", "y", "z"],
|
|
102
|
+
"expected": "[3|]: x|y|z",
|
|
103
|
+
"options": {
|
|
104
|
+
"delimiter": "|"
|
|
105
|
+
},
|
|
106
|
+
"specSection": "11"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"name": "encodes root-level array of objects with tab delimiter",
|
|
110
|
+
"input": [{ "id": 1 }, { "id": 2 }],
|
|
111
|
+
"expected": "[2\t]{id}:\n 1\n 2",
|
|
112
|
+
"options": {
|
|
113
|
+
"delimiter": "\t"
|
|
114
|
+
},
|
|
115
|
+
"specSection": "11"
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"name": "encodes root-level array of objects with pipe delimiter",
|
|
119
|
+
"input": [{ "id": 1 }, { "id": 2 }],
|
|
120
|
+
"expected": "[2|]{id}:\n 1\n 2",
|
|
121
|
+
"options": {
|
|
122
|
+
"delimiter": "|"
|
|
123
|
+
},
|
|
124
|
+
"specSection": "11"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"name": "quotes strings containing pipe delimiter",
|
|
128
|
+
"input": {
|
|
129
|
+
"items": ["a", "b|c", "d"]
|
|
130
|
+
},
|
|
131
|
+
"expected": "items[3|]: a|\"b|c\"|d",
|
|
132
|
+
"options": {
|
|
133
|
+
"delimiter": "|"
|
|
134
|
+
},
|
|
135
|
+
"specSection": "11"
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"name": "does not quote commas with tab delimiter",
|
|
139
|
+
"input": {
|
|
140
|
+
"items": ["a,b", "c,d"]
|
|
141
|
+
},
|
|
142
|
+
"expected": "items[2\t]: a,b\tc,d",
|
|
143
|
+
"options": {
|
|
144
|
+
"delimiter": "\t"
|
|
145
|
+
},
|
|
146
|
+
"specSection": "11"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"name": "does not quote commas in tabular values with tab delimiter",
|
|
150
|
+
"input": {
|
|
151
|
+
"items": [
|
|
152
|
+
{ "id": 1, "note": "a,b" },
|
|
153
|
+
{ "id": 2, "note": "c,d" }
|
|
154
|
+
]
|
|
155
|
+
},
|
|
156
|
+
"expected": "items[2\t]{id\tnote}:\n 1\ta,b\n 2\tc,d",
|
|
157
|
+
"options": {
|
|
158
|
+
"delimiter": "\t"
|
|
159
|
+
},
|
|
160
|
+
"specSection": "11"
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"name": "does not quote commas in object values with pipe delimiter",
|
|
164
|
+
"input": {
|
|
165
|
+
"note": "a,b"
|
|
166
|
+
},
|
|
167
|
+
"expected": "note: a,b",
|
|
168
|
+
"options": {
|
|
169
|
+
"delimiter": "|"
|
|
170
|
+
},
|
|
171
|
+
"specSection": "11"
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"name": "quotes nested array values containing pipe delimiter",
|
|
175
|
+
"input": {
|
|
176
|
+
"pairs": [["a", "b|c"]]
|
|
177
|
+
},
|
|
178
|
+
"expected": "pairs[1|]:\n - [2|]: a|\"b|c\"",
|
|
179
|
+
"options": {
|
|
180
|
+
"delimiter": "|"
|
|
181
|
+
},
|
|
182
|
+
"specSection": "11"
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"name": "quotes a primitive list item containing the document delimiter",
|
|
186
|
+
"input": {
|
|
187
|
+
"a": [
|
|
188
|
+
"x|y",
|
|
189
|
+
"p,q",
|
|
190
|
+
{
|
|
191
|
+
"b": 1
|
|
192
|
+
}
|
|
193
|
+
]
|
|
194
|
+
},
|
|
195
|
+
"expected": "a[3|]:\n - \"x|y\"\n - p,q\n - b: 1",
|
|
196
|
+
"options": {
|
|
197
|
+
"delimiter": "|"
|
|
198
|
+
},
|
|
199
|
+
"specSection": "11.1",
|
|
200
|
+
"minSpecVersion": "4.2"
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"name": "keeps a root string containing only a non-document delimiter unquoted",
|
|
204
|
+
"input": "a,b",
|
|
205
|
+
"expected": "a,b",
|
|
206
|
+
"options": {
|
|
207
|
+
"delimiter": "|"
|
|
208
|
+
},
|
|
209
|
+
"specSection": "11.1",
|
|
210
|
+
"note": "A root primitive is quoted against the document delimiter (§11.1)",
|
|
211
|
+
"minSpecVersion": "4.2"
|
|
212
|
+
}
|
|
213
|
+
]
|
|
214
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "4.0",
|
|
3
|
+
"category": "encode",
|
|
4
|
+
"description": "Keyed tabular encoding – objects whose values are uniform objects collapse into keyed headers with entry rows",
|
|
5
|
+
"tests": [
|
|
6
|
+
{
|
|
7
|
+
"name": "encodes objects of uniform objects in keyed tabular form",
|
|
8
|
+
"input": {
|
|
9
|
+
"servers": {
|
|
10
|
+
"alpha": { "host": "a.example.com", "port": 8080 },
|
|
11
|
+
"beta": { "host": "b.example.com", "port": 9090 }
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"expected": "servers[2:]{host,port}:\n alpha: a.example.com,8080\n beta: b.example.com,9090",
|
|
15
|
+
"specSection": "9.5"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "encodes an eligible root object with a keyless keyed header",
|
|
19
|
+
"input": {
|
|
20
|
+
"alice": { "age": 30, "city": "Berlin" },
|
|
21
|
+
"bob": { "age": 25, "city": "Oslo" }
|
|
22
|
+
},
|
|
23
|
+
"expected": "[2:]{age,city}:\n alice: 30,Berlin\n bob: 25,Oslo",
|
|
24
|
+
"specSection": "9.5",
|
|
25
|
+
"note": "The keyless keyed header is valid only at the root (§5)"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "collapses uniform nested object columns inside keyed headers",
|
|
29
|
+
"input": {
|
|
30
|
+
"regions": {
|
|
31
|
+
"eu": { "name": "Europe", "geo": { "lat": 50, "lon": 10 } },
|
|
32
|
+
"us": { "name": "America", "geo": { "lat": 40, "lon": -100 } }
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"expected": "regions[2:]{name,geo{lat,lon}}:\n eu: Europe,50,10\n us: America,40,-100",
|
|
36
|
+
"specSection": "9.5"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"name": "orders fields by the first entry value's encounter order",
|
|
40
|
+
"input": {
|
|
41
|
+
"m": {
|
|
42
|
+
"a": { "x": 1, "y": 2 },
|
|
43
|
+
"b": { "y": 4, "x": 3 }
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"expected": "m[2:]{x,y}:\n a: 1,2\n b: 3,4",
|
|
47
|
+
"specSection": "9.5"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"name": "uses the active delimiter in keyed headers and entry-row cells",
|
|
51
|
+
"input": {
|
|
52
|
+
"servers": {
|
|
53
|
+
"alpha": { "host": "a.example.com", "port": 8080, "note": "x|y" },
|
|
54
|
+
"beta": { "host": "b.example.com", "port": 9090, "note": "p,q" }
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"options": { "delimiter": "|" },
|
|
58
|
+
"expected": "servers[2:|]{host|port|note}:\n alpha: a.example.com|8080|\"x|y\"\n beta: b.example.com|9090|p,q",
|
|
59
|
+
"specSection": "9.5",
|
|
60
|
+
"minSpecVersion": "4.2",
|
|
61
|
+
"note": "The keyed marker precedes the delimiter symbol: [2:|]"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"name": "quotes entry keys per key encoding",
|
|
65
|
+
"input": {
|
|
66
|
+
"ids": { "42": { "v": 1 }, "my key": { "v": 2 } }
|
|
67
|
+
},
|
|
68
|
+
"expected": "ids[2:]{v}:\n \"42\": 1\n \"my key\": 2",
|
|
69
|
+
"specSection": "9.5"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "quotes entry-row cells containing the active delimiter",
|
|
73
|
+
"input": {
|
|
74
|
+
"notes": {
|
|
75
|
+
"n1": { "text": "a,b" },
|
|
76
|
+
"n2": { "text": "c" }
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"expected": "notes[2:]{text}:\n n1: \"a,b\"\n n2: c",
|
|
80
|
+
"specSection": "9.5"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"name": "keeps single-entry objects in nested form",
|
|
84
|
+
"input": {
|
|
85
|
+
"config": {
|
|
86
|
+
"only": { "a": 1, "b": 2 }
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"expected": "config:\n only:\n a: 1\n b: 2",
|
|
90
|
+
"specSection": "9.5",
|
|
91
|
+
"note": "Keyed tabular detection requires at least two entries"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"name": "keeps objects in nested form when entry values have differing key sets",
|
|
95
|
+
"input": {
|
|
96
|
+
"envs": {
|
|
97
|
+
"dev": { "host": "x" },
|
|
98
|
+
"prod": { "host": "y", "port": 1 }
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
"expected": "envs:\n dev:\n host: x\n prod:\n host: y\n port: 1",
|
|
102
|
+
"specSection": "9.5"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"name": "keeps objects in nested form when a value is primitive",
|
|
106
|
+
"input": {
|
|
107
|
+
"m": {
|
|
108
|
+
"a": { "x": 1 },
|
|
109
|
+
"b": 2
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
"expected": "m:\n a:\n x: 1\n b: 2",
|
|
113
|
+
"specSection": "9.5"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"name": "keeps objects in nested form when an entry value contains an array",
|
|
117
|
+
"input": {
|
|
118
|
+
"m": {
|
|
119
|
+
"a": { "tags": ["x"] },
|
|
120
|
+
"b": { "tags": ["y"] }
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
"expected": "m:\n a:\n tags[1]: x\n b:\n tags[1]: y",
|
|
124
|
+
"specSection": "9.5",
|
|
125
|
+
"note": "Entry-row cells must be primitive leaves; an array value disqualifies the column"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"name": "emits a keyed header on the hyphen line when it is the first field of a list item",
|
|
129
|
+
"input": {
|
|
130
|
+
"items": [
|
|
131
|
+
{ "config": { "a": { "x": 1 }, "b": { "x": 2 } }, "status": "ok" },
|
|
132
|
+
{ "status": "down" }
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
"expected": "items[2]:\n - config[2:]{x}:\n a: 1\n b: 2\n status: ok\n - status: down",
|
|
136
|
+
"specSection": "10",
|
|
137
|
+
"note": "Entry rows at depth +2, sibling fields at depth +1, mirroring tabular arrays on hyphen lines"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"name": "never encodes an anonymous array element in keyed tabular form",
|
|
141
|
+
"input": {
|
|
142
|
+
"items": [
|
|
143
|
+
{ "a": { "x": 1 }, "b": { "x": 2 } },
|
|
144
|
+
5
|
|
145
|
+
]
|
|
146
|
+
},
|
|
147
|
+
"expected": "items[2]:\n - a:\n x: 1\n b:\n x: 2\n - 5",
|
|
148
|
+
"specSection": "9.5",
|
|
149
|
+
"note": "The element object is keyed-eligible but has no key; the keyless form is root-only, so it encodes per §10"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"name": "keeps an object of empty objects out of keyed tabular form",
|
|
153
|
+
"input": {
|
|
154
|
+
"m": { "a": {}, "b": {} }
|
|
155
|
+
},
|
|
156
|
+
"expected": "m:\n a:\n b:",
|
|
157
|
+
"specSection": "9.5"
|
|
158
|
+
}
|
|
159
|
+
]
|
|
160
|
+
}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "4.0",
|
|
3
|
+
"category": "encode",
|
|
4
|
+
"description": "Object encoding – simple objects, nested objects, key encoding",
|
|
5
|
+
"tests": [
|
|
6
|
+
{
|
|
7
|
+
"name": "preserves key order in objects with primitive values",
|
|
8
|
+
"input": {
|
|
9
|
+
"id": 123,
|
|
10
|
+
"name": "Ada",
|
|
11
|
+
"active": true,
|
|
12
|
+
"value": null
|
|
13
|
+
},
|
|
14
|
+
"expected": "id: 123\nname: Ada\nactive: true\nvalue: null",
|
|
15
|
+
"specSection": "8"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "encodes an empty root object as an empty document",
|
|
19
|
+
"input": {},
|
|
20
|
+
"expected": "",
|
|
21
|
+
"specSection": "8"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"name": "quotes string value with colon",
|
|
25
|
+
"input": {
|
|
26
|
+
"note": "a:b"
|
|
27
|
+
},
|
|
28
|
+
"expected": "note: \"a:b\"",
|
|
29
|
+
"specSection": "7.2"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "quotes string value with comma",
|
|
33
|
+
"input": {
|
|
34
|
+
"note": "a,b"
|
|
35
|
+
},
|
|
36
|
+
"expected": "note: \"a,b\"",
|
|
37
|
+
"specSection": "7.2"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"name": "quotes string value with newline",
|
|
41
|
+
"input": {
|
|
42
|
+
"text": "line1\nline2"
|
|
43
|
+
},
|
|
44
|
+
"expected": "text: \"line1\\nline2\"",
|
|
45
|
+
"specSection": "7.2"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "quotes string value with embedded quotes",
|
|
49
|
+
"input": {
|
|
50
|
+
"text": "say \"hello\""
|
|
51
|
+
},
|
|
52
|
+
"expected": "text: \"say \\\"hello\\\"\"",
|
|
53
|
+
"specSection": "7.2"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "quotes string values with a leading or trailing space",
|
|
57
|
+
"input": {
|
|
58
|
+
"lead": " padded",
|
|
59
|
+
"trail": "padded "
|
|
60
|
+
},
|
|
61
|
+
"expected": "lead: \" padded\"\ntrail: \"padded \"",
|
|
62
|
+
"specSection": "7.2"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"name": "quotes string value with only spaces",
|
|
66
|
+
"input": {
|
|
67
|
+
"text": " "
|
|
68
|
+
},
|
|
69
|
+
"expected": "text: \" \"",
|
|
70
|
+
"specSection": "7.2"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"name": "quotes string value that looks like true",
|
|
74
|
+
"input": {
|
|
75
|
+
"v": "true"
|
|
76
|
+
},
|
|
77
|
+
"expected": "v: \"true\"",
|
|
78
|
+
"specSection": "7.2"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"name": "quotes string value that looks like number",
|
|
82
|
+
"input": {
|
|
83
|
+
"v": "42"
|
|
84
|
+
},
|
|
85
|
+
"expected": "v: \"42\"",
|
|
86
|
+
"specSection": "7.2"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"name": "quotes string value that looks like a number with an uppercase exponent",
|
|
90
|
+
"input": {
|
|
91
|
+
"v": "1E6"
|
|
92
|
+
},
|
|
93
|
+
"expected": "v: \"1E6\"",
|
|
94
|
+
"specSection": "7.2"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"name": "quotes key with colon",
|
|
98
|
+
"input": {
|
|
99
|
+
"order:id": 7
|
|
100
|
+
},
|
|
101
|
+
"expected": "\"order:id\": 7",
|
|
102
|
+
"specSection": "7.3"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"name": "quotes keys with brackets or braces",
|
|
106
|
+
"input": {
|
|
107
|
+
"[index]": 5,
|
|
108
|
+
"{key}": 6
|
|
109
|
+
},
|
|
110
|
+
"expected": "\"[index]\": 5\n\"{key}\": 6",
|
|
111
|
+
"specSection": "7.3"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"name": "quotes key with comma",
|
|
115
|
+
"input": {
|
|
116
|
+
"a,b": 1
|
|
117
|
+
},
|
|
118
|
+
"expected": "\"a,b\": 1",
|
|
119
|
+
"specSection": "7.3"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"name": "quotes keys with spaces",
|
|
123
|
+
"input": {
|
|
124
|
+
"full name": "Ada",
|
|
125
|
+
" a ": 1
|
|
126
|
+
},
|
|
127
|
+
"expected": "\"full name\": Ada\n\" a \": 1",
|
|
128
|
+
"specSection": "7.3"
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"name": "quotes keys with a leading or interior hyphen",
|
|
132
|
+
"input": {
|
|
133
|
+
"-lead": 1,
|
|
134
|
+
"a-b": 2
|
|
135
|
+
},
|
|
136
|
+
"expected": "\"-lead\": 1\n\"a-b\": 2",
|
|
137
|
+
"specSection": "7.3"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"name": "quotes numeric key",
|
|
141
|
+
"input": {
|
|
142
|
+
"123": "x"
|
|
143
|
+
},
|
|
144
|
+
"expected": "\"123\": x",
|
|
145
|
+
"specSection": "7.3"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"name": "quotes empty string key",
|
|
149
|
+
"input": {
|
|
150
|
+
"": 1
|
|
151
|
+
},
|
|
152
|
+
"expected": "\"\": 1",
|
|
153
|
+
"specSection": "7.3"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"name": "quotes non-ASCII key",
|
|
157
|
+
"input": {
|
|
158
|
+
"café": 1
|
|
159
|
+
},
|
|
160
|
+
"expected": "\"café\": 1",
|
|
161
|
+
"specSection": "7.3",
|
|
162
|
+
"note": "The unquoted-key pattern is ASCII-only, so every non-ASCII key is quoted"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"name": "keeps dotted and literal-named keys unquoted",
|
|
166
|
+
"input": {
|
|
167
|
+
"a.b": 1,
|
|
168
|
+
"true": 2
|
|
169
|
+
},
|
|
170
|
+
"expected": "a.b: 1\ntrue: 2",
|
|
171
|
+
"specSection": "7.3",
|
|
172
|
+
"minSpecVersion": "4.2"
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"name": "escapes newline and quotes in keys",
|
|
176
|
+
"input": {
|
|
177
|
+
"line\n": 1,
|
|
178
|
+
"he said \"hi\"": 2
|
|
179
|
+
},
|
|
180
|
+
"expected": "\"line\\n\": 1\n\"he said \\\"hi\\\"\": 2",
|
|
181
|
+
"specSection": "7.1"
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"name": "escapes tab in key",
|
|
185
|
+
"input": {
|
|
186
|
+
"tab\there": 2
|
|
187
|
+
},
|
|
188
|
+
"expected": "\"tab\\there\": 2",
|
|
189
|
+
"specSection": "7.1"
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"name": "escapes U+0004 control character in key via \\uXXXX",
|
|
193
|
+
"input": {
|
|
194
|
+
"a\u0004b": 1
|
|
195
|
+
},
|
|
196
|
+
"expected": "\"a\\u0004b\": 1",
|
|
197
|
+
"specSection": "7.1"
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"name": "escapes U+001F control character in key via \\uXXXX",
|
|
201
|
+
"input": {
|
|
202
|
+
"x\u001fy": 2
|
|
203
|
+
},
|
|
204
|
+
"expected": "\"x\\u001fy\": 2",
|
|
205
|
+
"specSection": "7.1"
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
"name": "encodes deeply nested objects",
|
|
209
|
+
"input": {
|
|
210
|
+
"a": {
|
|
211
|
+
"b": {
|
|
212
|
+
"c": "deep"
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
"expected": "a:\n b:\n c: deep",
|
|
217
|
+
"specSection": "8"
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"name": "encodes empty nested object",
|
|
221
|
+
"input": {
|
|
222
|
+
"user": {}
|
|
223
|
+
},
|
|
224
|
+
"expected": "user:",
|
|
225
|
+
"specSection": "8"
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
"name": "encodes __proto__ own property as an ordinary key",
|
|
229
|
+
"input": {
|
|
230
|
+
"__proto__": "polluted",
|
|
231
|
+
"safe": true
|
|
232
|
+
},
|
|
233
|
+
"expected": "__proto__: polluted\nsafe: true",
|
|
234
|
+
"specSection": "15",
|
|
235
|
+
"note": "No key has special meaning, so the encoder emits prototype-named own entries like any other (§8)"
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
"name": "encodes __proto__ as a tabular field name",
|
|
239
|
+
"input": {
|
|
240
|
+
"rows": [
|
|
241
|
+
{
|
|
242
|
+
"__proto__": "a",
|
|
243
|
+
"x": 1
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
"__proto__": "b",
|
|
247
|
+
"x": 2
|
|
248
|
+
}
|
|
249
|
+
]
|
|
250
|
+
},
|
|
251
|
+
"expected": "rows[2]{__proto__,x}:\n a,1\n b,2",
|
|
252
|
+
"specSection": "15"
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"name": "quotes hash-leading string in object field value",
|
|
256
|
+
"input": {
|
|
257
|
+
"note": "#x"
|
|
258
|
+
},
|
|
259
|
+
"expected": "note: \"#x\"",
|
|
260
|
+
"specSection": "7.2"
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
"name": "encodes empty string key opening a nested object",
|
|
264
|
+
"input": {
|
|
265
|
+
"": {
|
|
266
|
+
"a": 1
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
"expected": "\"\":\n a: 1",
|
|
270
|
+
"specSection": "8"
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
"name": "keeps strings that only resemble numbers or literals, a leading byte-order mark, or DEL unquoted",
|
|
274
|
+
"input": {
|
|
275
|
+
"a": ".5",
|
|
276
|
+
"b": "NaN",
|
|
277
|
+
"c": "True",
|
|
278
|
+
"d": "\ufeffx",
|
|
279
|
+
"e": "a\u007fb",
|
|
280
|
+
"f": "\u0664\u0662"
|
|
281
|
+
},
|
|
282
|
+
"expected": "a: .5\nb: NaN\nc: True\nd: \ufeffx\ne: a\u007fb\nf: \u0664\u0662",
|
|
283
|
+
"specSection": "7.2",
|
|
284
|
+
"note": "Only a root primitive starting with U+FEFF is quoted, and only U+0000–U+001F count as controls (§7.1, §7.2)",
|
|
285
|
+
"minSpecVersion": "4.2"
|
|
286
|
+
}
|
|
287
|
+
]
|
|
288
|
+
}
|