@toon-format/spec 2.1.0 → 3.0.1
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.
- package/CHANGELOG.md +21 -0
- package/CONTRIBUTING.md +13 -5
- package/README.md +3 -3
- package/SPEC.md +53 -53
- package/package.json +1 -1
- package/tests/fixtures/decode/arrays-nested.json +9 -11
- package/tests/fixtures/decode/numbers.json +33 -0
- package/tests/fixtures/encode/arrays-nested.json +9 -13
- package/tests/fixtures/encode/arrays-objects.json +39 -44
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,27 @@ All notable changes to the TOON specification will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [3.0] - 2025-11-24
|
|
9
|
+
|
|
10
|
+
### Breaking Changes
|
|
11
|
+
|
|
12
|
+
- Standardized encoding for list-item objects whose first field is a tabular array (§10):
|
|
13
|
+
- Encoders MUST emit `- key[N]{fields}:` on the hyphen line.
|
|
14
|
+
- Tabular rows MUST appear at depth +2 relative to the hyphen line.
|
|
15
|
+
- All other fields of the same object MUST appear at depth +1.
|
|
16
|
+
- The v2.0 shallow form (rows and fields at the same depth) and the v2.1 bare-hyphen form are no longer normative and MUST NOT be emitted by conforming encoders.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Encoding/decoding rules (§10) simplified to describe only the YAML-style pattern; legacy layouts are treated as generic nesting and are not covered by conformance tests.
|
|
21
|
+
- Nested tabular list-item example in Appendix A updated to the canonical v3.0 form.
|
|
22
|
+
|
|
23
|
+
### Migration from v2.1
|
|
24
|
+
|
|
25
|
+
- Update encoders to emit the YAML-style form for list-item objects whose first field is a tabular array.
|
|
26
|
+
- If you rely on v2.0/v2.1 layouts, keep decoder compatibility in non-strict or implementation-defined modes; the spec no longer requires or tests these patterns.
|
|
27
|
+
- Optionally regenerate existing `.toon` files for consistent v3 formatting.
|
|
28
|
+
|
|
8
29
|
## [2.1] - 2025-11-23
|
|
9
30
|
|
|
10
31
|
### Changed
|
package/CONTRIBUTING.md
CHANGED
|
@@ -95,12 +95,20 @@ Follow [SPEC.md](./SPEC.md) conventions:
|
|
|
95
95
|
- **Structure**: Number sections, cross-reference related rules
|
|
96
96
|
- **Line length**: 80-120 characters for readability
|
|
97
97
|
|
|
98
|
-
##
|
|
98
|
+
## Communication
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
- **GitHub Issues**: For bug reports and feature requests
|
|
101
|
+
- **GitHub Discussions**: For questions and general discussion
|
|
102
|
+
- **Pull Requests**: For code reviews and implementation discussion
|
|
103
|
+
|
|
104
|
+
## Maintainers
|
|
105
|
+
|
|
106
|
+
This is a collaborative project. Current maintainers:
|
|
107
|
+
|
|
108
|
+
- [@johannschopplich](https://github.com/johannschopplich)
|
|
109
|
+
|
|
110
|
+
All maintainers have equal and consensual decision-making power. For major architectural decisions, please open a discussion issue first.
|
|
103
111
|
|
|
104
112
|
## License
|
|
105
113
|
|
|
106
|
-
By contributing, you agree your contributions will be licensed under the MIT License.
|
|
114
|
+
By contributing, you agree your contributions will be licensed under the MIT License.
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# TOON Format Specification
|
|
2
2
|
|
|
3
|
-
[](./SPEC.md)
|
|
4
|
+
[](./tests/fixtures/)
|
|
5
5
|
[](./LICENSE)
|
|
6
6
|
|
|
7
7
|
This repository contains the official specification for **Token-Oriented Object Notation (TOON)**, a compact, human-readable encoding of the JSON data model for LLM prompts. It provides a lossless serialization of the same objects, arrays, and primitives as JSON, but in a syntax that minimizes tokens and makes structure easy for models to follow.
|
|
@@ -10,7 +10,7 @@ This repository contains the official specification for **Token-Oriented Object
|
|
|
10
10
|
|
|
11
11
|
[→ Read the full specification (SPEC.md)](./SPEC.md)
|
|
12
12
|
|
|
13
|
-
- **Version:**
|
|
13
|
+
- **Version:** 3.0 (2025-11-24)
|
|
14
14
|
- **Status:** Working Draft
|
|
15
15
|
- **License:** MIT
|
|
16
16
|
|
package/SPEC.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
## Token-Oriented Object Notation
|
|
4
4
|
|
|
5
|
-
**Version:**
|
|
5
|
+
**Version:** 3.0
|
|
6
6
|
|
|
7
|
-
**Date:** 2025-11-
|
|
7
|
+
**Date:** 2025-11-24
|
|
8
8
|
|
|
9
9
|
**Status:** Working Draft
|
|
10
10
|
|
|
@@ -20,7 +20,7 @@ Token-Oriented Object Notation (TOON) is a line-oriented, indentation-based text
|
|
|
20
20
|
|
|
21
21
|
## Status of This Document
|
|
22
22
|
|
|
23
|
-
This document is a Working Draft
|
|
23
|
+
This document is a Working Draft v3.0 and may be updated, replaced, or obsoleted. Implementers should monitor the canonical repository at https://github.com/toon-format/spec for changes.
|
|
24
24
|
|
|
25
25
|
This specification is stable for implementation but not yet finalized. Breaking changes may occur in future major versions.
|
|
26
26
|
|
|
@@ -217,7 +217,7 @@ Implementations that fail to conform to any MUST or REQUIRED level requirement a
|
|
|
217
217
|
- Encoders SHOULD provide an option to choose lossless stringification for out-of-range numbers.
|
|
218
218
|
- Numbers (decoding):
|
|
219
219
|
- Decoders MUST accept decimal and exponent forms on input (e.g., 42, -3.14, 1e-6, -1E+9).
|
|
220
|
-
- Decoders MUST treat tokens with forbidden leading zeros (e.g., "05"
|
|
220
|
+
- Decoders MUST treat tokens with forbidden leading zeros in the integer part (e.g., `"05"`, `"0001"`, `"-05"`, `"-0001"`) as strings, not numbers. This rule does **not** apply to a single zero integer part followed by a fractional or exponent part (e.g., `0.5`, `0e1`, `-0.5`, `-0e1`), which are valid numbers.
|
|
221
221
|
- If a decoded numeric token is not representable in the host's default numeric type without loss, implementations MAY:
|
|
222
222
|
- Return a higher-precision numeric type (e.g., arbitrary-precision integer or decimal), OR
|
|
223
223
|
- Return a string, OR
|
|
@@ -227,12 +227,12 @@ Implementations that fail to conform to any MUST or REQUIRED level requirement a
|
|
|
227
227
|
|
|
228
228
|
## 3. Encoding Normalization (Reference Encoder)
|
|
229
229
|
|
|
230
|
-
Encoders MUST normalize non-JSON values to the JSON data model before encoding
|
|
230
|
+
Encoders MUST normalize non-JSON values to the JSON data model before encoding. The mapping from host-specific types to JSON model is implementation-defined and MUST be documented.
|
|
231
231
|
|
|
232
232
|
- Number:
|
|
233
233
|
- Finite → number (canonical decimal form per Section 2). -0 → 0.
|
|
234
234
|
- NaN, +Infinity, -Infinity → null.
|
|
235
|
-
-
|
|
235
|
+
- Implementations MAY honor host-language–specific serialization hooks (for example, a `toJSON()` method in JavaScript or an equivalent mechanism) as part of host-type normalization. When supported, such hooks SHOULD be applied before other host-type mappings and their behavior MUST be documented by the implementation.
|
|
236
236
|
- Examples of host-type normalization (non-normative):
|
|
237
237
|
- Date/time objects → ISO 8601 string representation.
|
|
238
238
|
- Set-like collections → array.
|
|
@@ -384,9 +384,9 @@ A string value MUST be quoted if any of the following is true:
|
|
|
384
384
|
- It contains a colon (:), double quote ("), or backslash (\).
|
|
385
385
|
- It contains brackets or braces ([, ], {, }).
|
|
386
386
|
- It contains control characters: newline, carriage return, or tab.
|
|
387
|
-
- It contains the relevant delimiter:
|
|
388
|
-
-
|
|
389
|
-
-
|
|
387
|
+
- It contains the relevant delimiter (see §11 for complete delimiter rules):
|
|
388
|
+
- For inline array values and tabular row cells: the active delimiter from the nearest array header.
|
|
389
|
+
- For object field values (key: value): the document delimiter, even when the object is within an array's scope.
|
|
390
390
|
- It equals "-" or starts with "-" (any hyphen at position 0).
|
|
391
391
|
|
|
392
392
|
Otherwise, the string MAY be emitted without quotes. Unicode, emoji, and strings with internal (non-leading/trailing) spaces are safe unquoted provided they do not violate the conditions.
|
|
@@ -403,12 +403,10 @@ Encoders MAY perform key folding when enabled (see §13.4 for complete folding r
|
|
|
403
403
|
|
|
404
404
|
### 7.4 Decoding Rules for Strings and Keys (Decoding)
|
|
405
405
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
- Otherwise → strings
|
|
411
|
-
- Keys (quoted or unquoted) MUST be followed by ":"; missing colon MUST error.
|
|
406
|
+
Decoding of value tokens follows §4 (unquoted type inference, quoted strings, numeric rules). This section adds key-specific requirements:
|
|
407
|
+
|
|
408
|
+
- Quoted keys MUST be unescaped per Section 7.1; any other escape MUST error.
|
|
409
|
+
- Keys (quoted or unquoted) MUST be followed by ":"; missing colon MUST error (see also §14.2).
|
|
412
410
|
|
|
413
411
|
## 8. Objects
|
|
414
412
|
|
|
@@ -421,7 +419,6 @@ Encoders MAY perform key folding when enabled (see §13.4 for complete folding r
|
|
|
421
419
|
- Decoding:
|
|
422
420
|
- A line "key:" with nothing after the colon at depth d opens an object; subsequent lines at depth > d belong to that object until the depth decreases to ≤ d.
|
|
423
421
|
- Lines "key: value" at the same depth are sibling fields.
|
|
424
|
-
- Missing colon after a key MUST error.
|
|
425
422
|
|
|
426
423
|
## 9. Arrays
|
|
427
424
|
|
|
@@ -474,6 +471,7 @@ Decoding:
|
|
|
474
471
|
- Delimiter before colon → row.
|
|
475
472
|
- Colon before delimiter → key-value line (end of rows).
|
|
476
473
|
- If a line has an unquoted colon but no unquoted active delimiter → key-value line (end of rows).
|
|
474
|
+
- When a tabular array appears as the first field of a list-item object, indentation is governed by Section 10.
|
|
477
475
|
|
|
478
476
|
### 9.4 Mixed / Non-Uniform Arrays — Expanded List
|
|
479
477
|
|
|
@@ -499,28 +497,18 @@ Decoding:
|
|
|
499
497
|
For an object appearing as a list item:
|
|
500
498
|
|
|
501
499
|
- Empty object list item: a single "-" at the list-item indentation level.
|
|
502
|
-
- Encoding
|
|
503
|
-
- When
|
|
504
|
-
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
-
|
|
511
|
-
-
|
|
512
|
-
-
|
|
513
|
-
-
|
|
514
|
-
- Followed by tabular rows at depth +1 (relative to the hyphen line).
|
|
515
|
-
- Non-uniform array: - key[N<delim?>]:
|
|
516
|
-
- Followed by list items at depth +1.
|
|
517
|
-
- Object: - key:
|
|
518
|
-
- Nested object fields appear at depth +2 (i.e., one deeper than subsequent sibling fields of the same list item).
|
|
519
|
-
- Remaining fields of the same object appear at depth +1 under the hyphen line in encounter order, using normal object field rules.
|
|
520
|
-
|
|
521
|
-
Decoding:
|
|
522
|
-
- The first field is parsed from the hyphen line. If it is a nested object (- key:), nested fields are at +2 relative to the hyphen line; subsequent fields of the same list item are at +1.
|
|
523
|
-
- If the first field is a tabular header on the hyphen line, its rows are at +1; subsequent sibling fields continue at +1 after the rows.
|
|
500
|
+
- Encoding (normative):
|
|
501
|
+
- When a list-item object has a tabular array (Section 9.3) as its first field in encounter order, encoders MUST emit the tabular header on the hyphen line:
|
|
502
|
+
- The hyphen and tabular header appear on the same line at the list-item depth: - key[N<delim?>]{fields}:
|
|
503
|
+
- Tabular rows MUST appear at depth +2 (relative to the hyphen line).
|
|
504
|
+
- All other fields of the same object MUST appear at depth +1 under the hyphen line, in encounter order, using normal object field rules (Section 8).
|
|
505
|
+
- Encoders MUST NOT emit tabular rows at depth +1 or sibling fields at the same depth as rows when the first field is a tabular array.
|
|
506
|
+
- For all other cases (first field is not a tabular array), encoders SHOULD place the first field on the hyphen line. A bare hyphen on its own line is used only for empty list-item objects.
|
|
507
|
+
- Decoding (normative):
|
|
508
|
+
- When a decoder encounters a list-item line of the form - key[N<delim?>]{fields}: at depth d, it MUST treat this as the start of a tabular array field named key in the list-item object.
|
|
509
|
+
- Lines at depth d+2 that conform to tabular row syntax (Section 9.3) are rows of that tabular array.
|
|
510
|
+
- Lines at depth d+1 are additional fields of the same list-item object; the presence of a line at depth d+1 after rows terminates the rows.
|
|
511
|
+
- All other object-as-list-item patterns (bare hyphen, first field on hyphen line for non-tabular values) are decoded according to the general rules in Section 8 and Section 9.
|
|
524
512
|
|
|
525
513
|
## 11. Delimiters
|
|
526
514
|
|
|
@@ -528,19 +516,25 @@ Decoding:
|
|
|
528
516
|
- Comma (default): header omits the delimiter symbol.
|
|
529
517
|
- Tab: header includes HTAB inside brackets and braces (e.g., [N<TAB>], {a<TAB>b}); rows/inline arrays use tabs.
|
|
530
518
|
- Pipe: header includes "|" inside brackets and braces; rows/inline arrays use "|".
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
-
|
|
538
|
-
-
|
|
539
|
-
-
|
|
519
|
+
|
|
520
|
+
### 11.1 Encoding Rules (Normative for Encoders)
|
|
521
|
+
|
|
522
|
+
- Document delimiter: Encoders select a document delimiter (option: comma, tab, pipe; default comma) that influences quoting for all object field values (key: value) throughout the document.
|
|
523
|
+
- Active delimiter: Inside an array header's scope, the active delimiter governs quoting only for inline array values and tabular row cells.
|
|
524
|
+
- Delimiter-aware quoting:
|
|
525
|
+
- Inline array values and tabular row cells: strings containing the active delimiter MUST be quoted.
|
|
526
|
+
- Object field values (key: value): encoders use the document delimiter to decide delimiter-aware quoting, regardless of whether the object appears within an array's scope.
|
|
527
|
+
- Strings containing non-active delimiters do not require quoting unless another condition applies (§7.2).
|
|
528
|
+
|
|
529
|
+
### 11.2 Decoding Rules (Normative for Decoders)
|
|
530
|
+
|
|
531
|
+
- Active delimiter: Decoders use only the active delimiter declared by the nearest array header to split inline arrays and tabular rows.
|
|
532
|
+
- Delimiter-aware parsing:
|
|
533
|
+
- Inline arrays and tabular rows MUST be split only on the active delimiter.
|
|
540
534
|
- Splitting MUST preserve empty tokens; surrounding spaces are trimmed, and empty tokens decode to the empty string.
|
|
541
|
-
- Strings containing the active delimiter MUST be quoted to avoid splitting; non-active delimiters MUST NOT cause splits.
|
|
542
535
|
- Nested headers may change the active delimiter; decoding MUST use the delimiter declared by the nearest header.
|
|
543
|
-
- If the bracket declares tab or pipe, the same symbol MUST be used in the fields segment and for splitting all rows/values in that scope.
|
|
536
|
+
- If the bracket declares tab or pipe, the same symbol MUST be used in the fields segment and for splitting all rows/values in that scope (§6).
|
|
537
|
+
- Object field values (key: value): Decoders parse the entire post-colon token as a single value; document delimiter is not a decoder concept.
|
|
544
538
|
|
|
545
539
|
## 12. Indentation and Whitespace
|
|
546
540
|
|
|
@@ -738,12 +732,14 @@ When strict mode is enabled (default), decoders MUST error on the following cond
|
|
|
738
732
|
|
|
739
733
|
### 14.3 Indentation Errors
|
|
740
734
|
|
|
735
|
+
See §12 for indentation semantics. In strict mode, decoders MUST error on:
|
|
741
736
|
- Leading spaces not a multiple of indentSize.
|
|
742
737
|
- Any tab used in indentation (tabs allowed in quoted strings and as HTAB delimiter).
|
|
743
738
|
|
|
744
739
|
### 14.4 Structural Errors
|
|
745
740
|
|
|
746
|
-
|
|
741
|
+
See §12 for blank line semantics. In strict mode, decoders MUST error on:
|
|
742
|
+
- Blank lines inside arrays/tabular rows (between the first and last item/row).
|
|
747
743
|
|
|
748
744
|
For root-form rules, including handling of empty documents, see §5.
|
|
749
745
|
|
|
@@ -1000,14 +996,13 @@ items[2]:
|
|
|
1000
996
|
Nested tabular inside a list item:
|
|
1001
997
|
```
|
|
1002
998
|
items[1]:
|
|
1003
|
-
-
|
|
1004
|
-
users[2]{id,name}:
|
|
999
|
+
- users[2]{id,name}:
|
|
1005
1000
|
1,Ada
|
|
1006
1001
|
2,Bob
|
|
1007
1002
|
status: active
|
|
1008
1003
|
```
|
|
1009
1004
|
|
|
1010
|
-
Note:
|
|
1005
|
+
Note: When a list-item object has a tabular array as its first field, encoders emit the tabular header on the hyphen line with rows at depth +2 and other fields at depth +1. This is the canonical encoding for list-item objects whose first field is a tabular array.
|
|
1011
1006
|
|
|
1012
1007
|
Delimiter variations:
|
|
1013
1008
|
```
|
|
@@ -1235,6 +1230,10 @@ Note: Host-type normalization tests (e.g., BigInt, Date, Set, Map) are language-
|
|
|
1235
1230
|
|
|
1236
1231
|
This appendix summarizes major changes between spec versions. For the complete changelog, see [`CHANGELOG.md`](./CHANGELOG.md) in the specification repository.
|
|
1237
1232
|
|
|
1233
|
+
### v3.0 (2025-11-24)
|
|
1234
|
+
|
|
1235
|
+
- Standardized encoding for list-item objects whose first field is a tabular array (§10).
|
|
1236
|
+
|
|
1238
1237
|
### v2.1 (2025-11-23)
|
|
1239
1238
|
|
|
1240
1239
|
- Tightened canonical encoding for objects as list items (§10): bare `-` for multi-field objects, compact `- key[N]{fields}:` only for single-field tabular arrays, to improve visual consistency and LLM readability.
|
|
@@ -1336,6 +1335,7 @@ Collection Types:
|
|
|
1336
1335
|
- `Map`: Convert to object using `String(key)` for keys and normalizing values recursively. Non-string keys are coerced to strings.
|
|
1337
1336
|
|
|
1338
1337
|
Object Types:
|
|
1338
|
+
- Objects with a `toJSON()` method: Call `value.toJSON()` and then normalize the returned value recursively before encoding. This allows domain objects to override default normalization behavior in a controlled, deterministic way (similar to `JSON.stringify`). Implementations SHOULD guard against `toJSON()` returning the same object (to avoid infinite recursion) and MAY fall back to default normalization in that case.
|
|
1339
1339
|
- Plain objects: Enumerate own enumerable string keys in encounter order; normalize values recursively.
|
|
1340
1340
|
|
|
1341
1341
|
Non-Serializable Types:
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toon-format/spec",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "3.0.1",
|
|
5
5
|
"packageManager": "pnpm@10.19.0",
|
|
6
6
|
"description": "Official specification for Token-Oriented Object Notation (TOON)",
|
|
7
7
|
"author": "Johann Schopplich <hello@johannschopplich.com>",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "
|
|
2
|
+
"version": "3.0",
|
|
3
3
|
"category": "decode",
|
|
4
4
|
"description": "Nested and mixed array decoding - list format, arrays of arrays, root arrays, mixed types",
|
|
5
5
|
"tests": [
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
"specSection": "9.4"
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
|
-
"name": "parses
|
|
56
|
-
"input": "items[1]:\n - users[2]{id,name}:\n
|
|
55
|
+
"name": "parses list items whose first field is a tabular array",
|
|
56
|
+
"input": "items[1]:\n - users[2]{id,name}:\n 1,Ada\n 2,Bob\n status: active",
|
|
57
57
|
"expected": {
|
|
58
58
|
"items": [
|
|
59
59
|
{
|
|
@@ -66,25 +66,23 @@
|
|
|
66
66
|
]
|
|
67
67
|
},
|
|
68
68
|
"specSection": "10",
|
|
69
|
-
"note": "
|
|
69
|
+
"note": "Canonical encoding: tabular header on hyphen line, rows at depth +2, sibling fields at depth +1"
|
|
70
70
|
},
|
|
71
71
|
{
|
|
72
|
-
"name": "parses
|
|
73
|
-
"input": "items[1]:\n
|
|
72
|
+
"name": "parses single-field list-item object with tabular array",
|
|
73
|
+
"input": "items[1]:\n - users[2]{id,name}:\n 1,Ada\n 2,Bob",
|
|
74
74
|
"expected": {
|
|
75
75
|
"items": [
|
|
76
76
|
{
|
|
77
77
|
"users": [
|
|
78
78
|
{ "id": 1, "name": "Ada" },
|
|
79
79
|
{ "id": 2, "name": "Bob" }
|
|
80
|
-
]
|
|
81
|
-
"status": "active"
|
|
80
|
+
]
|
|
82
81
|
}
|
|
83
82
|
]
|
|
84
83
|
},
|
|
85
84
|
"specSection": "10",
|
|
86
|
-
"
|
|
87
|
-
"note": "Canonical v2.1+ encoding (bare hyphen with all fields indented)"
|
|
85
|
+
"note": "Single-field list-item object: only the tabular array, no sibling fields"
|
|
88
86
|
},
|
|
89
87
|
{
|
|
90
88
|
"name": "parses objects containing arrays (including empty arrays) in list format",
|
|
@@ -98,7 +96,7 @@
|
|
|
98
96
|
},
|
|
99
97
|
{
|
|
100
98
|
"name": "parses arrays of arrays within objects",
|
|
101
|
-
"input": "items[1]:\n - matrix[2]:\n
|
|
99
|
+
"input": "items[1]:\n - matrix[2]:\n - [2]: 1,2\n - [2]: 3,4\n name: grid",
|
|
102
100
|
"expected": {
|
|
103
101
|
"items": [
|
|
104
102
|
{ "matrix": [[1, 2], [3, 4]], "name": "grid" }
|
|
@@ -89,6 +89,24 @@
|
|
|
89
89
|
"specSection": "4",
|
|
90
90
|
"note": "Exponent +00 results in the integer 5"
|
|
91
91
|
},
|
|
92
|
+
{
|
|
93
|
+
"name": "parses zero with exponent as number",
|
|
94
|
+
"input": "value: 0e1",
|
|
95
|
+
"expected": {
|
|
96
|
+
"value": 0
|
|
97
|
+
},
|
|
98
|
+
"specSection": "4",
|
|
99
|
+
"note": "Exponent forms with a zero integer part (0e1) are valid numbers"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"name": "parses negative zero with exponent as number",
|
|
103
|
+
"input": "value: -0e1",
|
|
104
|
+
"expected": {
|
|
105
|
+
"value": 0
|
|
106
|
+
},
|
|
107
|
+
"specSection": "4",
|
|
108
|
+
"note": "Negative zero with exponent (-0e1) decodes to numeric 0"
|
|
109
|
+
},
|
|
92
110
|
{
|
|
93
111
|
"name": "parses exponent notation",
|
|
94
112
|
"input": "1e6",
|
|
@@ -137,6 +155,21 @@
|
|
|
137
155
|
"input": "nums[3]: 05,007,0123",
|
|
138
156
|
"expected": { "nums": ["05", "007", "0123"] },
|
|
139
157
|
"specSection": "4"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"name": "treats unquoted negative leading-zero number as string",
|
|
161
|
+
"input": "-05",
|
|
162
|
+
"expected": "-05",
|
|
163
|
+
"specSection": "4",
|
|
164
|
+
"note": "Negative numbers with leading zeros in the integer part are treated as strings"
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"name": "treats negative leading-zeros in array as strings",
|
|
168
|
+
"input": "nums[2]: -05,-007",
|
|
169
|
+
"expected": {
|
|
170
|
+
"nums": ["-05", "-007"]
|
|
171
|
+
},
|
|
172
|
+
"specSection": "4"
|
|
140
173
|
}
|
|
141
174
|
]
|
|
142
175
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "
|
|
2
|
+
"version": "3.0",
|
|
3
3
|
"category": "encode",
|
|
4
4
|
"description": "Nested and mixed array encoding - arrays of arrays, mixed type arrays, root arrays",
|
|
5
5
|
"tests": [
|
|
@@ -50,16 +50,14 @@
|
|
|
50
50
|
{
|
|
51
51
|
"name": "encodes root-level array of non-uniform objects in list format",
|
|
52
52
|
"input": [{ "id": 1 }, { "id": 2, "name": "Ada" }],
|
|
53
|
-
"expected": "[2]:\n
|
|
54
|
-
"specSection": "9.4"
|
|
55
|
-
"minSpecVersion": "2.1"
|
|
53
|
+
"expected": "[2]:\n - id: 1\n - id: 2\n name: Ada",
|
|
54
|
+
"specSection": "9.4"
|
|
56
55
|
},
|
|
57
56
|
{
|
|
58
57
|
"name": "encodes root-level array mixing primitive, object, and array of objects in list format",
|
|
59
58
|
"input": ["summary", { "id": 1, "name": "Ada" }, [{ "id": 2 }, { "status": "draft" }]],
|
|
60
|
-
"expected": "[3]:\n - summary\n
|
|
61
|
-
"specSection": "9.4"
|
|
62
|
-
"minSpecVersion": "2.1"
|
|
59
|
+
"expected": "[3]:\n - summary\n - id: 1\n name: Ada\n - [2]:\n - id: 2\n - status: draft",
|
|
60
|
+
"specSection": "9.4"
|
|
63
61
|
},
|
|
64
62
|
{
|
|
65
63
|
"name": "encodes root-level arrays of arrays",
|
|
@@ -92,18 +90,16 @@
|
|
|
92
90
|
"input": {
|
|
93
91
|
"items": [1, { "a": 1 }, "text"]
|
|
94
92
|
},
|
|
95
|
-
"expected": "items[3]:\n - 1\n
|
|
96
|
-
"specSection": "9.4"
|
|
97
|
-
"minSpecVersion": "2.1"
|
|
93
|
+
"expected": "items[3]:\n - 1\n - a: 1\n - text",
|
|
94
|
+
"specSection": "9.4"
|
|
98
95
|
},
|
|
99
96
|
{
|
|
100
97
|
"name": "uses list format for arrays mixing objects and arrays",
|
|
101
98
|
"input": {
|
|
102
99
|
"items": [{ "a": 1 }, [1, 2]]
|
|
103
100
|
},
|
|
104
|
-
"expected": "items[2]:\n
|
|
105
|
-
"specSection": "9.4"
|
|
106
|
-
"minSpecVersion": "2.1"
|
|
101
|
+
"expected": "items[2]:\n - a: 1\n - [2]: 1,2",
|
|
102
|
+
"specSection": "9.4"
|
|
107
103
|
}
|
|
108
104
|
]
|
|
109
105
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "
|
|
2
|
+
"version": "3.0",
|
|
3
3
|
"category": "encode",
|
|
4
4
|
"description": "Arrays of objects encoding - list format for non-uniform objects and complex structures",
|
|
5
5
|
"tests": [
|
|
@@ -11,9 +11,8 @@
|
|
|
11
11
|
{ "id": 2, "name": "Second", "extra": true }
|
|
12
12
|
]
|
|
13
13
|
},
|
|
14
|
-
"expected": "items[2]:\n
|
|
15
|
-
"specSection": "9.4"
|
|
16
|
-
"minSpecVersion": "2.1"
|
|
14
|
+
"expected": "items[2]:\n - id: 1\n name: First\n - id: 2\n name: Second\n extra: true",
|
|
15
|
+
"specSection": "9.4"
|
|
17
16
|
},
|
|
18
17
|
{
|
|
19
18
|
"name": "uses list format for objects with nested values",
|
|
@@ -22,27 +21,24 @@
|
|
|
22
21
|
{ "id": 1, "nested": { "x": 1 } }
|
|
23
22
|
]
|
|
24
23
|
},
|
|
25
|
-
"expected": "items[1]:\n
|
|
26
|
-
"specSection": "9.4"
|
|
27
|
-
"minSpecVersion": "2.1"
|
|
24
|
+
"expected": "items[1]:\n - id: 1\n nested:\n x: 1",
|
|
25
|
+
"specSection": "9.4"
|
|
28
26
|
},
|
|
29
27
|
{
|
|
30
28
|
"name": "preserves field order in list items - array first",
|
|
31
29
|
"input": {
|
|
32
30
|
"items": [{ "nums": [1, 2, 3], "name": "Ada" }]
|
|
33
31
|
},
|
|
34
|
-
"expected": "items[1]:\n
|
|
35
|
-
"specSection": "10"
|
|
36
|
-
"minSpecVersion": "2.1"
|
|
32
|
+
"expected": "items[1]:\n - nums[3]: 1,2,3\n name: Ada",
|
|
33
|
+
"specSection": "10"
|
|
37
34
|
},
|
|
38
35
|
{
|
|
39
36
|
"name": "preserves field order in list items - primitive first",
|
|
40
37
|
"input": {
|
|
41
38
|
"items": [{ "name": "Ada", "nums": [1, 2, 3] }]
|
|
42
39
|
},
|
|
43
|
-
"expected": "items[1]:\n
|
|
44
|
-
"specSection": "10"
|
|
45
|
-
"minSpecVersion": "2.1"
|
|
40
|
+
"expected": "items[1]:\n - name: Ada\n nums[3]: 1,2,3",
|
|
41
|
+
"specSection": "10"
|
|
46
42
|
},
|
|
47
43
|
{
|
|
48
44
|
"name": "uses list format for objects containing arrays of arrays",
|
|
@@ -51,9 +47,8 @@
|
|
|
51
47
|
{ "matrix": [[1, 2], [3, 4]], "name": "grid" }
|
|
52
48
|
]
|
|
53
49
|
},
|
|
54
|
-
"expected": "items[1]:\n
|
|
55
|
-
"specSection": "10"
|
|
56
|
-
"minSpecVersion": "2.1"
|
|
50
|
+
"expected": "items[1]:\n - matrix[2]:\n - [2]: 1,2\n - [2]: 3,4\n name: grid",
|
|
51
|
+
"specSection": "10"
|
|
57
52
|
},
|
|
58
53
|
{
|
|
59
54
|
"name": "uses tabular format for nested uniform object arrays",
|
|
@@ -62,10 +57,9 @@
|
|
|
62
57
|
{ "users": [{ "id": 1, "name": "Ada" }, { "id": 2, "name": "Bob" }], "status": "active" }
|
|
63
58
|
]
|
|
64
59
|
},
|
|
65
|
-
"expected": "items[1]:\n
|
|
60
|
+
"expected": "items[1]:\n - users[2]{id,name}:\n 1,Ada\n 2,Bob\n status: active",
|
|
66
61
|
"specSection": "10",
|
|
67
|
-
"
|
|
68
|
-
"note": "Bare hyphen format for multi-field objects with tabular arrays"
|
|
62
|
+
"note": "YAML-style encoding for list-item objects with tabular array as first field"
|
|
69
63
|
},
|
|
70
64
|
{
|
|
71
65
|
"name": "uses list format for nested object arrays with mismatched keys",
|
|
@@ -74,27 +68,24 @@
|
|
|
74
68
|
{ "users": [{ "id": 1, "name": "Ada" }, { "id": 2 }], "status": "active" }
|
|
75
69
|
]
|
|
76
70
|
},
|
|
77
|
-
"expected": "items[1]:\n
|
|
78
|
-
"specSection": "10"
|
|
79
|
-
"minSpecVersion": "2.1"
|
|
71
|
+
"expected": "items[1]:\n - users[2]:\n - id: 1\n name: Ada\n - id: 2\n status: active",
|
|
72
|
+
"specSection": "10"
|
|
80
73
|
},
|
|
81
74
|
{
|
|
82
75
|
"name": "uses list format for objects with multiple array fields",
|
|
83
76
|
"input": {
|
|
84
77
|
"items": [{ "nums": [1, 2], "tags": ["a", "b"], "name": "test" }]
|
|
85
78
|
},
|
|
86
|
-
"expected": "items[1]:\n
|
|
87
|
-
"specSection": "10"
|
|
88
|
-
"minSpecVersion": "2.1"
|
|
79
|
+
"expected": "items[1]:\n - nums[2]: 1,2\n tags[2]: a,b\n name: test",
|
|
80
|
+
"specSection": "10"
|
|
89
81
|
},
|
|
90
82
|
{
|
|
91
83
|
"name": "uses list format for objects with only array fields",
|
|
92
84
|
"input": {
|
|
93
85
|
"items": [{ "nums": [1, 2, 3], "tags": ["a", "b"] }]
|
|
94
86
|
},
|
|
95
|
-
"expected": "items[1]:\n
|
|
96
|
-
"specSection": "10"
|
|
97
|
-
"minSpecVersion": "2.1"
|
|
87
|
+
"expected": "items[1]:\n - nums[3]: 1,2,3\n tags[2]: a,b",
|
|
88
|
+
"specSection": "10"
|
|
98
89
|
},
|
|
99
90
|
{
|
|
100
91
|
"name": "encodes objects with empty arrays in list format",
|
|
@@ -103,38 +94,43 @@
|
|
|
103
94
|
{ "name": "Ada", "data": [] }
|
|
104
95
|
]
|
|
105
96
|
},
|
|
106
|
-
"expected": "items[1]:\n
|
|
107
|
-
"specSection": "10"
|
|
108
|
-
"minSpecVersion": "2.1"
|
|
97
|
+
"expected": "items[1]:\n - name: Ada\n data[0]:",
|
|
98
|
+
"specSection": "10"
|
|
109
99
|
},
|
|
110
100
|
{
|
|
111
|
-
"name": "uses
|
|
101
|
+
"name": "uses canonical encoding for multi-field list-item objects with tabular arrays",
|
|
112
102
|
"input": {
|
|
113
103
|
"items": [{ "users": [{ "id": 1 }, { "id": 2 }], "note": "x" }]
|
|
114
104
|
},
|
|
115
|
-
"expected": "items[1]:\n
|
|
105
|
+
"expected": "items[1]:\n - users[2]{id}:\n 1\n 2\n note: x",
|
|
116
106
|
"specSection": "10",
|
|
117
|
-
"
|
|
118
|
-
"note": "Multi-field objects use bare hyphen with all fields indented"
|
|
107
|
+
"note": "Tabular header on hyphen line with rows at depth +2 and sibling fields at depth +1"
|
|
119
108
|
},
|
|
120
109
|
{
|
|
121
|
-
"name": "uses
|
|
110
|
+
"name": "uses canonical encoding for single-field list-item tabular arrays",
|
|
122
111
|
"input": {
|
|
123
112
|
"items": [{ "users": [{ "id": 1, "name": "Ada" }, { "id": 2, "name": "Bob" }] }]
|
|
124
113
|
},
|
|
125
|
-
"expected": "items[1]:\n - users[2]{id,name}:\n
|
|
114
|
+
"expected": "items[1]:\n - users[2]{id,name}:\n 1,Ada\n 2,Bob",
|
|
126
115
|
"specSection": "10",
|
|
127
|
-
"
|
|
128
|
-
"note": "Single-field objects with tabular arrays use compact form on hyphen line"
|
|
116
|
+
"note": "Tabular header on hyphen line with rows at depth +2"
|
|
129
117
|
},
|
|
130
118
|
{
|
|
131
119
|
"name": "places empty arrays on hyphen line when first",
|
|
132
120
|
"input": {
|
|
133
121
|
"items": [{ "data": [], "name": "x" }]
|
|
134
122
|
},
|
|
135
|
-
"expected": "items[1]:\n
|
|
123
|
+
"expected": "items[1]:\n - data[0]:\n name: x",
|
|
124
|
+
"specSection": "10"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"name": "encodes empty object list items as bare hyphen",
|
|
128
|
+
"input": {
|
|
129
|
+
"items": ["first", "second", {}]
|
|
130
|
+
},
|
|
131
|
+
"expected": "items[3]:\n - first\n - second\n -",
|
|
136
132
|
"specSection": "10",
|
|
137
|
-
"
|
|
133
|
+
"note": "Empty object list items encode as a single \"-\" line at the list-item depth"
|
|
138
134
|
},
|
|
139
135
|
{
|
|
140
136
|
"name": "uses field order from first object for tabular headers",
|
|
@@ -155,9 +151,8 @@
|
|
|
155
151
|
{ "id": 2, "data": { "nested": true } }
|
|
156
152
|
]
|
|
157
153
|
},
|
|
158
|
-
"expected": "items[2]:\n
|
|
159
|
-
"specSection": "9.4"
|
|
160
|
-
"minSpecVersion": "2.1"
|
|
154
|
+
"expected": "items[2]:\n - id: 1\n data: string\n - id: 2\n data:\n nested: true",
|
|
155
|
+
"specSection": "9.4"
|
|
161
156
|
}
|
|
162
157
|
]
|
|
163
158
|
}
|