yamlstar 0.0.1 → 0.1.2
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/Makefile +18 -15
- package/ReadMe.md +326 -0
- package/lib/yamlstar/index.js +125 -0
- package/package.json +14 -7
- package/test/test.js +146 -0
- package/Changes +0 -5
- package/src/yamlstar/index.coffee +0 -4
package/Makefile
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+
include ../common/init.mk
|
|
2
|
+
include $M/node.mk
|
|
3
|
+
include $(COMMON)/common.mk
|
|
4
|
+
include $(COMMON)/binding.mk
|
|
2
5
|
|
|
3
|
-
|
|
4
|
-
JS := $(COFFEE:%.coffee=%.js)
|
|
5
|
-
JS := $(JS:src/%=lib/%)
|
|
6
|
+
NODE-MODULES := node_modules
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
MAKES-CLEAN := \
|
|
9
|
+
.npmrc \
|
|
10
|
+
package-lock.json \
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
MAKES-REALCLEAN := \
|
|
13
|
+
$(NODE-MODULES) \
|
|
11
14
|
|
|
12
|
-
lib/%.js: src/%.coffee
|
|
13
|
-
@mkdir -p $(dir $@)
|
|
14
|
-
coffee -c -p $< > $@
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
test: $(NODE-MODULES) $(LIBYAMLSTAR-SO)
|
|
17
|
+
node test/test.js
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
build: $(LIBYAMLSTAR-SO)
|
|
20
|
+
|
|
21
|
+
node_modules: package.json $(NODE)
|
|
22
|
+
npm install
|
|
23
|
+
|
|
24
|
+
release-deps:: $(NODE)
|
package/ReadMe.md
ADDED
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
# YAMLStar Node.js Bindings
|
|
2
|
+
|
|
3
|
+
Node.js bindings for YAMLStar - a pure YAML 1.2 loader implemented in Clojure.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **YAML 1.2 Spec Compliance**: 100% compliant with YAML 1.2 core schema
|
|
8
|
+
- **Pure Implementation**: No dependencies on js-yaml or other external parsers
|
|
9
|
+
- **Fast Native Performance**: Uses GraalVM native-image shared library
|
|
10
|
+
- **Simple API**: Load YAML documents with a single method call
|
|
11
|
+
- **Multi-Document Support**: Load multiple YAML documents from a single string
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
### Prerequisites
|
|
16
|
+
|
|
17
|
+
First, build and install the shared library:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
cd ../libyamlstar
|
|
21
|
+
make native
|
|
22
|
+
sudo make install PREFIX=/usr/local
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Or install to user-local directory:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
cd ../libyamlstar
|
|
29
|
+
make native
|
|
30
|
+
make install PREFIX=~/.local
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Install Node.js Package
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install @yaml/yamlstar
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
For development:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm install
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Quick Start
|
|
46
|
+
|
|
47
|
+
```javascript
|
|
48
|
+
const YAMLStar = require('@yaml/yamlstar');
|
|
49
|
+
|
|
50
|
+
// Create a YAMLStar instance
|
|
51
|
+
const ys = new YAMLStar();
|
|
52
|
+
|
|
53
|
+
// Load a simple YAML string
|
|
54
|
+
const data = ys.load('key: value');
|
|
55
|
+
console.log(data); // { key: 'value' }
|
|
56
|
+
|
|
57
|
+
// Clean up when done
|
|
58
|
+
ys.close();
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Usage Examples
|
|
62
|
+
|
|
63
|
+
### Basic Types
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
const YAMLStar = require('@yaml/yamlstar');
|
|
67
|
+
const ys = new YAMLStar();
|
|
68
|
+
|
|
69
|
+
// Strings
|
|
70
|
+
ys.load('hello'); // 'hello'
|
|
71
|
+
|
|
72
|
+
// Integers
|
|
73
|
+
ys.load('42'); // 42
|
|
74
|
+
|
|
75
|
+
// Floats
|
|
76
|
+
ys.load('3.14'); // 3.14
|
|
77
|
+
|
|
78
|
+
// Booleans
|
|
79
|
+
ys.load('true'); // true
|
|
80
|
+
ys.load('false'); // false
|
|
81
|
+
|
|
82
|
+
// Null
|
|
83
|
+
ys.load('null'); // null
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Collections
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
// Mappings (objects)
|
|
90
|
+
const data = ys.load(`
|
|
91
|
+
name: Alice
|
|
92
|
+
age: 30
|
|
93
|
+
city: Seattle
|
|
94
|
+
`);
|
|
95
|
+
// { name: 'Alice', age: 30, city: 'Seattle' }
|
|
96
|
+
|
|
97
|
+
// Sequences (arrays)
|
|
98
|
+
const data = ys.load(`
|
|
99
|
+
- apple
|
|
100
|
+
- banana
|
|
101
|
+
- orange
|
|
102
|
+
`);
|
|
103
|
+
// ['apple', 'banana', 'orange']
|
|
104
|
+
|
|
105
|
+
// Flow style
|
|
106
|
+
const data = ys.load('[a, b, c]');
|
|
107
|
+
// ['a', 'b', 'c']
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Nested Structures
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
const data = ys.load(`
|
|
114
|
+
person:
|
|
115
|
+
name: Alice
|
|
116
|
+
age: 30
|
|
117
|
+
hobbies:
|
|
118
|
+
- reading
|
|
119
|
+
- coding
|
|
120
|
+
- hiking
|
|
121
|
+
`);
|
|
122
|
+
// {
|
|
123
|
+
// person: {
|
|
124
|
+
// name: 'Alice',
|
|
125
|
+
// age: 30,
|
|
126
|
+
// hobbies: ['reading', 'coding', 'hiking']
|
|
127
|
+
// }
|
|
128
|
+
// }
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Multi-Document YAML
|
|
132
|
+
|
|
133
|
+
```javascript
|
|
134
|
+
// Load all documents from a multi-document YAML string
|
|
135
|
+
const docs = ys.loadAll(`---
|
|
136
|
+
name: Document 1
|
|
137
|
+
---
|
|
138
|
+
name: Document 2
|
|
139
|
+
---
|
|
140
|
+
name: Document 3
|
|
141
|
+
`);
|
|
142
|
+
// [
|
|
143
|
+
// { name: 'Document 1' },
|
|
144
|
+
// { name: 'Document 2' },
|
|
145
|
+
// { name: 'Document 3' }
|
|
146
|
+
// ]
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Type Coercion
|
|
150
|
+
|
|
151
|
+
YAMLStar follows YAML 1.2 core schema type inference:
|
|
152
|
+
|
|
153
|
+
```javascript
|
|
154
|
+
const data = ys.load(`
|
|
155
|
+
string: hello
|
|
156
|
+
integer: 42
|
|
157
|
+
float: 3.14
|
|
158
|
+
bool_true: true
|
|
159
|
+
bool_false: false
|
|
160
|
+
null_value: null
|
|
161
|
+
`);
|
|
162
|
+
// {
|
|
163
|
+
// string: 'hello',
|
|
164
|
+
// integer: 42,
|
|
165
|
+
// float: 3.14,
|
|
166
|
+
// bool_true: true,
|
|
167
|
+
// bool_false: false,
|
|
168
|
+
// null_value: null
|
|
169
|
+
// }
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Error Handling
|
|
173
|
+
|
|
174
|
+
```javascript
|
|
175
|
+
try {
|
|
176
|
+
const data = ys.load('invalid: yaml: syntax');
|
|
177
|
+
} catch (error) {
|
|
178
|
+
console.error('Error loading YAML:', error.message);
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Version Information
|
|
183
|
+
|
|
184
|
+
```javascript
|
|
185
|
+
// Get YAMLStar version
|
|
186
|
+
const version = ys.version();
|
|
187
|
+
console.log(`YAMLStar version: ${version}`);
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Resource Cleanup
|
|
191
|
+
|
|
192
|
+
```javascript
|
|
193
|
+
const ys = new YAMLStar();
|
|
194
|
+
|
|
195
|
+
// ... use ys ...
|
|
196
|
+
|
|
197
|
+
// Clean up GraalVM isolate when done
|
|
198
|
+
ys.close();
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## API Reference
|
|
202
|
+
|
|
203
|
+
### `YAMLStar` Class
|
|
204
|
+
|
|
205
|
+
#### `new YAMLStar()`
|
|
206
|
+
Create a new YAMLStar instance. Each instance maintains its own GraalVM isolate.
|
|
207
|
+
|
|
208
|
+
```javascript
|
|
209
|
+
const ys = new YAMLStar();
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
#### `load(yamlInput)`
|
|
213
|
+
Load a single YAML document.
|
|
214
|
+
|
|
215
|
+
**Parameters:**
|
|
216
|
+
- `yamlInput` (string): String containing YAML content
|
|
217
|
+
|
|
218
|
+
**Returns:**
|
|
219
|
+
- JavaScript value representing the YAML document (object, array, string, number, boolean, or null)
|
|
220
|
+
|
|
221
|
+
**Throws:**
|
|
222
|
+
- `Error` if the YAML is malformed
|
|
223
|
+
|
|
224
|
+
**Example:**
|
|
225
|
+
```javascript
|
|
226
|
+
const data = ys.load('key: value');
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
#### `loadAll(yamlInput)`
|
|
230
|
+
Load all YAML documents from a multi-document string.
|
|
231
|
+
|
|
232
|
+
**Parameters:**
|
|
233
|
+
- `yamlInput` (string): String containing one or more YAML documents
|
|
234
|
+
|
|
235
|
+
**Returns:**
|
|
236
|
+
- Array of JavaScript values, one per YAML document
|
|
237
|
+
|
|
238
|
+
**Throws:**
|
|
239
|
+
- `Error` if the YAML is malformed
|
|
240
|
+
|
|
241
|
+
**Example:**
|
|
242
|
+
```javascript
|
|
243
|
+
const docs = ys.loadAll('---\ndoc1\n---\ndoc2');
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
#### `version()`
|
|
247
|
+
Get the YAMLStar version string.
|
|
248
|
+
|
|
249
|
+
**Returns:**
|
|
250
|
+
- string: Version string
|
|
251
|
+
|
|
252
|
+
**Example:**
|
|
253
|
+
```javascript
|
|
254
|
+
const version = ys.version();
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
#### `close()`
|
|
258
|
+
Tear down the GraalVM isolate and free resources. Should be called when done using the instance.
|
|
259
|
+
|
|
260
|
+
**Example:**
|
|
261
|
+
```javascript
|
|
262
|
+
ys.close();
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Development
|
|
266
|
+
|
|
267
|
+
### Running Tests
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
# Run all tests
|
|
271
|
+
make test
|
|
272
|
+
|
|
273
|
+
# Or directly with node
|
|
274
|
+
node test/test.js
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Building libyamlstar
|
|
278
|
+
|
|
279
|
+
If you need to rebuild the shared library:
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
cd ../libyamlstar
|
|
283
|
+
make clean
|
|
284
|
+
make native
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## Requirements
|
|
288
|
+
|
|
289
|
+
- **Node.js**: 18.0.0 or higher
|
|
290
|
+
- **libyamlstar**: Shared library (installed separately)
|
|
291
|
+
- **System**: Linux or macOS
|
|
292
|
+
- **Dependencies**: `@makeomatic/ffi-napi`, `ref-napi`
|
|
293
|
+
|
|
294
|
+
## Library Search Path
|
|
295
|
+
|
|
296
|
+
The module searches for `libyamlstar.so` (or `.dylib` on macOS) in:
|
|
297
|
+
|
|
298
|
+
1. Development path (relative to module: `../../libyamlstar/lib/`)
|
|
299
|
+
2. Directories in `LD_LIBRARY_PATH` environment variable
|
|
300
|
+
3. `/usr/local/lib` (default install location)
|
|
301
|
+
4. `~/.local/lib` (user-local install location)
|
|
302
|
+
|
|
303
|
+
## Comparison to js-yaml
|
|
304
|
+
|
|
305
|
+
| Feature | YAMLStar | js-yaml |
|
|
306
|
+
|---------|----------|---------|
|
|
307
|
+
| YAML Version | 1.2 | 1.2 |
|
|
308
|
+
| Implementation | Pure Clojure | JavaScript |
|
|
309
|
+
| Type Inference | YAML 1.2 core schema | YAML 1.2 + custom |
|
|
310
|
+
| Native Performance | Yes (GraalVM) | No |
|
|
311
|
+
| Dependencies | libyamlstar.so | None |
|
|
312
|
+
|
|
313
|
+
## License
|
|
314
|
+
|
|
315
|
+
MIT License - See [License](License) file
|
|
316
|
+
|
|
317
|
+
## Credits
|
|
318
|
+
|
|
319
|
+
Created by Ingy döt Net, inventor of YAML.
|
|
320
|
+
|
|
321
|
+
YAMLStar is built on the YAML Reference Parser (pure Clojure implementation).
|
|
322
|
+
|
|
323
|
+
## Links
|
|
324
|
+
|
|
325
|
+
- **GitHub**: https://github.com/yaml/yamlstar
|
|
326
|
+
- **YAML Specification**: https://yaml.org/spec/1.2/spec.html
|
package/lib/yamlstar/index.js
CHANGED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
const yamlstarVersion = '0.1.2';
|
|
2
|
+
|
|
3
|
+
const ffi = require('@makeomatic/ffi-napi');
|
|
4
|
+
const ref = require('ref-napi');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const os = require('os');
|
|
8
|
+
|
|
9
|
+
function defineForeignFunctionInterface() {
|
|
10
|
+
let libPath = findLibyamlstarPath();
|
|
11
|
+
|
|
12
|
+
return ffi.Library(libPath, {
|
|
13
|
+
'graal_create_isolate': ['int', ['pointer', 'pointer', 'pointer']],
|
|
14
|
+
'graal_tear_down_isolate': ['int', ['pointer']],
|
|
15
|
+
'yamlstar_load': ['string', ['pointer', 'string']],
|
|
16
|
+
'yamlstar_load_all': ['string', ['pointer', 'string']],
|
|
17
|
+
'yamlstar_version': ['string', ['pointer']],
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
class YAMLStar {
|
|
22
|
+
constructor(config = {}) {
|
|
23
|
+
this.libyamlstar = defineForeignFunctionInterface();
|
|
24
|
+
this.isolatethread = ref.NULL_POINTER;
|
|
25
|
+
|
|
26
|
+
let rc = this.libyamlstar.graal_create_isolate(
|
|
27
|
+
null,
|
|
28
|
+
null,
|
|
29
|
+
this.isolatethread,
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
if (rc !== 0) {
|
|
33
|
+
throw new Error('Failed to create GraalVM isolate');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
load(input) {
|
|
38
|
+
let dataJson = this.libyamlstar.yamlstar_load(
|
|
39
|
+
this.isolatethread.deref(),
|
|
40
|
+
input,
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
let resp = JSON.parse(dataJson);
|
|
44
|
+
|
|
45
|
+
if (resp.error) {
|
|
46
|
+
throw new Error(`libyamlstar: ${resp.error.cause}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!('data' in resp)) {
|
|
50
|
+
throw new Error("Unexpected response from 'libyamlstar'");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return resp.data;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
loadAll(input) {
|
|
57
|
+
let dataJson = this.libyamlstar.yamlstar_load_all(
|
|
58
|
+
this.isolatethread.deref(),
|
|
59
|
+
input,
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
let resp = JSON.parse(dataJson);
|
|
63
|
+
|
|
64
|
+
if (resp.error) {
|
|
65
|
+
throw new Error(`libyamlstar: ${resp.error.cause}`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (!('data' in resp)) {
|
|
69
|
+
throw new Error("Unexpected response from 'libyamlstar'");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return resp.data;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
version() {
|
|
76
|
+
return this.libyamlstar.yamlstar_version(this.isolatethread.deref());
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
close() {
|
|
80
|
+
let ret = this.libyamlstar.graal_tear_down_isolate(
|
|
81
|
+
this.isolatethread.deref(),
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
if (ret !== 0) {
|
|
85
|
+
throw new Error("Failed to tear down isolate.");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Helper function to find the libyamlstar shared library path
|
|
91
|
+
function findLibyamlstarPath() {
|
|
92
|
+
let platform = os.platform();
|
|
93
|
+
let soExtension = platform === 'win32' ? 'dll' : (platform === 'linux' ? 'so' : 'dylib');
|
|
94
|
+
let libyamlstarName = `libyamlstar.${soExtension}.${yamlstarVersion}`;
|
|
95
|
+
|
|
96
|
+
let searchPaths = [];
|
|
97
|
+
|
|
98
|
+
// Add relative path for development (from nodejs/lib/yamlstar to libyamlstar/lib)
|
|
99
|
+
let devPath = path.join(__dirname, '..', '..', '..', 'libyamlstar', 'lib');
|
|
100
|
+
if (fs.existsSync(devPath)) {
|
|
101
|
+
searchPaths.push(devPath);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Add LD_LIBRARY_PATH
|
|
105
|
+
if (process.env.LD_LIBRARY_PATH) {
|
|
106
|
+
searchPaths.push(...process.env.LD_LIBRARY_PATH.split(':'));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Add system paths
|
|
110
|
+
searchPaths.push('/usr/local/lib', path.join(os.homedir(), '.local', 'lib'));
|
|
111
|
+
|
|
112
|
+
for (let p of searchPaths) {
|
|
113
|
+
let fullPath = path.join(p, libyamlstarName);
|
|
114
|
+
if (fs.existsSync(fullPath)) {
|
|
115
|
+
return fullPath;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
throw new Error(
|
|
120
|
+
`Shared library file '${libyamlstarName}' not found
|
|
121
|
+
Search paths: ${searchPaths.join(':')}
|
|
122
|
+
Build with: cd libyamlstar && make native`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
module.exports = YAMLStar;
|
package/package.json
CHANGED
|
@@ -1,20 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yamlstar",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
5
|
-
"main": "index.js",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "YAML 1.2 loader - Node.js bindings",
|
|
5
|
+
"main": "lib/yamlstar/index.js",
|
|
6
|
+
"author": "Ingy döt Net",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"dependencies": {
|
|
9
|
+
"@makeomatic/ffi-napi": "^4.2.0",
|
|
10
|
+
"ref-napi": "^3.0.3"
|
|
11
|
+
},
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">=18.0.0"
|
|
14
|
+
},
|
|
6
15
|
"directories": {
|
|
7
|
-
"
|
|
16
|
+
"test": "test"
|
|
8
17
|
},
|
|
9
18
|
"scripts": {
|
|
10
|
-
"test": "
|
|
19
|
+
"test": "make test"
|
|
11
20
|
},
|
|
12
21
|
"repository": {
|
|
13
22
|
"type": "git",
|
|
14
23
|
"url": "git+https://github.com/yaml/yamlstar.git"
|
|
15
24
|
},
|
|
16
|
-
"author": "Ingy döt Net",
|
|
17
|
-
"license": "MIT",
|
|
18
25
|
"bugs": {
|
|
19
26
|
"url": "https://github.com/yaml/yamlstar/issues"
|
|
20
27
|
},
|
package/test/test.js
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
const YAMLStar = require('../lib/yamlstar');
|
|
2
|
+
const assert = require('assert');
|
|
3
|
+
|
|
4
|
+
// Helper function for deep equality check
|
|
5
|
+
function deepEqual(actual, expected, message) {
|
|
6
|
+
try {
|
|
7
|
+
assert.deepStrictEqual(actual, expected);
|
|
8
|
+
console.log(`✓ ${message}`);
|
|
9
|
+
} catch (e) {
|
|
10
|
+
console.error(`✗ ${message}`);
|
|
11
|
+
console.error(` Expected: ${JSON.stringify(expected)}`);
|
|
12
|
+
console.error(` Actual: ${JSON.stringify(actual)}`);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Create a YAMLStar instance
|
|
18
|
+
const ys = new YAMLStar();
|
|
19
|
+
|
|
20
|
+
console.log('Running YAMLStar tests...\n');
|
|
21
|
+
|
|
22
|
+
// Test simple scalar
|
|
23
|
+
deepEqual(ys.load('hello'), 'hello', 'Load simple scalar');
|
|
24
|
+
|
|
25
|
+
// Test integer
|
|
26
|
+
deepEqual(ys.load('42'), 42, 'Load integer');
|
|
27
|
+
|
|
28
|
+
// Test float
|
|
29
|
+
deepEqual(ys.load('3.14'), 3.14, 'Load float');
|
|
30
|
+
|
|
31
|
+
// Test boolean true
|
|
32
|
+
deepEqual(ys.load('true'), true, 'Load boolean true');
|
|
33
|
+
|
|
34
|
+
// Test boolean false
|
|
35
|
+
deepEqual(ys.load('false'), false, 'Load boolean false');
|
|
36
|
+
|
|
37
|
+
// Test null
|
|
38
|
+
deepEqual(ys.load('null'), null, 'Load null');
|
|
39
|
+
|
|
40
|
+
// Test simple mapping
|
|
41
|
+
deepEqual(ys.load('key: value'), {key: 'value'}, 'Load simple mapping');
|
|
42
|
+
|
|
43
|
+
// Test nested mapping
|
|
44
|
+
deepEqual(
|
|
45
|
+
ys.load('outer:\n inner: value'),
|
|
46
|
+
{outer: {inner: 'value'}},
|
|
47
|
+
'Load nested mapping'
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// Test mapping with multiple keys
|
|
51
|
+
deepEqual(
|
|
52
|
+
ys.load('key1: value1\nkey2: value2\nkey3: value3'),
|
|
53
|
+
{key1: 'value1', key2: 'value2', key3: 'value3'},
|
|
54
|
+
'Load mapping with multiple keys'
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
// Test simple sequence
|
|
58
|
+
deepEqual(
|
|
59
|
+
ys.load('- item1\n- item2\n- item3'),
|
|
60
|
+
['item1', 'item2', 'item3'],
|
|
61
|
+
'Load simple sequence'
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
// Test flow sequence
|
|
65
|
+
deepEqual(ys.load('[a, b, c]'), ['a', 'b', 'c'], 'Load flow sequence');
|
|
66
|
+
|
|
67
|
+
// Test type coercion
|
|
68
|
+
deepEqual(
|
|
69
|
+
ys.load('string: hello\ninteger: 42\nfloat: 3.14\nbool_true: true\nbool_false: false\nnull_value: null'),
|
|
70
|
+
{
|
|
71
|
+
string: 'hello',
|
|
72
|
+
integer: 42,
|
|
73
|
+
float: 3.14,
|
|
74
|
+
bool_true: true,
|
|
75
|
+
bool_false: false,
|
|
76
|
+
null_value: null
|
|
77
|
+
},
|
|
78
|
+
'Load with type coercion'
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
// Test sequence of mappings
|
|
82
|
+
deepEqual(
|
|
83
|
+
ys.load('- name: Alice\n age: 30\n- name: Bob\n age: 25'),
|
|
84
|
+
[
|
|
85
|
+
{name: 'Alice', age: 30},
|
|
86
|
+
{name: 'Bob', age: 25}
|
|
87
|
+
],
|
|
88
|
+
'Load sequence of mappings'
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
// Test mapping with sequence values
|
|
92
|
+
deepEqual(
|
|
93
|
+
ys.load('fruits:\n - apple\n - banana\ncolors:\n - red\n - blue'),
|
|
94
|
+
{
|
|
95
|
+
fruits: ['apple', 'banana'],
|
|
96
|
+
colors: ['red', 'blue']
|
|
97
|
+
},
|
|
98
|
+
'Load mapping with sequence values'
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
// Test loadAll with single document
|
|
102
|
+
deepEqual(ys.loadAll('hello'), ['hello'], 'LoadAll with single document');
|
|
103
|
+
|
|
104
|
+
// Test loadAll with multiple documents
|
|
105
|
+
deepEqual(
|
|
106
|
+
ys.loadAll('---\ndoc1\n---\ndoc2\n---\ndoc3'),
|
|
107
|
+
['doc1', 'doc2', 'doc3'],
|
|
108
|
+
'LoadAll with multiple documents'
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
// Test loadAll with explicit markers
|
|
112
|
+
deepEqual(
|
|
113
|
+
ys.loadAll('---\na: 1\n...\n---\nb: 2\n...'),
|
|
114
|
+
[{a: 1}, {b: 2}],
|
|
115
|
+
'LoadAll with explicit markers'
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
// Test version
|
|
119
|
+
const version = ys.version();
|
|
120
|
+
assert(typeof version === 'string' && version.length > 0, 'Version returns a string');
|
|
121
|
+
console.log(`✓ Version returns a string: ${version}`);
|
|
122
|
+
|
|
123
|
+
// Test error handling with malformed YAML
|
|
124
|
+
try {
|
|
125
|
+
ys.load('key: "unclosed');
|
|
126
|
+
console.error('✗ Should have thrown error on malformed YAML');
|
|
127
|
+
process.exit(1);
|
|
128
|
+
} catch (e) {
|
|
129
|
+
assert(e.message.includes('libyamlstar'), 'Error message includes libyamlstar');
|
|
130
|
+
console.log('✓ Dies with libyamlstar error on malformed YAML');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Test empty document
|
|
134
|
+
deepEqual(ys.load(''), null, 'Load empty document');
|
|
135
|
+
|
|
136
|
+
// Test whitespace only
|
|
137
|
+
deepEqual(ys.load(' \n \n '), null, 'Load whitespace only');
|
|
138
|
+
|
|
139
|
+
// Test quoted strings
|
|
140
|
+
deepEqual(ys.load("'hello world'"), 'hello world', 'Load single-quoted string');
|
|
141
|
+
deepEqual(ys.load('"hello world"'), 'hello world', 'Load double-quoted string');
|
|
142
|
+
|
|
143
|
+
// Clean up
|
|
144
|
+
ys.close();
|
|
145
|
+
|
|
146
|
+
console.log('\n✓ All tests passed!');
|
package/Changes
DELETED