UNPKG

11.2 kBJavaScriptView Raw
1/*eslint func-names: 0, no-magic-numbers:0, id-length:0 */
2/*global describe, it */
3
4const flow = require('../lib/xml-flow');
5const fs = require('fs');
6
7
8require('chai').should();
9
10function getFlow(fileName, options) {
11 return flow(fs.createReadStream(fileName), options);
12}
13
14describe('xml-flow', () => {
15 describe('invoke', () => {
16 it('should create an emitter when invoked with a stream and options', () => {
17 const inStream = fs.createReadStream('./test/simple.xml');
18 inStream.pause();
19 const simpleStream = flow(inStream);
20
21 simpleStream.on.should.be.a('function');
22 simpleStream.pause();
23 simpleStream.resume();
24 });
25 });
26
27 describe('.on(\'end\')', () => {
28 it('should emit after the file has been read', done => {
29 const simpleStream = getFlow('./test/simple.xml');
30 simpleStream.on('end', () => {
31 done();
32 });
33 });
34 });
35
36 describe('.on(\'tag:...\')', () => {
37 it('should emit the right number of nodes', done => {
38 const simpleStream = getFlow('./test/simple.xml');
39 let count = 0;
40
41 simpleStream.on('tag:item', () => {
42 count++;
43 });
44
45 simpleStream.on('end', () => {
46 count.should.equal(3);
47 done();
48 });
49 });
50
51 it('should make non-attributed data look really simple', done => {
52 const simpleStream = getFlow('./test/test.xml');
53 const output = {
54 $name: 'no-attrs',
55 person: [
56 { name: 'Bill', id: '1', age: '27' },
57 { name: 'Joe', id: '2', age: '29' },
58 { name: 'Smitty', id: '3', age: '37' }
59 ]
60 };
61
62
63 simpleStream.on('tag:no-attrs', node => {
64 node.should.deep.equal(output);
65 done();
66 });
67 });
68
69 it('should make all-attributed data look really simple', done => {
70 const simpleStream = getFlow('./test/test.xml');
71 const output = {
72 $name: 'all-attrs',
73 person: [
74 { name: 'Bill', id: '1', age: '27' },
75 { name: 'Joe', id: '2', age: '29' },
76 { name: 'Smitty', id: '3', age: '37' }
77 ]
78 };
79
80
81 simpleStream.on('tag:all-attrs', node => {
82 node.should.deep.equal(output);
83 done();
84 });
85 });
86
87 it('should handle tags with both attributes and other stuff', done => {
88 const simpleStream = getFlow('./test/test.xml');
89 const output = {
90 $name: 'mixed',
91 person: [
92 { $attrs: { name: 'Bill', id: '1', age: '27' }, $text: 'some text' },
93 { $attrs: { name: 'Joe', id: '2', age: '29' }, p: 'some paragraph' },
94 { $attrs: { name: 'Smitty', id: '3', age: '37' }, thing: { id: '999', ref: 'blah' }}
95 ]
96 };
97
98
99 simpleStream.on('tag:mixed', node => {
100 node.should.deep.equal(output);
101 done();
102 });
103 });
104
105 it('should preserve markup when things get more complex', done => {
106 const simpleStream = getFlow('./test/test.xml');
107 const output = {
108 $name: 'markup',
109 $markup: [
110 'Some unwrapped text',
111 { $name: 'person', $attrs: { name: 'Bill', id: '1', age: '27' }, $text: 'some text' },
112 'Some more unwrapped text',
113 { $name: 'person', $attrs: { name: 'Joe', id: '2', age: '29' }, p: 'some paragraph' },
114 { $name: 'person', $attrs: { name: 'Smitty', id: '3', age: '37' }, thing: { id: '999', ref: 'blah' }}
115 ]
116 };
117
118
119 simpleStream.on('tag:markup', node => {
120 node.should.deep.equal(output);
121 done();
122 });
123 });
124
125 it('should handle scripts', done => {
126 const simpleStream = getFlow('./test/test.xml');
127 const output = {
128 $name: 'has-scripts',
129 script: [
130 'var x = 3;',
131 { $attrs: { type: 'text/javascript' }, $script: '//this is a comment' }
132 ]
133 };
134
135 simpleStream.on('tag:has-scripts', node => {
136 node.should.deep.equal(output);
137 done();
138 });
139 });
140
141 it('should handle CDATA', done => {
142 const simpleStream = getFlow('./test/test.xml');
143 const output = {
144 $name: 'has-cdata',
145 $text: 'here comes the cdata...',
146 $cdata: 'this is <span>cdata!</span>'
147 };
148
149 simpleStream.on('tag:has-cdata', node => {
150 node.should.deep.equal(output);
151 done();
152 });
153 });
154
155 it('should handle bad formatting', done => {
156 const simpleStream = getFlow('./test/badFormatting.xml');
157 const output = {
158 $name: 'section',
159 $markup: [
160 'Text1</p>',
161 { $name: 'p', $text: 'Text2' },
162 { $name: 'p', $text: 'Text3' },
163 'Text4',
164 { $name: 'p' }
165 ]
166 };
167
168 simpleStream.on('tag:section', node => {
169 node.should.deep.equal(output);
170 done();
171 });
172 });
173 });
174
175 describe('options', () => {
176 it('should normalize whitespace by default', done => {
177 const simpleStream = getFlow('./test/test.xml');
178 const output = 'This is some text with extra whitespace.';
179
180 simpleStream.on('tag:extra-whitespace', node => {
181 node.$text.should.equal(output);
182 done();
183 });
184 });
185
186 it('should not normalize whitespace when asked not to', done => {
187 const simpleStream = getFlow('./test/test.xml', { normalize: false });
188 const output = 'This is some text with extra whitespace.';
189
190 simpleStream.on('tag:extra-whitespace', node => {
191 node.$text.should.equal(output);
192 done();
193 });
194 });
195
196 it('should trim by default', done => {
197 const simpleStream = getFlow('./test/test.xml');
198 const output = 'This is some text with extra whitespace.';
199
200 simpleStream.on('tag:extra-whitespace', node => {
201 node.$text.should.equal(output);
202 done();
203 });
204 });
205
206 it('should not trim when asked not to', done => {
207 const simpleStream = getFlow('./test/test.xml', { trim: false });
208 const output = 'This is some text with extra whitespace. ';
209
210 simpleStream.on('tag:extra-whitespace', node => {
211 node.$text.should.equal(output);
212 done();
213 });
214 });
215
216 it('should not preserve markup when told to never do so', done => {
217 const simpleStream = getFlow('./test/test.xml', { preserveMarkup: flow.NEVER });
218 const output = {
219 $name: 'markup',
220 $text: [
221 'Some unwrapped text',
222 'Some more unwrapped text'
223 ],
224 person: [
225 { $attrs: { name: 'Bill', id: '1', age: '27' }, $text: 'some text' },
226 { $attrs: { name: 'Joe', id: '2', age: '29' }, p: 'some paragraph' },
227 { $attrs: { name: 'Smitty', id: '3', age: '37' }, thing: { id: '999', ref: 'blah' }}
228 ]
229 };
230
231 simpleStream.on('tag:markup', node => {
232 node.should.deep.equal(output);
233 done();
234 });
235 });
236
237 it('should always preserve markup when told to do so', done => {
238 const simpleStream = getFlow('./test/test.xml', { preserveMarkup: flow.ALWAYS });
239 const output = {
240 $name: 'mixed',
241 $markup: [
242 {
243 $name: 'person',
244 $attrs: { name: 'Bill', id: '1', age: '27' },
245 $markup: [ 'some text' ]
246 },
247 {
248 $name: 'person',
249 $attrs: { name: 'Joe', id: '2', age: '29' },
250 $markup: [{ $name: 'p', $markup: [ 'some paragraph' ]}]
251 },
252 {
253 $name: 'person',
254 $attrs: { name: 'Smitty', id: '3', age: '37' },
255 $markup: [{ $name: 'thing', id: '999', ref: 'blah' }]
256 }
257 ]
258 };
259
260 simpleStream.on('tag:mixed', node => {
261 node.should.deep.equal(output);
262 done();
263 });
264 });
265
266 it('should handle CDATA as text when asked', done => {
267 const simpleStream = getFlow('./test/test.xml', { cdataAsText: true });
268 const output = {
269 $name: 'has-cdata',
270 $text: 'here comes the cdata...this is <span>cdata!</span>'
271 };
272
273 simpleStream.on('tag:has-cdata', node => {
274 node.should.deep.equal(output);
275 done();
276 });
277 });
278
279 it('should completely drop arrays when asked', done => {
280 const simpleStream = getFlow('./test/test.xml', { useArrays: flow.NEVER });
281 const output = {
282 $name: 'two-items',
283 p: 'one'
284 };
285
286 simpleStream.on('tag:two-items', node => {
287 node.should.deep.equal(output);
288 done();
289 });
290 });
291
292 it('should keep things as arrays when asked', done => {
293 const simpleStream = getFlow('./test/test.xml', { useArrays: flow.ALWAYS });
294 const output = {
295 $name: 'one-item',
296 p: [ 'this is one item' ]
297 };
298
299 simpleStream.on('tag:one-item', node => {
300 node.should.deep.equal(output);
301 done();
302 });
303 });
304 });
305
306 describe('toXml()', () => {
307 it('should convert $attrs as expected', () => {
308 const input = { $name: 'tag', $attrs: { id: 3 }};
309 const output = '<tag id="3"/>';
310
311 flow.toXml(input).should.equal(output);
312 });
313
314 it('should convert $text as expected', () => {
315 const input = { $name: 'tag', $attrs: { id: 3 }, $text: 'some text' };
316 const output = '<tag id="3">some text</tag>';
317
318 flow.toXml(input).should.equal(output);
319 });
320
321 it('should convert random fields as expected', () => {
322 const input = { $name: 'tag', $attrs: { id: 3 }, $text: 'some text', p: 'other text', j: [ 'text1', 'text2' ]};
323 const output = '<tag id="3">some text<p>other text</p><j>text1</j><j>text2</j></tag>';
324
325 flow.toXml(input).should.equal(output);
326 });
327
328 it('should convert $markup', () => {
329 const input = { $name: 'tag', $markup: [ 'text', { $name: 'j', $text: 'stuff' }]};
330 const output = '<tag>text<j>stuff</j></tag>';
331
332 flow.toXml(input).should.equal(output);
333 });
334
335 it('should convert $script', () => {
336 const input = { $name: 'tag', $script: 'console.log(\'stuff\');' };
337 const output = '<tag><script>console.log(\'stuff\');</script></tag>';
338
339 flow.toXml(input).should.equal(output);
340 });
341
342 it('should convert $cdata', () => {
343 const input = { $name: 'tag', $cdata: '<<science>>' };
344 const output = '<tag><![CDATA[<<science>>]]></tag>';
345
346 flow.toXml(input).should.equal(output);
347 });
348
349 it('should pretty-print', () => {
350 const input = {
351 $name: 'tag',
352 $markup: [
353 'text',
354 {
355 $name: 'tag',
356 $text: 'moar text'
357 }
358 ]
359 };
360 const output = '<tag>\n text\n <tag>\n moar text\n </tag>\n</tag>';
361
362 flow.toXml(input, { indent: ' ' }).should.equal(output);
363 });
364
365 it('should not do self-closing if asked', () => {
366 const input = { $name: 'tag', $attrs: { id: 3 }};
367 const output = '<tag id="3"></tag>';
368
369 flow.toXml(input, { selfClosing: false }).should.equal(output);
370 });
371
372 it('should escape html entities', () => {
373 const input = { $name: 'tag', $text: '<br><br><table class=\'data\' ></table>' };
374 const output = '<tag>&lt;br&gt;&lt;br&gt;&lt;table class=\'data\' &gt;&lt;/table&gt;</tag>';
375
376 flow.toXml(input).should.equal(output);
377 });
378 });
379});