Skip to content

Commit da93f35

Browse files
Add tests for handling various YAML data types and structures in ConvertFrom-Yaml and ConvertTo-Yaml
1 parent 7ce8fd0 commit da93f35

2 files changed

Lines changed: 444 additions & 10 deletions

File tree

tests/ConvertFrom-Yaml.Tests.ps1

Lines changed: 210 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,74 @@ f: OFF
9191
$result = 'value: "line1\nline2\ttab"' | ConvertFrom-Yaml
9292
$result.value | Should -Be "line1`nline2`ttab"
9393
}
94+
95+
It 'Handles all supported double-quoted escapes (\r, \\, \", \0)' {
96+
$result = 'cr: "a\rb"' | ConvertFrom-Yaml
97+
$result.cr | Should -Be "a`rb"
98+
99+
$result = 'bs: "a\\b"' | ConvertFrom-Yaml
100+
$result.bs | Should -Be 'a\b'
101+
102+
$result = 'dq: "she said \"hi\""' | ConvertFrom-Yaml
103+
$result.dq | Should -Be 'she said "hi"'
104+
105+
$result = 'nul: "a\0b"' | ConvertFrom-Yaml
106+
$result.nul | Should -Be "a$([char]0)b"
107+
}
108+
109+
It 'Preserves single-quoted escape (double apostrophe)' {
110+
$result = "value: 'it''s a test'" | ConvertFrom-Yaml
111+
$result.value | Should -Be "it's a test"
112+
}
113+
114+
It 'Parses a negative integer' {
115+
$result = 'value: -7' | ConvertFrom-Yaml
116+
$result.value | Should -Be -7
117+
$result.value | Should -BeOfType [int]
118+
}
119+
120+
It 'Parses a large integer as [long]' {
121+
$result = 'value: 3000000000' | ConvertFrom-Yaml
122+
$result.value | Should -Be 3000000000
123+
$result.value | Should -BeOfType [long]
124+
}
125+
126+
It 'Parses a negative floating-point value' {
127+
$result = 'value: -3.14' | ConvertFrom-Yaml
128+
$result.value | Should -Be -3.14
129+
$result.value | Should -BeOfType [double]
130+
}
131+
132+
It 'Parses scientific notation as a double' {
133+
$result = 'value: 6.022e23' | ConvertFrom-Yaml
134+
$result.value | Should -Be 6.022e23
135+
$result.value | Should -BeOfType [double]
136+
}
137+
138+
It 'Parses zero as an integer' {
139+
$result = 'value: 0' | ConvertFrom-Yaml
140+
$result.value | Should -Be 0
141+
$result.value | Should -BeOfType [int]
142+
}
143+
144+
It 'Parses leading-zero integer as a number (YAML 1.2.2 core schema)' {
145+
$result = 'value: 01' | ConvertFrom-Yaml
146+
$result.value | Should -Be 1
147+
$result.value | Should -BeOfType [int]
148+
}
149+
150+
It 'Parses leading-plus integer as a number (YAML 1.2.2 core schema)' {
151+
$result = 'value: +42' | ConvertFrom-Yaml
152+
$result.value | Should -Be 42
153+
$result.value | Should -BeOfType [int]
154+
}
155+
156+
It 'Returns empty/whitespace-only input as null' {
157+
$result = '' | ConvertFrom-Yaml
158+
$result | Should -BeNullOrEmpty
159+
$result = ' ' | ConvertFrom-Yaml
160+
$result | Should -BeNullOrEmpty
161+
}
94162
}
95163

96164
Context 'Mappings' {
@@ -171,6 +239,44 @@ GetType: world
171239
$result.PSObject.Properties['ToString'].Value | Should -Be 'hello'
172240
$result.PSObject.Properties['GetType'].Value | Should -Be 'world'
173241
}
242+
243+
It 'Parses a mapping with null values' {
244+
$yaml = @'
245+
present: value
246+
empty:
247+
tilde: ~
248+
explicit: null
249+
'@
250+
$result = $yaml | ConvertFrom-Yaml
251+
$result.present | Should -Be 'value'
252+
$result.empty | Should -BeNullOrEmpty
253+
$result.tilde | Should -BeNullOrEmpty
254+
$result.explicit | Should -BeNullOrEmpty
255+
}
256+
257+
It 'Parses a mapping with mixed value types' {
258+
$yaml = @'
259+
str: hello
260+
int: 10
261+
float: 2.5
262+
bool: true
263+
nothing: null
264+
list:
265+
- a
266+
- b
267+
child:
268+
key: val
269+
'@
270+
$result = $yaml | ConvertFrom-Yaml
271+
$result.str | Should -Be 'hello'
272+
$result.str | Should -BeOfType [string]
273+
$result.int | Should -Be 10
274+
$result.float | Should -Be 2.5
275+
$result.bool | Should -BeTrue
276+
$result.nothing | Should -BeNullOrEmpty
277+
$result.list.Count | Should -Be 2
278+
$result.child.key | Should -Be 'val'
279+
}
174280
}
175281

176282
Context 'Sequences' {
@@ -211,6 +317,55 @@ people:
211317
$result.people[0].name | Should -Be 'Alice'
212318
$result.people[1].age | Should -Be 25
213319
}
320+
321+
It 'Parses nested sequences (sequence of sequences)' {
322+
$yaml = @'
323+
matrix:
324+
-
325+
- 1
326+
- 2
327+
-
328+
- 3
329+
- 4
330+
'@
331+
$result = $yaml | ConvertFrom-Yaml
332+
$result.matrix.Count | Should -Be 2
333+
$result.matrix[0].Count | Should -Be 2
334+
$result.matrix[0][0] | Should -Be 1
335+
$result.matrix[1][1] | Should -Be 4
336+
}
337+
338+
It 'Parses a sequence with null items' {
339+
$yaml = @'
340+
- alpha
341+
-
342+
- bravo
343+
'@
344+
$result = $yaml | ConvertFrom-Yaml -NoEnumerate
345+
$result.Count | Should -Be 3
346+
$result[0] | Should -Be 'alpha'
347+
$result[1] | Should -BeNullOrEmpty
348+
$result[2] | Should -Be 'bravo'
349+
}
350+
351+
It 'Parses a sequence with mixed scalar types' {
352+
$yaml = @'
353+
- hello
354+
- 42
355+
- true
356+
- 3.14
357+
- null
358+
'@
359+
$result = $yaml | ConvertFrom-Yaml -NoEnumerate
360+
$result[0] | Should -Be 'hello'
361+
$result[0] | Should -BeOfType [string]
362+
$result[1] | Should -Be 42
363+
$result[1] | Should -BeOfType [int]
364+
$result[2] | Should -BeTrue
365+
$result[3] | Should -Be 3.14
366+
$result[3] | Should -BeOfType [double]
367+
$result[4] | Should -BeNullOrEmpty
368+
}
214369
}
215370

216371
Context '-AsHashtable' {
@@ -246,6 +401,35 @@ outer:
246401
, $result | Should -BeOfType [System.Object[]]
247402
$result.Count | Should -Be 1
248403
}
404+
405+
It 'Without -NoEnumerate, unwraps a single-element top-level sequence' {
406+
$yaml = '- only'
407+
$result = $yaml | ConvertFrom-Yaml
408+
$result | Should -Be 'only'
409+
$result | Should -BeOfType [string]
410+
}
411+
}
412+
413+
Context 'Pipeline input' {
414+
It 'Accepts multi-line pipeline strings (simulating Get-Content)' {
415+
$lines = @('name: Alice', 'age: 30')
416+
$result = $lines | ConvertFrom-Yaml
417+
$result.name | Should -Be 'Alice'
418+
$result.age | Should -Be 30
419+
}
420+
}
421+
422+
Context 'Deeply nested structures' {
423+
It 'Parses 4 levels of nesting' {
424+
$yaml = @'
425+
a:
426+
b:
427+
c:
428+
d: deep
429+
'@
430+
$result = $yaml | ConvertFrom-Yaml
431+
$result.a.b.c.d | Should -Be 'deep'
432+
}
249433
}
250434

251435
Context 'Document markers' {
@@ -264,6 +448,16 @@ age: 30
264448
$yaml = @'
265449
name: Alice
266450
...
451+
'@
452+
$result = $yaml | ConvertFrom-Yaml
453+
$result.name | Should -Be 'Alice'
454+
}
455+
456+
It 'Tolerates both --- and ... markers together' {
457+
$yaml = @'
458+
---
459+
name: Alice
460+
...
267461
'@
268462
$result = $yaml | ConvertFrom-Yaml
269463
$result.name | Should -Be 'Alice'
@@ -288,13 +482,23 @@ age: 30
288482
$result.name | Should -Be 'Alice'
289483
}
290484

291-
It 'Ignores blank lines' {
292-
$yaml = @'
293-
name: Alice
485+
It 'Preserves # inside double-quoted strings' {
486+
$result = 'value: "has # inside"' | ConvertFrom-Yaml
487+
$result.value | Should -Be 'has # inside'
488+
}
294489

295-
age: 30
490+
It 'Preserves # inside single-quoted strings' {
491+
$result = "value: 'has # inside'" | ConvertFrom-Yaml
492+
$result.value | Should -Be 'has # inside'
493+
}
296494

297-
'@
495+
It 'Does not treat # without leading space as an inline comment' {
496+
$result = 'channel: news#general' | ConvertFrom-Yaml
497+
$result.channel | Should -Be 'news#general'
498+
}
499+
500+
It 'Ignores blank lines' {
501+
$yaml = "name: Alice`n`nage: 30`n"
298502
$result = $yaml | ConvertFrom-Yaml
299503
$result.name | Should -Be 'Alice'
300504
$result.age | Should -Be 30
@@ -352,11 +556,7 @@ a:
352556
}
353557

354558
It 'Parses sequence items {} and [] correctly' {
355-
$yaml = @'
356-
- {}
357-
- []
358-
- hello
359-
'@
559+
$yaml = "- {}`n- []`n- hello"
360560
$result = $yaml | ConvertFrom-Yaml -NoEnumerate -AsHashtable
361561
$result[0] | Should -BeOfType [System.Collections.Specialized.OrderedDictionary]
362562
$result[0].Count | Should -Be 0

0 commit comments

Comments
 (0)