@toon-format/spec 1.3.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.
- package/CHANGELOG.md +42 -0
- package/CONTRIBUTING.md +259 -0
- package/LICENSE +21 -0
- package/README.md +111 -0
- package/SPEC.md +1089 -0
- package/VERSIONING.md +150 -0
- package/package.json +42 -0
- package/tests/README.md +218 -0
- package/tests/fixtures/decode/arrays-nested.json +156 -0
- package/tests/fixtures/decode/arrays-primitive.json +87 -0
- package/tests/fixtures/decode/arrays-tabular.json +40 -0
- package/tests/fixtures/decode/blank-lines.json +153 -0
- package/tests/fixtures/decode/delimiters.json +237 -0
- package/tests/fixtures/decode/indentation-errors.json +197 -0
- package/tests/fixtures/decode/objects.json +238 -0
- package/tests/fixtures/decode/primitives.json +189 -0
- package/tests/fixtures/decode/validation-errors.json +63 -0
- package/tests/fixtures/encode/arrays-nested.json +99 -0
- package/tests/fixtures/encode/arrays-objects.json +138 -0
- package/tests/fixtures/encode/arrays-primitive.json +87 -0
- package/tests/fixtures/encode/arrays-tabular.json +62 -0
- package/tests/fixtures/encode/delimiters.json +253 -0
- package/tests/fixtures/encode/normalization.json +107 -0
- package/tests/fixtures/encode/objects.json +220 -0
- package/tests/fixtures/encode/options.json +88 -0
- package/tests/fixtures/encode/primitives.json +226 -0
- package/tests/fixtures/encode/whitespace.json +29 -0
- package/tests/fixtures.schema.json +106 -0
package/VERSIONING.md
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# TOON Specification Versioning Policy
|
|
2
|
+
|
|
3
|
+
This document outlines the versioning policy for the TOON specification.
|
|
4
|
+
|
|
5
|
+
## Semantic Versioning
|
|
6
|
+
|
|
7
|
+
The TOON specification follows [Semantic Versioning](https://semver.org/) with a `MAJOR.MINOR` format (specifications don't need PATCH versions).
|
|
8
|
+
|
|
9
|
+
### Version Format
|
|
10
|
+
|
|
11
|
+
**`MAJOR.MINOR`**
|
|
12
|
+
|
|
13
|
+
- **MAJOR version** - Incremented for breaking changes that are incompatible with previous versions
|
|
14
|
+
- **MINOR version** - Incremented for backward-compatible additions, clarifications, or non-breaking changes
|
|
15
|
+
|
|
16
|
+
**Example:** Moving from v1.3 to v1.4 means your implementation keeps working. Moving from v1.3 to v2.0 means you'll likely need to update your code.
|
|
17
|
+
|
|
18
|
+
## What Constitutes a Breaking Change
|
|
19
|
+
|
|
20
|
+
Breaking changes (requiring a MAJOR version bump) include:
|
|
21
|
+
|
|
22
|
+
### Syntax Changes
|
|
23
|
+
|
|
24
|
+
- Removing or changing existing syntax.
|
|
25
|
+
- Changing the meaning of existing constructs.
|
|
26
|
+
- Adding new reserved characters that could conflict with existing valid TOON documents.
|
|
27
|
+
- Changing encoding/decoding behavior in incompatible ways.
|
|
28
|
+
|
|
29
|
+
### Semantic Changes
|
|
30
|
+
|
|
31
|
+
- Changing how valid TOON should be interpreted.
|
|
32
|
+
- Modifying type conversion rules in incompatible ways.
|
|
33
|
+
- Changing quoting rules in ways that break existing documents.
|
|
34
|
+
- Altering delimiter behavior.
|
|
35
|
+
|
|
36
|
+
### Conformance Changes
|
|
37
|
+
|
|
38
|
+
- Making previously valid TOON invalid.
|
|
39
|
+
- Adding new MUST requirements that existing implementations don't meet.
|
|
40
|
+
- Changing error handling in ways that break round-trip compatibility.
|
|
41
|
+
|
|
42
|
+
## What Constitutes a Non-Breaking Change
|
|
43
|
+
|
|
44
|
+
Non-breaking changes (MINOR version bump) include:
|
|
45
|
+
|
|
46
|
+
### Clarifications
|
|
47
|
+
|
|
48
|
+
- Clarifying ambiguous language without changing behavior.
|
|
49
|
+
- Adding examples to illustrate existing rules.
|
|
50
|
+
- Improving specification wording for clarity.
|
|
51
|
+
- Adding informative (non-normative) sections.
|
|
52
|
+
|
|
53
|
+
### Backward-Compatible Additions
|
|
54
|
+
|
|
55
|
+
- Adding optional features that don't affect existing documents.
|
|
56
|
+
- Adding new SHOULD or MAY recommendations.
|
|
57
|
+
- Expanding the specification to cover previously undefined behavior (if done in a backward-compatible way).
|
|
58
|
+
- Adding new test cases that existing conformant implementations already pass.
|
|
59
|
+
|
|
60
|
+
### Documentation Improvements
|
|
61
|
+
|
|
62
|
+
- Grammar and typo fixes.
|
|
63
|
+
- Reorganizing content for better readability.
|
|
64
|
+
- Adding cross-references.
|
|
65
|
+
- Improving examples.
|
|
66
|
+
|
|
67
|
+
## Version Lifecycle
|
|
68
|
+
|
|
69
|
+
### Working Draft
|
|
70
|
+
|
|
71
|
+
- Current development version.
|
|
72
|
+
- May receive updates without version changes.
|
|
73
|
+
- Indicated by "Status: Working Draft" in the specification.
|
|
74
|
+
|
|
75
|
+
### Stable Release
|
|
76
|
+
|
|
77
|
+
- Released versions are immutable.
|
|
78
|
+
- Version number is assigned when changes are merged.
|
|
79
|
+
- Previous versions remain available for reference.
|
|
80
|
+
|
|
81
|
+
### Deprecation
|
|
82
|
+
|
|
83
|
+
If we need to make a breaking change (MAJOR version bump):
|
|
84
|
+
|
|
85
|
+
1. **Announcement:** We add a deprecation notice to the current spec
|
|
86
|
+
2. **Migration Period:** The next MINOR version includes migration guidance
|
|
87
|
+
3. **New Major Version:** Breaking changes are released in the next MAJOR version
|
|
88
|
+
4. **Support:** Previous MAJOR versions remain available – we don't break old links
|
|
89
|
+
|
|
90
|
+
## Implementation Compatibility
|
|
91
|
+
|
|
92
|
+
### Specification Version Support
|
|
93
|
+
|
|
94
|
+
If you're implementing TOON, clearly document which spec version you support:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"toon-spec": "1.3"
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
This helps users know what behavior to expect.
|
|
103
|
+
|
|
104
|
+
### Forward Compatibility
|
|
105
|
+
|
|
106
|
+
Your implementation can support multiple spec versions. If you do:
|
|
107
|
+
|
|
108
|
+
1. Default to the latest supported version
|
|
109
|
+
2. Let users specify which version to target
|
|
110
|
+
3. Document version-specific behavior clearly
|
|
111
|
+
|
|
112
|
+
### Backward Compatibility
|
|
113
|
+
|
|
114
|
+
**When a new MINOR version is released:**
|
|
115
|
+
|
|
116
|
+
- Your implementation stays conformant – no code changes needed
|
|
117
|
+
- Updates may be recommended but aren't required
|
|
118
|
+
|
|
119
|
+
**When a new MAJOR version is released:**
|
|
120
|
+
|
|
121
|
+
- You may need updates to support the new version
|
|
122
|
+
- Previous version implementations remain valid
|
|
123
|
+
- We'll provide a migration guide
|
|
124
|
+
|
|
125
|
+
## Version Numbering Examples
|
|
126
|
+
|
|
127
|
+
### Current: v1.3
|
|
128
|
+
|
|
129
|
+
**Next minor update (clarifications, additions):**
|
|
130
|
+
- v1.4
|
|
131
|
+
|
|
132
|
+
**Next major update (breaking changes):**
|
|
133
|
+
- v2.0
|
|
134
|
+
|
|
135
|
+
**After v2.0, next minor update:**
|
|
136
|
+
- v2.1
|
|
137
|
+
|
|
138
|
+
## Version History
|
|
139
|
+
|
|
140
|
+
See [CHANGELOG.md](./CHANGELOG.md) for detailed version history.
|
|
141
|
+
|
|
142
|
+
## Questions
|
|
143
|
+
|
|
144
|
+
Not sure if your proposed change is breaking or non-breaking?
|
|
145
|
+
|
|
146
|
+
1. Open an issue with the `[RFC]` tag
|
|
147
|
+
2. Describe the proposed change
|
|
148
|
+
3. Ask for feedback from maintainers and community
|
|
149
|
+
|
|
150
|
+
When in doubt, we err on the side of caution and treat potentially breaking changes as MAJOR version bumps.
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@toon-format/spec",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "1.3.0",
|
|
5
|
+
"packageManager": "pnpm@10.19.0",
|
|
6
|
+
"description": "Official specification for Token-Oriented Object Notation (TOON)",
|
|
7
|
+
"author": "Johann Schopplich <hello@johannschopplich.com>",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"homepage": "https://github.com/toon-format/spec",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/toon-format/spec.git"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/toon-format/spec/issues"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"toon",
|
|
19
|
+
"format",
|
|
20
|
+
"specification",
|
|
21
|
+
"llm",
|
|
22
|
+
"token-efficiency",
|
|
23
|
+
"data-format"
|
|
24
|
+
],
|
|
25
|
+
"files": [
|
|
26
|
+
"CHANGELOG.md",
|
|
27
|
+
"CONTRIBUTING.md",
|
|
28
|
+
"SPEC.md",
|
|
29
|
+
"VERSIONING.md",
|
|
30
|
+
"tests"
|
|
31
|
+
],
|
|
32
|
+
"scripts": {
|
|
33
|
+
"lint": "eslint .",
|
|
34
|
+
"release": "bumpp"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@antfu/eslint-config": "^6.2.0",
|
|
38
|
+
"bumpp": "^10.3.1",
|
|
39
|
+
"eslint": "^9.39.0",
|
|
40
|
+
"vitest": "^4.0.6"
|
|
41
|
+
}
|
|
42
|
+
}
|
package/tests/README.md
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# TOON Test Fixtures
|
|
2
|
+
|
|
3
|
+
This directory contains **comprehensive language-agnostic JSON test fixtures** for validating TOON implementations against the specification. These fixtures cover all specification requirements and provide a standardized conformance test suite.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
The test fixtures serve multiple purposes:
|
|
8
|
+
|
|
9
|
+
- **Conformance validation:** Verify implementations follow the specification
|
|
10
|
+
- **Regression testing:** Catch behavioral changes across versions
|
|
11
|
+
- **Implementation guide:** Demonstrate expected encoding/decoding behavior
|
|
12
|
+
- **Cross-language consistency:** Ensure all implementations produce identical output
|
|
13
|
+
|
|
14
|
+
## Directory Structure
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
tests/
|
|
18
|
+
├── fixtures.schema.json # JSON Schema for fixture validation
|
|
19
|
+
├── fixtures/
|
|
20
|
+
│ ├── encode/ # Encoding tests (JSON → TOON)
|
|
21
|
+
│ │ ├── primitives.json
|
|
22
|
+
│ │ ├── objects.json
|
|
23
|
+
│ │ ├── arrays-primitive.json
|
|
24
|
+
│ │ ├── arrays-tabular.json
|
|
25
|
+
│ │ ├── arrays-nested.json
|
|
26
|
+
│ │ ├── arrays-objects.json
|
|
27
|
+
│ │ ├── delimiters.json
|
|
28
|
+
│ │ ├── normalization.json
|
|
29
|
+
│ │ ├── whitespace.json
|
|
30
|
+
│ │ └── options.json
|
|
31
|
+
│ └── decode/ # Decoding tests (TOON → JSON)
|
|
32
|
+
│ ├── primitives.json
|
|
33
|
+
│ ├── objects.json
|
|
34
|
+
│ ├── arrays-primitive.json
|
|
35
|
+
│ ├── arrays-tabular.json
|
|
36
|
+
│ ├── arrays-nested.json
|
|
37
|
+
│ ├── delimiters.json
|
|
38
|
+
│ ├── validation-errors.json
|
|
39
|
+
│ ├── indentation-errors.json
|
|
40
|
+
│ └── blank-lines.json
|
|
41
|
+
└── README.md # This file
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Fixture Format
|
|
45
|
+
|
|
46
|
+
All test fixtures follow a standard JSON structure defined in [`fixtures.schema.json`](./fixtures.schema.json):
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"version": "1.3",
|
|
51
|
+
"category": "encode",
|
|
52
|
+
"description": "Brief description of test category",
|
|
53
|
+
"tests": [
|
|
54
|
+
{
|
|
55
|
+
"name": "descriptive test name",
|
|
56
|
+
"input": "JSON value or TOON string",
|
|
57
|
+
"expected": "TOON string or JSON value",
|
|
58
|
+
"options": {},
|
|
59
|
+
"specSection": "7.2",
|
|
60
|
+
"note": "Optional explanation"
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Field Descriptions
|
|
67
|
+
|
|
68
|
+
| Field | Required | Description |
|
|
69
|
+
|-------|----------|-------------|
|
|
70
|
+
| `version` | Yes | TOON specification version (e.g., `"1.3"`) |
|
|
71
|
+
| `category` | Yes | Test category: `"encode"` or `"decode"` |
|
|
72
|
+
| `description` | Yes | Brief description of what this fixture tests |
|
|
73
|
+
| `tests` | Yes | Array of test cases |
|
|
74
|
+
| `tests[].name` | Yes | Descriptive name explaining what is validated |
|
|
75
|
+
| `tests[].input` | Yes | Input value (JSON for encode, TOON string for decode) |
|
|
76
|
+
| `tests[].expected` | Yes | Expected output (TOON string for encode, JSON for decode) |
|
|
77
|
+
| `tests[].shouldError` | No | If `true`, expects an error (default: `false`) |
|
|
78
|
+
| `tests[].options` | No | Encoder/decoder options (see below) |
|
|
79
|
+
| `tests[].specSection` | No | Reference to specification section (e.g., `"7.2"`, `"§6"`) |
|
|
80
|
+
| `tests[].note` | No | Optional explanation for special cases |
|
|
81
|
+
| `tests[].minSpecVersion` | No | Minimum spec version required (e.g., `"1.3"`) |
|
|
82
|
+
|
|
83
|
+
### Options
|
|
84
|
+
|
|
85
|
+
#### Encoding Options
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"delimiter": ",",
|
|
90
|
+
"indent": 2,
|
|
91
|
+
"lengthMarker": ""
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- `delimiter`: `","` (comma, default), `"\t"` (tab), or `"|"` (pipe)
|
|
96
|
+
- `indent`: Number of spaces per indentation level (default: `2`)
|
|
97
|
+
- `lengthMarker`: `"#"` to prefix array lengths, or `""` for no marker (default: `""`)
|
|
98
|
+
|
|
99
|
+
#### Decoding Options
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"indent": 2,
|
|
104
|
+
"strict": true
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
- `indent`: Expected number of spaces per level (default: `2`)
|
|
109
|
+
- `strict`: Enable strict validation (default: `true`)
|
|
110
|
+
|
|
111
|
+
### Error Tests
|
|
112
|
+
|
|
113
|
+
Error tests use `shouldError: true` to indicate that the test expects an error to be thrown:
|
|
114
|
+
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"name": "throws on array length mismatch",
|
|
118
|
+
"input": "tags[3]: a,b",
|
|
119
|
+
"expected": null,
|
|
120
|
+
"shouldError": true,
|
|
121
|
+
"options": { "strict": true }
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Note:** Error tests do not specify expected error messages, as these are implementation-specific and vary across languages.
|
|
126
|
+
|
|
127
|
+
## Using These Tests
|
|
128
|
+
|
|
129
|
+
To validate your TOON implementation against these fixtures:
|
|
130
|
+
|
|
131
|
+
1. **Load a fixture file** from `fixtures/encode/` or `fixtures/decode/`.
|
|
132
|
+
2. **Iterate through the `tests` array** in the fixture.
|
|
133
|
+
3. **For each test case:**
|
|
134
|
+
- If `shouldError` is `true`: verify your implementation throws an error.
|
|
135
|
+
- Otherwise: assert that your encoder/decoder produces the `expected` output when given the `input`.
|
|
136
|
+
4. **Pass options** from `test.options` to your encoder/decoder (if present).
|
|
137
|
+
|
|
138
|
+
The fixture format is language-agnostic JSON, so you can load and iterate it using your language's standard JSON parser and test framework.
|
|
139
|
+
|
|
140
|
+
## Test Coverage
|
|
141
|
+
|
|
142
|
+
### Encoding Tests (`fixtures/encode/`)
|
|
143
|
+
|
|
144
|
+
| File | Description | Spec Sections |
|
|
145
|
+
|------|-------------|---------------|
|
|
146
|
+
| `primitives.json` | String, number, boolean, null encoding and escaping | §5 |
|
|
147
|
+
| `objects.json` | Simple objects, nested objects, key encoding | §6 |
|
|
148
|
+
| `arrays-primitive.json` | Inline primitive arrays, empty arrays | §7.1 |
|
|
149
|
+
| `arrays-tabular.json` | Tabular format with header and rows | §7.2 |
|
|
150
|
+
| `arrays-nested.json` | Arrays of arrays, mixed arrays | §7.3 |
|
|
151
|
+
| `arrays-objects.json` | Objects as list items, complex nesting | §7 |
|
|
152
|
+
| `delimiters.json` | Tab and pipe delimiter options | §8 |
|
|
153
|
+
| `normalization.json` | BigInt, Date, undefined, NaN, Infinity handling | §5 |
|
|
154
|
+
| `whitespace.json` | Formatting invariants and indentation | §4 |
|
|
155
|
+
| `options.json` | Length marker and delimiter option combinations | §3 |
|
|
156
|
+
|
|
157
|
+
### Decoding Tests (`fixtures/decode/`)
|
|
158
|
+
|
|
159
|
+
| File | Description | Spec Sections |
|
|
160
|
+
|------|-------------|---------------|
|
|
161
|
+
| `primitives.json` | Parsing primitives, unescaping, ambiguity | §5 |
|
|
162
|
+
| `objects.json` | Parsing objects, keys, nesting | §6 |
|
|
163
|
+
| `arrays-primitive.json` | Inline array parsing | §7.1 |
|
|
164
|
+
| `arrays-tabular.json` | Tabular format parsing | §7.2 |
|
|
165
|
+
| `arrays-nested.json` | Nested and mixed array parsing | §7.3 |
|
|
166
|
+
| `delimiters.json` | Delimiter detection and parsing | §8 |
|
|
167
|
+
| `validation-errors.json` | Syntax errors, length mismatches, malformed input | §9 |
|
|
168
|
+
| `indentation-errors.json` | Strict mode indentation validation | §9 |
|
|
169
|
+
| `blank-lines.json` | Blank line handling in arrays | §9 |
|
|
170
|
+
|
|
171
|
+
## Validating Fixtures
|
|
172
|
+
|
|
173
|
+
All fixture files should validate against [`fixtures.schema.json`](./fixtures.schema.json). You can use standard JSON Schema validators:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
# Using ajv-cli
|
|
177
|
+
npx ajv-cli validate -s fixtures.schema.json -d "fixtures/**/*.json"
|
|
178
|
+
|
|
179
|
+
# Using check-jsonschema (Python)
|
|
180
|
+
pip install check-jsonschema
|
|
181
|
+
check-jsonschema --schemafile fixtures.schema.json fixtures/**/*.json
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Contributing Test Cases
|
|
185
|
+
|
|
186
|
+
To contribute new test cases:
|
|
187
|
+
|
|
188
|
+
1. **Identify the category:** Which fixture file should contain the test?
|
|
189
|
+
2. **Follow the format:** Use the structure defined in `fixtures.schema.json`
|
|
190
|
+
3. **Add spec references:** Link to relevant specification sections
|
|
191
|
+
4. **Validate:** Ensure your fixture validates against the schema
|
|
192
|
+
5. **Test with reference implementation:** Verify expected output is correct
|
|
193
|
+
6. **Submit PR:** Include clear description of what the test validates
|
|
194
|
+
|
|
195
|
+
See [CONTRIBUTING.md](../CONTRIBUTING.md) for detailed guidelines.
|
|
196
|
+
|
|
197
|
+
## Reference Implementation
|
|
198
|
+
|
|
199
|
+
The reference implementation in TypeScript/JavaScript is maintained at: [github.com/toon-format/toon](https://github.com/toon-format/toon)
|
|
200
|
+
|
|
201
|
+
## Questions or Issues?
|
|
202
|
+
|
|
203
|
+
If you find:
|
|
204
|
+
|
|
205
|
+
- Test cases that contradict the specification
|
|
206
|
+
- Missing coverage for edge cases
|
|
207
|
+
- Ambiguous expected outputs
|
|
208
|
+
- Schema validation issues
|
|
209
|
+
|
|
210
|
+
Please [open an issue](https://github.com/toon-format/spec/issues) with:
|
|
211
|
+
|
|
212
|
+
- Fixture file and test case name
|
|
213
|
+
- Description of the issue
|
|
214
|
+
- Proposed fix (if applicable)
|
|
215
|
+
|
|
216
|
+
## License
|
|
217
|
+
|
|
218
|
+
These test fixtures are released under the MIT License, the same as the specification.
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.3",
|
|
3
|
+
"category": "decode",
|
|
4
|
+
"description": "Nested and mixed array decoding - list format, arrays of arrays, root arrays, mixed types",
|
|
5
|
+
"tests": [
|
|
6
|
+
{
|
|
7
|
+
"name": "parses list arrays for non-uniform objects",
|
|
8
|
+
"input": "items[2]:\n - id: 1\n name: First\n - id: 2\n name: Second\n extra: true",
|
|
9
|
+
"expected": {
|
|
10
|
+
"items": [
|
|
11
|
+
{ "id": 1, "name": "First" },
|
|
12
|
+
{ "id": 2, "name": "Second", "extra": true }
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
"specSection": "7"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "parses objects with nested values inside list items",
|
|
19
|
+
"input": "items[1]:\n - id: 1\n nested:\n x: 1",
|
|
20
|
+
"expected": {
|
|
21
|
+
"items": [
|
|
22
|
+
{ "id": 1, "nested": { "x": 1 } }
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
"specSection": "7"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "parses nested tabular arrays as first field on hyphen line",
|
|
29
|
+
"input": "items[1]:\n - users[2]{id,name}:\n 1,Ada\n 2,Bob\n status: active",
|
|
30
|
+
"expected": {
|
|
31
|
+
"items": [
|
|
32
|
+
{
|
|
33
|
+
"users": [
|
|
34
|
+
{ "id": 1, "name": "Ada" },
|
|
35
|
+
{ "id": 2, "name": "Bob" }
|
|
36
|
+
],
|
|
37
|
+
"status": "active"
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
"specSection": "7"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "parses objects containing arrays (including empty arrays) in list format",
|
|
45
|
+
"input": "items[1]:\n - name: test\n data[0]:",
|
|
46
|
+
"expected": {
|
|
47
|
+
"items": [
|
|
48
|
+
{ "name": "test", "data": [] }
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
"specSection": "7"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"name": "parses arrays of arrays within objects",
|
|
55
|
+
"input": "items[1]:\n - matrix[2]:\n - [2]: 1,2\n - [2]: 3,4\n name: grid",
|
|
56
|
+
"expected": {
|
|
57
|
+
"items": [
|
|
58
|
+
{ "matrix": [[1, 2], [3, 4]], "name": "grid" }
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
"specSection": "7"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"name": "parses nested arrays of primitives",
|
|
65
|
+
"input": "pairs[2]:\n - [2]: a,b\n - [2]: c,d",
|
|
66
|
+
"expected": {
|
|
67
|
+
"pairs": [["a", "b"], ["c", "d"]]
|
|
68
|
+
},
|
|
69
|
+
"specSection": "7.3"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "parses quoted strings and mixed lengths in nested arrays",
|
|
73
|
+
"input": "pairs[2]:\n - [2]: a,b\n - [3]: \"c,d\",\"e:f\",\"true\"",
|
|
74
|
+
"expected": {
|
|
75
|
+
"pairs": [["a", "b"], ["c,d", "e:f", "true"]]
|
|
76
|
+
},
|
|
77
|
+
"specSection": "7.3"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"name": "parses empty inner arrays",
|
|
81
|
+
"input": "pairs[2]:\n - [0]:\n - [0]:",
|
|
82
|
+
"expected": {
|
|
83
|
+
"pairs": [[], []]
|
|
84
|
+
},
|
|
85
|
+
"specSection": "7.3"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"name": "parses mixed-length inner arrays",
|
|
89
|
+
"input": "pairs[2]:\n - [1]: 1\n - [2]: 2,3",
|
|
90
|
+
"expected": {
|
|
91
|
+
"pairs": [[1], [2, 3]]
|
|
92
|
+
},
|
|
93
|
+
"specSection": "7.3"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"name": "parses root arrays of primitives (inline)",
|
|
97
|
+
"input": "[5]: x,y,\"true\",true,10",
|
|
98
|
+
"expected": ["x", "y", "true", true, 10],
|
|
99
|
+
"specSection": "7"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"name": "parses root arrays of uniform objects in tabular format",
|
|
103
|
+
"input": "[2]{id}:\n 1\n 2",
|
|
104
|
+
"expected": [{ "id": 1 }, { "id": 2 }],
|
|
105
|
+
"specSection": "7.2"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"name": "parses root arrays of non-uniform objects in list format",
|
|
109
|
+
"input": "[2]:\n - id: 1\n - id: 2\n name: Ada",
|
|
110
|
+
"expected": [{ "id": 1 }, { "id": 2, "name": "Ada" }],
|
|
111
|
+
"specSection": "7"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"name": "parses empty root arrays",
|
|
115
|
+
"input": "[0]:",
|
|
116
|
+
"expected": [],
|
|
117
|
+
"specSection": "7"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"name": "parses root arrays of arrays",
|
|
121
|
+
"input": "[2]:\n - [2]: 1,2\n - [0]:",
|
|
122
|
+
"expected": [[1, 2], []],
|
|
123
|
+
"specSection": "7.3"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"name": "parses complex mixed object with arrays and nested objects",
|
|
127
|
+
"input": "user:\n id: 123\n name: Ada\n tags[2]: reading,gaming\n active: true\n prefs[0]:",
|
|
128
|
+
"expected": {
|
|
129
|
+
"user": {
|
|
130
|
+
"id": 123,
|
|
131
|
+
"name": "Ada",
|
|
132
|
+
"tags": ["reading", "gaming"],
|
|
133
|
+
"active": true,
|
|
134
|
+
"prefs": []
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"specSection": "6"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"name": "parses arrays mixing primitives, objects and strings (list format)",
|
|
141
|
+
"input": "items[3]:\n - 1\n - a: 1\n - text",
|
|
142
|
+
"expected": {
|
|
143
|
+
"items": [1, { "a": 1 }, "text"]
|
|
144
|
+
},
|
|
145
|
+
"specSection": "7.3"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"name": "parses arrays mixing objects and arrays",
|
|
149
|
+
"input": "items[2]:\n - a: 1\n - [2]: 1,2",
|
|
150
|
+
"expected": {
|
|
151
|
+
"items": [{ "a": 1 }, [1, 2]]
|
|
152
|
+
},
|
|
153
|
+
"specSection": "7.3"
|
|
154
|
+
}
|
|
155
|
+
]
|
|
156
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.3",
|
|
3
|
+
"category": "decode",
|
|
4
|
+
"description": "Primitive array decoding - inline arrays of strings, numbers, booleans, quoted strings",
|
|
5
|
+
"tests": [
|
|
6
|
+
{
|
|
7
|
+
"name": "parses string arrays inline",
|
|
8
|
+
"input": "tags[3]: reading,gaming,coding",
|
|
9
|
+
"expected": {
|
|
10
|
+
"tags": ["reading", "gaming", "coding"]
|
|
11
|
+
},
|
|
12
|
+
"specSection": "7.1"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"name": "parses number arrays inline",
|
|
16
|
+
"input": "nums[3]: 1,2,3",
|
|
17
|
+
"expected": {
|
|
18
|
+
"nums": [1, 2, 3]
|
|
19
|
+
},
|
|
20
|
+
"specSection": "7.1"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "parses mixed primitive arrays inline",
|
|
24
|
+
"input": "data[4]: x,y,true,10",
|
|
25
|
+
"expected": {
|
|
26
|
+
"data": ["x", "y", true, 10]
|
|
27
|
+
},
|
|
28
|
+
"specSection": "7.1"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "parses empty arrays",
|
|
32
|
+
"input": "items[0]:",
|
|
33
|
+
"expected": {
|
|
34
|
+
"items": []
|
|
35
|
+
},
|
|
36
|
+
"specSection": "7.1"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"name": "parses single-item array with empty string",
|
|
40
|
+
"input": "items[1]: \"\"",
|
|
41
|
+
"expected": {
|
|
42
|
+
"items": [""]
|
|
43
|
+
},
|
|
44
|
+
"specSection": "7.1"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"name": "parses multi-item array with empty string",
|
|
48
|
+
"input": "items[3]: a,\"\",b",
|
|
49
|
+
"expected": {
|
|
50
|
+
"items": ["a", "", "b"]
|
|
51
|
+
},
|
|
52
|
+
"specSection": "7.1"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"name": "parses whitespace-only strings in arrays",
|
|
56
|
+
"input": "items[2]: \" \",\" \"",
|
|
57
|
+
"expected": {
|
|
58
|
+
"items": [" ", " "]
|
|
59
|
+
},
|
|
60
|
+
"specSection": "7.1"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"name": "parses strings with delimiters in arrays",
|
|
64
|
+
"input": "items[3]: a,\"b,c\",\"d:e\"",
|
|
65
|
+
"expected": {
|
|
66
|
+
"items": ["a", "b,c", "d:e"]
|
|
67
|
+
},
|
|
68
|
+
"specSection": "7.1"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"name": "parses strings that look like primitives when quoted",
|
|
72
|
+
"input": "items[4]: x,\"true\",\"42\",\"-3.14\"",
|
|
73
|
+
"expected": {
|
|
74
|
+
"items": ["x", "true", "42", "-3.14"]
|
|
75
|
+
},
|
|
76
|
+
"specSection": "7.1"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"name": "parses strings with structural tokens in arrays",
|
|
80
|
+
"input": "items[3]: \"[5]\",\"- item\",\"{key}\"",
|
|
81
|
+
"expected": {
|
|
82
|
+
"items": ["[5]", "- item", "{key}"]
|
|
83
|
+
},
|
|
84
|
+
"specSection": "7.1"
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.3",
|
|
3
|
+
"category": "decode",
|
|
4
|
+
"description": "Tabular array decoding - parsing arrays of uniform objects with headers",
|
|
5
|
+
"tests": [
|
|
6
|
+
{
|
|
7
|
+
"name": "parses tabular arrays of uniform objects",
|
|
8
|
+
"input": "items[2]{sku,qty,price}:\n A1,2,9.99\n B2,1,14.5",
|
|
9
|
+
"expected": {
|
|
10
|
+
"items": [
|
|
11
|
+
{ "sku": "A1", "qty": 2, "price": 9.99 },
|
|
12
|
+
{ "sku": "B2", "qty": 1, "price": 14.5 }
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
"specSection": "7.2"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "parses nulls and quoted values in tabular rows",
|
|
19
|
+
"input": "items[2]{id,value}:\n 1,null\n 2,\"test\"",
|
|
20
|
+
"expected": {
|
|
21
|
+
"items": [
|
|
22
|
+
{ "id": 1, "value": null },
|
|
23
|
+
{ "id": 2, "value": "test" }
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
"specSection": "7.2"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "parses quoted header keys in tabular arrays",
|
|
30
|
+
"input": "items[2]{\"order:id\",\"full name\"}:\n 1,Ada\n 2,Bob",
|
|
31
|
+
"expected": {
|
|
32
|
+
"items": [
|
|
33
|
+
{ "order:id": 1, "full name": "Ada" },
|
|
34
|
+
{ "order:id": 2, "full name": "Bob" }
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
"specSection": "7.2"
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|