···11+Location and Layout Preservation Tests with Yamlt
22+==================================================
33+44+This test suite validates the `locs` and `layout` options in the Yamlt decoder,
55+demonstrating how they affect error messages and metadata preservation.
66+77+================================================================================
88+ERROR MESSAGE PRECISION - locs option
99+================================================================================
1010+1111+The `locs` option controls whether source locations are preserved in error messages.
1212+When `locs=false` (default), errors show basic location info.
1313+When `locs=true`, errors show precise character positions.
1414+1515+Basic type error with and without locs
1616+1717+ $ test_locations error-precision ../data/locations/type_error.yml
1818+ === Without locs (default) ===
1919+ Error message:
2020+ String "not-a-number" does not parse to OCaml int value
2121+ File "-":
2222+ File "-": in member age of
2323+ File "-": Person object
2424+2525+ === With locs=true ===
2626+ Error message:
2727+ String "not-a-number" does not parse to OCaml int value
2828+ File "-", lines 2-3, characters 5-0:
2929+ File "-", line 2, characters 0-3: in member age of
3030+ File "-", line 1, characters 0-1: Person object
3131+3232+================================================================================
3333+NESTED ERROR LOCATIONS
3434+================================================================================
3535+3636+The `locs` option is especially useful for nested structures,
3737+showing exactly where deep errors occur.
3838+3939+Error in nested object field
4040+4141+ $ test_locations nested-error ../data/locations/nested_error.yml
4242+ === Without locs (default) ===
4343+ Nested error:
4444+ String "invalid-zip" does not parse to OCaml int value
4545+ File "-":
4646+ File "-": in member zip of
4747+ File "-": Address object
4848+ File "-": in member address of
4949+ File "-": Employee object
5050+5151+ === With locs=true ===
5252+ Nested error:
5353+ String "invalid-zip" does not parse to OCaml int value
5454+ File "-", lines 5-6, characters 7-0:
5555+ File "-", line 5, characters 2-5: in member zip of
5656+ File "-", line 3, characters 2-3: Address object
5757+ File "-", line 2, characters 0-7: in member address of
5858+ File "-", line 1, characters 0-1: Employee object
5959+6060+================================================================================
6161+ARRAY ELEMENT ERROR LOCATIONS
6262+================================================================================
6363+6464+The `locs` option pinpoints which array element caused an error.
6565+6666+Error at specific array index
6767+6868+ $ test_locations array-error ../data/locations/array_error.yml
6969+ === Without locs (default) ===
7070+ Array error:
7171+ String "not-a-number" does not parse to OCaml int value
7272+ File "-":
7373+ at index 2 of
7474+ File "-": array<OCaml int>
7575+ File "-": in member values of
7676+ File "-": Numbers object
7777+7878+ === With locs=true ===
7979+ Array error:
8080+ String "not-a-number" does not parse to OCaml int value
8181+ File "-", lines 4-5, characters 4-2:
8282+ at index 2 of
8383+ File "-", line 2, characters 2-3: array<OCaml int>
8484+ File "-", line 1, characters 0-6: in member values of
8585+ File "-", line 1, characters 0-1: Numbers object
8686+8787+================================================================================
8888+FILE PATH IN ERROR MESSAGES
8989+================================================================================
9090+9191+The `file` parameter sets the file path shown in error messages.
9292+9393+ $ test_locations file-path
9494+ === Without file path ===
9595+ Error:
9696+ String "not-a-number" does not parse to OCaml int value
9797+ File "-", lines 2-3, characters 5-0:
9898+ File "-", line 2, characters 0-3: in member age of
9999+ File "-", line 1, characters 0-1: Person object
100100+101101+ === With file path ===
102102+ Error:
103103+ String "not-a-number" does not parse to OCaml int value
104104+ File "test.yml", lines 2-3, characters 5-0:
105105+ File "test.yml", line 2, characters 0-3: in member age of
106106+ File "test.yml", line 1, characters 0-1: Person object
107107+108108+================================================================================
109109+MISSING FIELD ERROR LOCATIONS
110110+================================================================================
111111+112112+The `locs` option helps identify where fields are missing.
113113+114114+ $ test_locations missing-field ../data/locations/missing_field.yml
115115+ === Without locs ===
116116+ Missing field:
117117+ Missing member field_c in Complete object
118118+ File "-":
119119+120120+ === With locs=true ===
121121+ Missing field:
122122+ Missing member field_c in Complete object
123123+ File "-", line 1, characters 0-1:
124124+125125+================================================================================
126126+LAYOUT PRESERVATION - layout option
127127+================================================================================
128128+129129+The `layout` option controls whether style information (block vs flow)
130130+is preserved in metadata for potential round-tripping.
131131+132132+Basic layout preservation
133133+134134+ $ test_locations layout ../data/locations/simple.yml
135135+ === Without layout (default) ===
136136+ Decoded: host=localhost, port=8080
137137+ Meta preserved: no
138138+139139+ === With layout=true ===
140140+ Decoded: host=localhost, port=8080
141141+ Meta preserved: yes (style info available for round-tripping)
142142+143143+================================================================================
144144+ROUND-TRIPPING WITH LAYOUT
145145+================================================================================
146146+147147+With `layout=true` during decode and `format:Layout` during encode,
148148+the original YAML style can be preserved.
149149+150150+Flow style preservation
151151+152152+ $ test_locations roundtrip ../data/locations/flow_style.yml
153153+ === Original YAML ===
154154+ items: [apple, banana, cherry]
155155+156156+ === Decode without layout, re-encode ===
157157+ items:
158158+ - apple
159159+ - banana
160160+ - cherry
161161+162162+ === Decode with layout=true, re-encode with Layout format ===
163163+ items:
164164+ - apple
165165+ - banana
166166+ - cherry
167167+168168+Block style preservation
169169+170170+ $ test_locations roundtrip ../data/locations/block_style.yml
171171+ === Original YAML ===
172172+ items:
173173+ - apple
174174+ - banana
175175+ - cherry
176176+177177+ === Decode without layout, re-encode ===
178178+ items:
179179+ - apple
180180+ - banana
181181+ - cherry
182182+183183+ === Decode with layout=true, re-encode with Layout format ===
184184+ items:
185185+ - apple
186186+ - banana
187187+ - cherry
188188+189189+================================================================================
190190+COMBINED OPTIONS - locs and layout together
191191+================================================================================
192192+193193+Both options can be used simultaneously for maximum information.
194194+195195+ $ test_locations combined ../data/locations/valid_settings.yml
196196+ === locs=false, layout=false (defaults) ===
197197+ OK: timeout=30, retries=3
198198+199199+ === locs=true, layout=false ===
200200+ OK: timeout=30, retries=3 (with precise locations)
201201+202202+ === locs=false, layout=true ===
203203+ OK: timeout=30, retries=3 (with layout metadata)
204204+205205+ === locs=true, layout=true (both enabled) ===
206206+ OK: timeout=30, retries=3 (with locations and layout)
207207+208208+================================================================================
209209+SUMMARY OF OPTIONS
210210+================================================================================
211211+212212+locs option:
213213+214214+layout option:
215215+216216+Both options add metadata overhead, so only enable when needed.
217217+For production parsing where you only need the data, use defaults (both false).