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