forked from nodeca/js-yaml
/
dump-scalar-styles.js
245 lines (210 loc) · 9.09 KB
/
dump-scalar-styles.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
'use strict';
var assert = require('assert');
var yaml = require('../..');
// Indents lines by 2 spaces. Empty lines (\n only) are not indented.
function indent(string) {
return string.replace(/^.+/gm, ' ' + '$&');
}
function getLength(s) {
return s.length;
}
// Repeats a string n times.
function repeat(string, n) {
return (new Array(n + 1)).join(string);
}
suite('Scalar style dump:', function () {
suite('Plain style', function () {
test('is preferred', function () {
[ 'plain',
'hello world',
'pizza 3.14159',
// cannot be misinterpreted as a number
'127.0.0.1',
// quotes are allowed after the first character
'quoted"scalar',
'here\'s to "quotes"',
// additional allowed characters
'100% safe non-first characters? Of course!',
'Jack & Jill <well@example.com>'
].forEach(function (string) {
assert.strictEqual(yaml.safeDump(string), string + '\n');
});
});
test('disallows flow indicators inside flow collections', function () {
assert.strictEqual(yaml.safeDump({ quote: 'mispell [sic]' }, { flowLevel: 0 }),
'{quote: mispell [sic]}\n');
assert.strictEqual(yaml.safeDump({ key: 'no commas, either' }, { flowLevel: 0 }),
'{key: no commas, either}\n');
});
});
suite('Single- and double-quoted styles', function () {
test('quote strings of ambiguous type', function () {
assert.strictEqual(yaml.safeDump('Yes'), '\'Yes\'\n');
assert.strictEqual(yaml.safeDump('true'), '\'true\'\n');
assert.strictEqual(yaml.safeDump('42'), '\'42\'\n');
assert.strictEqual(yaml.safeDump('99.9'), '\'99.9\'\n');
assert.strictEqual(yaml.safeDump('127.0001'), '\'127.0001\'\n');
assert.strictEqual(yaml.safeDump('1.23015e+3'), '\'1.23015e+3\'\n');
});
test('quote leading/trailing whitespace', function () {
assert.strictEqual(yaml.safeDump(' leading space'), '\' leading space\'\n');
assert.strictEqual(yaml.safeDump('trailing space '), '\'trailing space \'\n');
});
test('quote leading quotes', function () {
assert.strictEqual(yaml.safeDump("'singles double'"), "'''singles double'''\n");
assert.strictEqual(yaml.safeDump('"single double'), '\'"single double\'\n');
});
test('escape \\ and " in double-quoted', function () {
assert.strictEqual(yaml.safeDump('\u0007 escape\\ escaper"'), '"\\a escape\\\\ escaper\\""\n');
});
test('escape non-printables', function () {
assert.strictEqual(yaml.safeDump('a\nb\u0001c'), '"a\\nb\\x01c"\n');
});
});
suite('Literal style', function () {
var content = 'a\nb \n\n c\n d', indented = indent(content);
test('preserves trailing newlines using chomping', function () {
assert.strictEqual(yaml.safeDump({ a: '\n', b: '\n\n', c: 'c\n', d: 'd\nd' }),
'a: |+\n\nb: |+\n\n\nc: |\n c\nd: |-\n d\n d\n');
assert.strictEqual(yaml.safeDump('\n'), '|+\n' + '\n');
assert.strictEqual(yaml.safeDump('\n\n'), '|+\n' + '\n\n');
assert.strictEqual(yaml.safeDump(content), '|-\n' + indented + '\n');
assert.strictEqual(yaml.safeDump(content + '\n'), '|\n' + indented + '\n');
assert.strictEqual(yaml.safeDump(content + '\n\n'), '|+\n' + indented + '\n\n');
assert.strictEqual(yaml.safeDump(content + '\n\n\n'), '|+\n' + indented + '\n\n\n');
});
test('accepts leading whitespace', function () {
assert.strictEqual(yaml.safeDump(' ' + content), '|2-\n ' + indented + '\n');
});
test('falls back to quoting when required indent indicator is too large', function () {
assert.strictEqual(yaml.safeDump(' these go\nup to\neleven', { indent: 11 }),
'" these go\\nup to\\neleven"\n');
});
test('does not use block style for multiline key', function () {
assert.strictEqual(yaml.safeDump({
'push\nand': {
you: 'pull'
}
}), '"push\\nand":\n you: pull\n');
});
});
suite('Folded style', function () {
(function () {
var content = (function () {
var result = '';
var i = 1000;
for (var para = 1; para <= 7; para++) {
result += '\n';
// indent paragraphs 3 and 4
if (para === 3 || para === 4) {
result += repeat(' ', para);
}
// vary the number of words on the last line
for (var count = 2 * (30 / 5) + para - 1; count > 0; count--) {
result += i + ' ';
if (i % 17 === 0) result += ' ';
i++;
}
}
return result;
}());
var wrapped = '\n' +
'1000 1001 1002 1003 1004 1005\n' +
'1006 1007 1008 1009 1010 1011 \n' +
'\n' +
'1012 1013 1014 1015 1016 1017\n' +
'1018 1019 1020 1021 1022 1023\n' +
'1024 \n' +
' 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 \n' +
' 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 \n' +
'1054 1055 1056 1057 1058 1059\n' +
'1060 1061 1062 1063 1064 1065\n' +
'1066 1067 1068 1069 \n' +
'\n' +
'1070 1071 1072 1073 1074 1075\n' +
'1076 1077 1078 1079 1080 1081\n' +
'1082 1083 1084 1085 1086 \n' +
'\n' +
'1087 1088 1089 1090 1091 1092\n' +
'1093 1094 1095 1096 1097 1098\n' +
'1099 1100 1101 1102 1103 1104 ';
var indented = indent(wrapped);
function dumpNarrow(s) {
return yaml.safeDump(s, { lineWidth: 30 + 2 });
}
test('wraps lines and ignores more-indented lines ', function () {
assert.strictEqual(dumpNarrow(content), '>-\n' + indented + '\n');
});
test('preserves trailing newlines using chomping', function () {
assert.strictEqual(dumpNarrow(content + '\n'), '>\n' + indented + '\n');
assert.strictEqual(dumpNarrow(content + '\n\n'), '>+\n' + indented + '\n\n');
assert.strictEqual(dumpNarrow(content + '\n\n\n'), '>+\n' + indented + '\n\n\n');
});
}());
// Dump and check that dump-then-load preserves content (is the identity function).
function dump(input, opts) {
var output = yaml.safeDump(input, opts);
assert.strictEqual(yaml.safeLoad(output), input, 'Dump then load should preserve content');
return output;
}
test('should not cut off a long word at the start of a line', function () {
assert.strictEqual(dump('123\n' + repeat('1234567890', 9) + ' hello\ngoodbye'),
'>-\n' + indent(
'123\n' +
'\n' +
repeat('1234567890', 9) + '\n' +
'hello\n' +
'\n' +
'goodbye\n'));
});
test('preserves consecutive spaces', function () {
var alphabet = 'a bc def ghi' + repeat(' ', 70) + 'jk lmn o\n'
+ ' p qrstu v' + repeat(' ', 80) + '\nw x\n' + 'yz ';
assert.strictEqual(dump(alphabet),
'>-\n' + indent(
'a bc def \n' +
'ghi' + repeat(' ', 70) + 'jk \n' +
'lmn o\n' +
' p qrstu v' + repeat(' ', 80) + '\n' +
'w x\n' +
'\n' +
'yz \n'));
var indeed = repeat('word. ', 31) + '\n' +
[ 2, 3, 5, 7, 11, 13, 17 ]
.map(function (n) { return repeat(' ', n); })
.join('\n');
assert.strictEqual(dump(indeed),
'>-\n' + indent(
'word. word. word. word. word. word. word. word. word. word. word. word. word.\n' +
'word. word. word. word. word. word. word. word. word. word. word. word. word.\n' +
'word. word. word. word. word. \n' +
[ 2, 3, 5, 7, 11, 13, 17 ]
.map(function (n) { return repeat(' ', n); })
.join('\n') + '\n'));
});
var story = 'Call me Ishmael. Some years ago—never mind how long precisely—'
+ 'having little or no money in my purse, '
+ 'and nothing particular to interest me on shore, '
+ 'I thought I would sail about a little and see the watery part of the world...';
var prefix = 'var short_story = "",';
var line = 'longer_story = "' + story + '";';
test('should fold a long last line missing an ending newline', function () {
var content = [ prefix, line ].join('\n');
var lengths = dump(content).split('\n').map(getLength);
assert.deepEqual(lengths, [ 2, 23, 0, 69, 76, 80, 24, 0 ]);
});
test('should not fold a more-indented last line', function functionName() {
var content = [ prefix, line, ' ' + line ].join('\n');
var lengths = dump(content).split('\n').map(getLength);
assert.deepEqual(lengths, [ 2, 23, 0, 69, 76, 80, 24, 250, 0 ]);
});
test('should not fold when lineWidth === -1', function () {
var content = [ prefix, line, line + line, line ].join('\n');
assert.strictEqual(dump(content, { lineWidth: -1 }), '|-\n' + indent(content) + '\n');
});
test('falls back to literal style when no lines are foldable', function () {
var content = [ prefix, ' ' + line, ' ' + line ].join('\n');
assert.strictEqual(dump(content), '|-\n' + indent(content) + '\n');
});
});
});