@curly-message/conformance 1.0.0-next.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.
@@ -0,0 +1,916 @@
1
+ {
2
+ "format": "curly-message-1",
3
+ "level": "core",
4
+ "section": "11.1",
5
+ "cases": [
6
+ {
7
+ "id": "comparisons/eq-selects-equal-key",
8
+ "description": "eq selects the first option whose key equals the value.",
9
+ "section": "11.1",
10
+ "message": "{{v:eq; a:A; b:B; default:D}}",
11
+ "payload": {
12
+ "v": "b"
13
+ },
14
+ "expected": {
15
+ "output": "B"
16
+ }
17
+ },
18
+ {
19
+ "id": "comparisons/eq-when-no-modifier-named",
20
+ "description": "A placeholder with options and no modifier selects as eq.",
21
+ "section": "9.5",
22
+ "message": "{{v; a:A; b:B; default:D}}",
23
+ "payload": {
24
+ "v": "b"
25
+ },
26
+ "expected": {
27
+ "output": "B"
28
+ }
29
+ },
30
+ {
31
+ "id": "comparisons/eq-compares-as-text",
32
+ "description": "eq compares as text, so a key spelled differently from the value does not select however the two compare as numbers.",
33
+ "section": "11.1",
34
+ "message": "{{v:eq; 1.0:X; default:D}}",
35
+ "payload": {
36
+ "v": "1"
37
+ },
38
+ "expected": {
39
+ "output": "D"
40
+ }
41
+ },
42
+ {
43
+ "id": "comparisons/count-and-noun-one",
44
+ "description": "The count and the noun are two placeholders, and the noun selects on the value as text: 1 file.",
45
+ "section": "11.1",
46
+ "message": "{{n}} {{n; 1:file; default:files;}}",
47
+ "payload": {
48
+ "n": 1
49
+ },
50
+ "expected": {
51
+ "output": "1 file"
52
+ }
53
+ },
54
+ {
55
+ "id": "comparisons/count-and-noun-five",
56
+ "description": "The count and the noun are two placeholders, and the noun selects on the value as text: 5 files.",
57
+ "section": "11.1",
58
+ "message": "{{n}} {{n; 1:file; default:files;}}",
59
+ "payload": {
60
+ "n": 5
61
+ },
62
+ "expected": {
63
+ "output": "5 files"
64
+ }
65
+ },
66
+ {
67
+ "id": "comparisons/grouped-key-does-not-equal",
68
+ "description": "An option key is compared against the value's own text, so a grouped key does not equal the ungrouped value.",
69
+ "section": "11.1",
70
+ "message": "{{n; 1,000:K; default:files;}}",
71
+ "payload": {
72
+ "n": 1000
73
+ },
74
+ "expected": {
75
+ "output": "files"
76
+ }
77
+ },
78
+ {
79
+ "id": "comparisons/eq-case-insensitive-key",
80
+ "description": "eq compares case-insensitively: an upper-case key selects for a lower-case value.",
81
+ "section": "11.1",
82
+ "message": "{{v:eq; YES:A; default:D}}",
83
+ "payload": {
84
+ "v": "yes"
85
+ },
86
+ "expected": {
87
+ "output": "A"
88
+ }
89
+ },
90
+ {
91
+ "id": "comparisons/eq-case-insensitive-mixed",
92
+ "description": "eq compares case-insensitively whatever the mix of cases on either side.",
93
+ "section": "11.1",
94
+ "message": "{{v:eq; yEs:A; default:D}}",
95
+ "payload": {
96
+ "v": "YeS"
97
+ },
98
+ "expected": {
99
+ "output": "A"
100
+ }
101
+ },
102
+ {
103
+ "id": "comparisons/eq-no-case-fold",
104
+ "description": "The mapping is a lower-casing and not a case fold, so a key STRASSE does not select for the value stra\u00dfe.",
105
+ "section": "11.1",
106
+ "message": "{{v:eq; STRASSE:X; default:D}}",
107
+ "payload": {
108
+ "v": "stra\u00dfe"
109
+ },
110
+ "expected": {
111
+ "output": "D"
112
+ }
113
+ },
114
+ {
115
+ "id": "comparisons/ne-no-case-fold",
116
+ "description": "Under ne the key STRASSE differs from the value stra\u00dfe, because a lower-casing leaves the two apart.",
117
+ "section": "11.1",
118
+ "message": "{{v:ne; STRASSE:X; default:D}}",
119
+ "payload": {
120
+ "v": "stra\u00dfe"
121
+ },
122
+ "expected": {
123
+ "output": "X"
124
+ }
125
+ },
126
+ {
127
+ "id": "comparisons/eq-no-normalization",
128
+ "description": "The comparison is by code-point equality, so a precomposed key does not select for a decomposed value.",
129
+ "section": "11.1",
130
+ "message": "{{v:eq; \u00e9:X; default:D}}",
131
+ "payload": {
132
+ "v": "e\u0301"
133
+ },
134
+ "expected": {
135
+ "output": "D"
136
+ }
137
+ },
138
+ {
139
+ "id": "comparisons/eq-no-collation",
140
+ "description": "The comparison is not a collation, so an unaccented key does not select for an accented value.",
141
+ "section": "11.1",
142
+ "message": "{{v:eq; e:X; default:D}}",
143
+ "payload": {
144
+ "v": "\u00e9"
145
+ },
146
+ "expected": {
147
+ "output": "D"
148
+ }
149
+ },
150
+ {
151
+ "id": "comparisons/eq-not-tailored-to-locale",
152
+ "description": "The case mapping is locale-independent, so a key I selects for the value i under a Turkish locale.",
153
+ "section": "11.1",
154
+ "message": "{{v:eq; I:X; default:D}}",
155
+ "payload": {
156
+ "v": "i"
157
+ },
158
+ "locale": "tr",
159
+ "expected": {
160
+ "output": "X"
161
+ }
162
+ },
163
+ {
164
+ "id": "comparisons/eq-dotless-i-not-tailored",
165
+ "description": "The case mapping is locale-independent, so a key I does not select for a dotless i under a Turkish locale.",
166
+ "section": "11.1",
167
+ "message": "{{v:eq; I:X; default:D}}",
168
+ "payload": {
169
+ "v": "\u0131"
170
+ },
171
+ "locale": "tr",
172
+ "expected": {
173
+ "output": "D"
174
+ }
175
+ },
176
+ {
177
+ "id": "comparisons/eq-without-locale",
178
+ "description": "A comparison resolves alike where no locale is available at all.",
179
+ "section": "11.1",
180
+ "message": "{{v:eq; I:X; default:D}}",
181
+ "payload": {
182
+ "v": "i"
183
+ },
184
+ "expected": {
185
+ "output": "X"
186
+ }
187
+ },
188
+ {
189
+ "id": "comparisons/ne-not-tailored-to-locale",
190
+ "description": "Under ne the key I equals the value i under a Turkish locale, so nothing differs and the placeholder takes the chain.",
191
+ "section": "11.1",
192
+ "message": "{{v:ne; I:X; default:D}}",
193
+ "payload": {
194
+ "v": "i"
195
+ },
196
+ "locale": "tr",
197
+ "expected": {
198
+ "output": "D"
199
+ }
200
+ },
201
+ {
202
+ "id": "comparisons/ne-selects-first-differing-key",
203
+ "description": "ne selects the first option whose key differs from the value.",
204
+ "section": "11.1",
205
+ "message": "{{v:ne; a:A; b:B; default:D}}",
206
+ "payload": {
207
+ "v": "a"
208
+ },
209
+ "expected": {
210
+ "output": "B"
211
+ }
212
+ },
213
+ {
214
+ "id": "comparisons/ne-no-differing-key-takes-chain",
215
+ "description": "Where every key equals the value, ne selects nothing and the placeholder takes the chain.",
216
+ "section": "11.1",
217
+ "message": "{{v:ne; 10:V2; default:D}}",
218
+ "payload": {
219
+ "v": 10
220
+ },
221
+ "expected": {
222
+ "output": "D"
223
+ }
224
+ },
225
+ {
226
+ "id": "comparisons/ne-case-insensitive",
227
+ "description": "ne compares case-insensitively, so a key differing from the value only by case does not differ.",
228
+ "section": "11.1",
229
+ "message": "{{v:ne; YES:A; NO:B; default:D}}",
230
+ "payload": {
231
+ "v": "yes"
232
+ },
233
+ "expected": {
234
+ "output": "B"
235
+ }
236
+ },
237
+ {
238
+ "id": "comparisons/ne-differs-as-text",
239
+ "description": "ne compares as text, so a key numerically equal to the value but spelled differently differs.",
240
+ "section": "11.1",
241
+ "message": "{{v:ne; 1.0:X; default:D}}",
242
+ "payload": {
243
+ "v": "1"
244
+ },
245
+ "expected": {
246
+ "output": "X"
247
+ }
248
+ },
249
+ {
250
+ "id": "comparisons/ne-absent-takes-chain",
251
+ "description": "An absent value takes the fallback chain under ne like every other modifier.",
252
+ "section": "11.1",
253
+ "message": "{{v:ne; 10:V2; default:D}}",
254
+ "payload": {},
255
+ "expected": {
256
+ "output": "D"
257
+ }
258
+ },
259
+ {
260
+ "id": "comparisons/eq-absent-takes-chain",
261
+ "description": "An absent value takes the fallback chain under eq, as under every other modifier.",
262
+ "section": "11.1",
263
+ "message": "{{v:eq; 10:V2; default:D}}",
264
+ "payload": {},
265
+ "expected": {
266
+ "output": "D"
267
+ }
268
+ },
269
+ {
270
+ "id": "comparisons/ne-absent-is-not-a-text",
271
+ "description": "An absent value is never compared, so an option keyed with the host's word for nothing does not select under ne.",
272
+ "section": "11.1",
273
+ "message": "{{v:ne; undefined:U; default:D}}",
274
+ "payload": {},
275
+ "expected": {
276
+ "output": "D"
277
+ }
278
+ },
279
+ {
280
+ "id": "comparisons/ne-absent-without-default",
281
+ "description": "An absent value under ne takes the chain down to the empty string where nothing declares a default.",
282
+ "section": "11.1",
283
+ "message": "{{v:ne; a:A; b:B}}",
284
+ "payload": {},
285
+ "expected": {
286
+ "output": ""
287
+ }
288
+ },
289
+ {
290
+ "id": "comparisons/ne-undefined-entry-is-absent",
291
+ "description": "An own entry that is the host's undefined is absent, and takes the chain under ne.",
292
+ "section": "11.1",
293
+ "message": "{{v:ne; 10:V2; default:D}}",
294
+ "payload": {
295
+ "v": {
296
+ "$curly": "undefined"
297
+ }
298
+ },
299
+ "expected": {
300
+ "output": "D"
301
+ }
302
+ },
303
+ {
304
+ "id": "comparisons/absent-takes-chain-under-every-comparison",
305
+ "description": "An absent value takes the fallback chain under every comparison modifier.",
306
+ "section": "11.1",
307
+ "message": "{{v:eq; 1:X; default:D}}, {{v:ne; 1:X; default:D}}, {{v:lt; 1:X; default:D}}, {{v:gt; 1:X; default:D}}, {{v:lte; 1:X; default:D}}, {{v:gte; 1:X; default:D}}",
308
+ "payload": {},
309
+ "expected": {
310
+ "output": "D, D, D, D, D, D"
311
+ }
312
+ },
313
+ {
314
+ "id": "comparisons/lt-selects-greater-key",
315
+ "description": "lt selects the first option whose key is greater than the value.",
316
+ "section": "11.1",
317
+ "message": "{{v:lt; 1:VALUE1; 10:VALUE2; default:D}}",
318
+ "payload": {
319
+ "v": 5
320
+ },
321
+ "expected": {
322
+ "output": "VALUE2"
323
+ }
324
+ },
325
+ {
326
+ "id": "comparisons/lt-equal-key-is-not-greater",
327
+ "description": "A key equal to the value is not greater than it, so lt selects nothing.",
328
+ "section": "11.1",
329
+ "message": "{{v:lt; 1:VALUE1; 10:VALUE2; default:D}}",
330
+ "payload": {
331
+ "v": 10
332
+ },
333
+ "expected": {
334
+ "output": "D"
335
+ }
336
+ },
337
+ {
338
+ "id": "comparisons/gt-selects-lesser-key",
339
+ "description": "gt selects the first option whose key is less than the value.",
340
+ "section": "11.1",
341
+ "message": "{{v:gt; 1:VALUE1; 10:VALUE2; default:D}}",
342
+ "payload": {
343
+ "v": 15
344
+ },
345
+ "expected": {
346
+ "output": "VALUE2"
347
+ }
348
+ },
349
+ {
350
+ "id": "comparisons/gt-equal-key-is-not-lesser",
351
+ "description": "A key equal to the value is not less than it, so gt selects nothing.",
352
+ "section": "11.1",
353
+ "message": "{{v:gt; 1:VALUE1; 10:VALUE2; default:D}}",
354
+ "payload": {
355
+ "v": 1
356
+ },
357
+ "expected": {
358
+ "output": "D"
359
+ }
360
+ },
361
+ {
362
+ "id": "comparisons/gt-equal-key-verbatim",
363
+ "description": "A key equal to the value is not less than it, so gt selects nothing and takes the chain.",
364
+ "section": "11.1",
365
+ "message": "{{v:gt; 1:ONE; default:D}}",
366
+ "payload": {
367
+ "v": 1
368
+ },
369
+ "expected": {
370
+ "output": "D",
371
+ "reports": []
372
+ }
373
+ },
374
+ {
375
+ "id": "comparisons/lt-compares-numerically",
376
+ "description": "lt compares numerically, so 10 is greater than 9 though it sorts before it as text.",
377
+ "section": "11.1",
378
+ "message": "{{v:lt; 10:TEN; default:D}}",
379
+ "payload": {
380
+ "v": "9"
381
+ },
382
+ "expected": {
383
+ "output": "TEN"
384
+ }
385
+ },
386
+ {
387
+ "id": "comparisons/gt-compares-numerically",
388
+ "description": "gt compares numerically, so 9 is less than 10 though it sorts after it as text.",
389
+ "section": "11.1",
390
+ "message": "{{v:gt; 9:NINE; default:D}}",
391
+ "payload": {
392
+ "v": "10"
393
+ },
394
+ "expected": {
395
+ "output": "NINE"
396
+ }
397
+ },
398
+ {
399
+ "id": "comparisons/lt-ascending-key-order",
400
+ "description": "lt considers options in ascending numeric key order, not in source order.",
401
+ "section": "11.1",
402
+ "message": "{{v:lt; 10:TEN; 5:FIVE; default:D}}",
403
+ "payload": {
404
+ "v": 1
405
+ },
406
+ "expected": {
407
+ "output": "FIVE"
408
+ }
409
+ },
410
+ {
411
+ "id": "comparisons/gt-descending-key-order",
412
+ "description": "gt considers options in descending numeric key order, not in source order.",
413
+ "section": "11.1",
414
+ "message": "{{v:gt; 5:FIVE; 10:TEN; default:D}}",
415
+ "payload": {
416
+ "v": 20
417
+ },
418
+ "expected": {
419
+ "output": "TEN"
420
+ }
421
+ },
422
+ {
423
+ "id": "comparisons/lt-skips-non-numeric-key",
424
+ "description": "An option whose key is not numeric is never selected by lt, and the numeric keys around it are ordered.",
425
+ "section": "11.1",
426
+ "message": "{{v:lt; 10:TEN; abc:ABC; 5:FIVE; default:D}}",
427
+ "payload": {
428
+ "v": 1
429
+ },
430
+ "expected": {
431
+ "output": "FIVE"
432
+ }
433
+ },
434
+ {
435
+ "id": "comparisons/gt-skips-non-numeric-key",
436
+ "description": "An option whose key is not numeric is never selected by gt, and the numeric keys around it are ordered.",
437
+ "section": "11.1",
438
+ "message": "{{v:gt; 5:FIVE; abc:ABC; 10:TEN; default:D}}",
439
+ "payload": {
440
+ "v": 20
441
+ },
442
+ "expected": {
443
+ "output": "TEN"
444
+ }
445
+ },
446
+ {
447
+ "id": "comparisons/lt-non-numeric-key-only-takes-chain",
448
+ "description": "Where the only option has a non-numeric key, a numeric comparison selects nothing.",
449
+ "section": "11.1",
450
+ "message": "{{v:lt; abc:ABC; default:D}}",
451
+ "payload": {
452
+ "v": 1
453
+ },
454
+ "expected": {
455
+ "output": "D"
456
+ }
457
+ },
458
+ {
459
+ "id": "comparisons/lt-tie-source-order",
460
+ "description": "Keys 2 and 2.0 tie under lt, and the tie is broken by source order.",
461
+ "section": "11.1",
462
+ "message": "{{v:lt; 2:FIRST; 2.0:SECOND; default:D}}",
463
+ "payload": {
464
+ "v": 1
465
+ },
466
+ "expected": {
467
+ "output": "FIRST"
468
+ }
469
+ },
470
+ {
471
+ "id": "comparisons/lt-tie-source-order-reversed",
472
+ "description": "Keys 2.0 and 2 tie under lt, and the tie is broken by source order.",
473
+ "section": "11.1",
474
+ "message": "{{v:lt; 2.0:FIRST; 2:SECOND; default:D}}",
475
+ "payload": {
476
+ "v": 1
477
+ },
478
+ "expected": {
479
+ "output": "FIRST"
480
+ }
481
+ },
482
+ {
483
+ "id": "comparisons/gt-tie-source-order",
484
+ "description": "Keys 2 and 2.0 tie under gt, and the tie is broken by source order.",
485
+ "section": "11.1",
486
+ "message": "{{v:gt; 2:FIRST; 2.0:SECOND; default:D}}",
487
+ "payload": {
488
+ "v": 3
489
+ },
490
+ "expected": {
491
+ "output": "FIRST"
492
+ }
493
+ },
494
+ {
495
+ "id": "comparisons/gt-tie-source-order-reversed",
496
+ "description": "Keys 2.0 and 2 tie under gt, and the tie is broken by source order.",
497
+ "section": "11.1",
498
+ "message": "{{v:gt; 2.0:FIRST; 2:SECOND; default:D}}",
499
+ "payload": {
500
+ "v": 3
501
+ },
502
+ "expected": {
503
+ "output": "FIRST"
504
+ }
505
+ },
506
+ {
507
+ "id": "comparisons/partly-numeric-value-is-not-a-number",
508
+ "description": "The numeric conversion reads the whole value, so 12px is not a number and the comparison fails.",
509
+ "section": "11.2",
510
+ "message": "{{v:gt; 5:X; default:D}}",
511
+ "payload": {
512
+ "v": "12px"
513
+ },
514
+ "expected": {
515
+ "output": "D"
516
+ }
517
+ },
518
+ {
519
+ "id": "comparisons/whitespace-around-a-number",
520
+ "description": "Whitespace around a number is not part of it, so a padded value compares as the number.",
521
+ "section": "11.2",
522
+ "message": "{{v:gt; 5:X; default:D}}",
523
+ "payload": {
524
+ "v": " 12 "
525
+ },
526
+ "expected": {
527
+ "output": "X"
528
+ }
529
+ },
530
+ {
531
+ "id": "comparisons/signed-number",
532
+ "description": "A sign is part of a number, so a signed value compares as the number.",
533
+ "section": "11.2",
534
+ "message": "{{v:gt; 5:X; default:D}}",
535
+ "payload": {
536
+ "v": "+12"
537
+ },
538
+ "expected": {
539
+ "output": "X"
540
+ }
541
+ },
542
+ {
543
+ "id": "comparisons/exponent-number",
544
+ "description": "An exponent is part of a number, so 1e3 compares as one thousand.",
545
+ "section": "11.2",
546
+ "message": "{{v:gt; 5:X; default:D}}",
547
+ "payload": {
548
+ "v": "1e3"
549
+ },
550
+ "expected": {
551
+ "output": "X"
552
+ }
553
+ },
554
+ {
555
+ "id": "comparisons/infinity-compares",
556
+ "description": "A comparison over an infinity still selects, though no formatting modifier could format it.",
557
+ "section": "11.2",
558
+ "message": "{{v:gt; 5:X}}",
559
+ "payload": {
560
+ "v": "Infinity"
561
+ },
562
+ "expected": {
563
+ "output": "X"
564
+ }
565
+ },
566
+ {
567
+ "id": "comparisons/lte-equal-key-selects",
568
+ "description": "lte selects an option whose key equals the value.",
569
+ "section": "11.1",
570
+ "message": "{{v:lte; 1:VALUE1; 10:VALUE2; default:D}}",
571
+ "payload": {
572
+ "v": 10
573
+ },
574
+ "expected": {
575
+ "output": "VALUE2"
576
+ }
577
+ },
578
+ {
579
+ "id": "comparisons/lte-otherwise-as-lt",
580
+ "description": "Where no key equals the value, lte selects as lt does.",
581
+ "section": "11.1",
582
+ "message": "{{v:lte; 1:VALUE1; 10:VALUE2; default:D}}",
583
+ "payload": {
584
+ "v": 5
585
+ },
586
+ "expected": {
587
+ "output": "VALUE2"
588
+ }
589
+ },
590
+ {
591
+ "id": "comparisons/lte-none-takes-chain",
592
+ "description": "Where no key equals the value and none is greater, lte takes the chain.",
593
+ "section": "11.1",
594
+ "message": "{{v:lte; 1:VALUE1; 10:VALUE2; default:D}}",
595
+ "payload": {
596
+ "v": 11
597
+ },
598
+ "expected": {
599
+ "output": "D"
600
+ }
601
+ },
602
+ {
603
+ "id": "comparisons/gte-equal-key-selects",
604
+ "description": "gte selects an option whose key equals the value.",
605
+ "section": "11.1",
606
+ "message": "{{v:gte; 1:VALUE1; 10:VALUE2; default:D}}",
607
+ "payload": {
608
+ "v": 10
609
+ },
610
+ "expected": {
611
+ "output": "VALUE2"
612
+ }
613
+ },
614
+ {
615
+ "id": "comparisons/gte-otherwise-as-gt",
616
+ "description": "Where no key equals the value, gte selects as gt does, in descending key order.",
617
+ "section": "11.1",
618
+ "message": "{{v:gte; 1:VALUE1; 10:VALUE2; default:D}}",
619
+ "payload": {
620
+ "v": 5
621
+ },
622
+ "expected": {
623
+ "output": "VALUE1"
624
+ }
625
+ },
626
+ {
627
+ "id": "comparisons/gte-none-takes-chain",
628
+ "description": "Where no key equals the value and none is less, gte takes the chain.",
629
+ "section": "11.1",
630
+ "message": "{{v:gte; 1:VALUE1; 10:VALUE2; default:D}}",
631
+ "payload": {
632
+ "v": 0
633
+ },
634
+ "expected": {
635
+ "output": "D"
636
+ }
637
+ },
638
+ {
639
+ "id": "comparisons/lte-equality-before-order",
640
+ "description": "lte compares for equality before it reaches the key order, so an equal key wins over a greater one.",
641
+ "section": "11.1",
642
+ "message": "{{v:lte; 10:TEN; 20:TWENTY; default:D}}",
643
+ "payload": {
644
+ "v": 10
645
+ },
646
+ "expected": {
647
+ "output": "TEN"
648
+ }
649
+ },
650
+ {
651
+ "id": "comparisons/gte-equality-before-order",
652
+ "description": "gte compares for equality before it reaches the key order, so an equal key wins over a lesser one.",
653
+ "section": "11.1",
654
+ "message": "{{v:gte; 5:FIVE; 10:TEN; default:D}}",
655
+ "payload": {
656
+ "v": 10
657
+ },
658
+ "expected": {
659
+ "output": "TEN"
660
+ }
661
+ },
662
+ {
663
+ "id": "comparisons/lte-equality-leg-is-text",
664
+ "description": "The equality leg of lte is a text comparison, so it selects a key that is not numeric.",
665
+ "section": "11.1",
666
+ "message": "{{v:lte; abc:X}}",
667
+ "payload": {
668
+ "v": "abc"
669
+ },
670
+ "expected": {
671
+ "output": "X"
672
+ }
673
+ },
674
+ {
675
+ "id": "comparisons/gte-equality-leg-is-text",
676
+ "description": "The equality leg of gte is a text comparison, so it selects a key that is not numeric.",
677
+ "section": "11.1",
678
+ "message": "{{v:gte; abc:X; default:D}}",
679
+ "payload": {
680
+ "v": "abc"
681
+ },
682
+ "expected": {
683
+ "output": "X"
684
+ }
685
+ },
686
+ {
687
+ "id": "comparisons/lte-equality-leg-over-every-option",
688
+ "description": "The equality leg of lte runs over every option, so a non-numeric key after a numeric one is still selected.",
689
+ "section": "11.1",
690
+ "message": "{{v:lte; 10:TEN; abc:X; default:D}}",
691
+ "payload": {
692
+ "v": "abc"
693
+ },
694
+ "expected": {
695
+ "output": "X"
696
+ }
697
+ },
698
+ {
699
+ "id": "comparisons/gte-equality-leg-over-every-option",
700
+ "description": "The equality leg of gte runs over every option, so a non-numeric key before a numeric one is still selected.",
701
+ "section": "11.1",
702
+ "message": "{{v:gte; abc:X; 5:FIVE; default:D}}",
703
+ "payload": {
704
+ "v": "abc"
705
+ },
706
+ "expected": {
707
+ "output": "X"
708
+ }
709
+ },
710
+ {
711
+ "id": "comparisons/lte-equality-case-insensitive",
712
+ "description": "The equality leg of lte compares case-insensitively.",
713
+ "section": "11.1",
714
+ "message": "{{v:lte; ABC:X; default:D}}",
715
+ "payload": {
716
+ "v": "abc"
717
+ },
718
+ "expected": {
719
+ "output": "X"
720
+ }
721
+ },
722
+ {
723
+ "id": "comparisons/gte-equality-case-insensitive",
724
+ "description": "The equality leg of gte compares case-insensitively.",
725
+ "section": "11.1",
726
+ "message": "{{v:gte; ABC:X; default:D}}",
727
+ "payload": {
728
+ "v": "abc"
729
+ },
730
+ "expected": {
731
+ "output": "X"
732
+ }
733
+ },
734
+ {
735
+ "id": "comparisons/lte-equality-is-not-numeric",
736
+ "description": "The equality leg of lte is text rather than numeric, and the numeric leg is strict, so a key of 2.0 selects nothing for the value 2.",
737
+ "section": "11.1",
738
+ "message": "{{v:lte; 2.0:X; default:D}}",
739
+ "payload": {
740
+ "v": "2"
741
+ },
742
+ "expected": {
743
+ "output": "D"
744
+ }
745
+ },
746
+ {
747
+ "id": "comparisons/lte-numeric-leg-ascending",
748
+ "description": "The numeric leg of lte considers options in ascending key order.",
749
+ "section": "11.1",
750
+ "message": "{{v:lte; 10:TEN; 5:FIVE; default:D}}",
751
+ "payload": {
752
+ "v": 3
753
+ },
754
+ "expected": {
755
+ "output": "FIVE"
756
+ }
757
+ },
758
+ {
759
+ "id": "comparisons/gte-numeric-leg-descending",
760
+ "description": "The numeric leg of gte considers options in descending key order.",
761
+ "section": "11.1",
762
+ "message": "{{v:gte; 5:FIVE; 10:TEN; default:D}}",
763
+ "payload": {
764
+ "v": 20
765
+ },
766
+ "expected": {
767
+ "output": "TEN"
768
+ }
769
+ },
770
+ {
771
+ "id": "comparisons/gte-numeric-leg-skips-non-numeric",
772
+ "description": "The numeric leg of gte never selects an option whose key is not numeric.",
773
+ "section": "11.1",
774
+ "message": "{{v:gte; abc:ABC; 5:FIVE; default:D}}",
775
+ "payload": {
776
+ "v": 7
777
+ },
778
+ "expected": {
779
+ "output": "FIVE"
780
+ }
781
+ },
782
+ {
783
+ "id": "comparisons/no-selection-takes-inline-default",
784
+ "description": "Where no option is selected, the result is the fallback chain: the inline default.",
785
+ "section": "11.1",
786
+ "message": "{{v:eq; a:A; b:B; default:D}}",
787
+ "payload": {
788
+ "v": "c"
789
+ },
790
+ "expected": {
791
+ "output": "D"
792
+ }
793
+ },
794
+ {
795
+ "id": "comparisons/no-selection-takes-payload-default",
796
+ "description": "Where no option is selected, the chain is read in its order: the payload's default outranks the inline one.",
797
+ "section": "11.1",
798
+ "message": "{{v:eq; a:A; default:D}}",
799
+ "payload": {
800
+ "v": "c",
801
+ "default": "P"
802
+ },
803
+ "expected": {
804
+ "output": "P"
805
+ }
806
+ },
807
+ {
808
+ "id": "comparisons/selection-is-never-the-value",
809
+ "description": "A placeholder with an option asks which option matches, so where none does the result is never the value itself.",
810
+ "section": "9.5",
811
+ "message": "{{v; a:A;}}",
812
+ "payload": {
813
+ "v": "RAW"
814
+ },
815
+ "expected": {
816
+ "output": ""
817
+ }
818
+ },
819
+ {
820
+ "id": "comparisons/eq-first-of-shared-key",
821
+ "description": "Where two options share a key, eq selects the first.",
822
+ "section": "9.4",
823
+ "message": "{{v:eq; a:first; a:second}}",
824
+ "payload": {
825
+ "v": "a"
826
+ },
827
+ "expected": {
828
+ "output": "first"
829
+ }
830
+ },
831
+ {
832
+ "id": "comparisons/eq-first-of-shared-key-by-case",
833
+ "description": "eq selects the first option whose key equals the value case-insensitively, so an earlier key differing only by case wins.",
834
+ "section": "11.1",
835
+ "message": "{{v:eq; a:first; A:second}}",
836
+ "payload": {
837
+ "v": "A"
838
+ },
839
+ "expected": {
840
+ "output": "first"
841
+ }
842
+ },
843
+ {
844
+ "id": "comparisons/lte-first-of-shared-key",
845
+ "description": "Where two options share a key, the equality leg of lte selects the first.",
846
+ "section": "9.4",
847
+ "message": "{{v:lte; 2:first; 2:second}}",
848
+ "payload": {
849
+ "v": 2
850
+ },
851
+ "expected": {
852
+ "output": "first"
853
+ }
854
+ },
855
+ {
856
+ "id": "comparisons/gte-first-of-shared-key",
857
+ "description": "Where two options share a key, the equality leg of gte selects the first.",
858
+ "section": "9.4",
859
+ "message": "{{v:gte; 2:first; 2:second}}",
860
+ "payload": {
861
+ "v": 2
862
+ },
863
+ "expected": {
864
+ "output": "first"
865
+ }
866
+ },
867
+ {
868
+ "id": "comparisons/ne-first-of-shared-key",
869
+ "description": "Where two options share a key that differs from the value, ne selects the first.",
870
+ "section": "9.4",
871
+ "message": "{{v:ne; a:first; b:second; b:third}}",
872
+ "payload": {
873
+ "v": "a"
874
+ },
875
+ "expected": {
876
+ "output": "second"
877
+ }
878
+ },
879
+ {
880
+ "id": "comparisons/lt-first-of-shared-key",
881
+ "description": "Where two options share a key, the numeric leg selects the first.",
882
+ "section": "9.4",
883
+ "message": "{{v:lt; 5:first; 5:second; default:D}}",
884
+ "payload": {
885
+ "v": 1
886
+ },
887
+ "expected": {
888
+ "output": "first"
889
+ }
890
+ },
891
+ {
892
+ "id": "comparisons/empty-value-is-compared",
893
+ "description": "An empty string is present, so it is compared rather than taking the chain.",
894
+ "section": "9.2",
895
+ "message": "{{v:ne; a:A; default:D}}",
896
+ "payload": {
897
+ "v": ""
898
+ },
899
+ "expected": {
900
+ "output": "A"
901
+ }
902
+ },
903
+ {
904
+ "id": "comparisons/zero-is-compared",
905
+ "description": "Zero is present, so it is compared rather than taking the chain.",
906
+ "section": "9.2",
907
+ "message": "{{v:eq; 0:ZERO; default:D}}",
908
+ "payload": {
909
+ "v": 0
910
+ },
911
+ "expected": {
912
+ "output": "ZERO"
913
+ }
914
+ }
915
+ ]
916
+ }