Initial commit
[yaffs-website] / node_modules / gulp-postcss / test.js
1 /* global it, afterEach, beforeEach, describe, Promise */
2
3 var assert = require('assert')
4 var gutil = require('gulp-util')
5 var sourceMaps = require('gulp-sourcemaps')
6 var postcss = require('./index')
7 var proxyquire = require('proxyquire')
8 var sinon = require('sinon')
9 var path = require('path')
10
11 it('should pass file when it isNull()', function (cb) {
12   var stream = postcss([ doubler ])
13   var emptyFile = {
14     isNull: function () { return true }
15   }
16
17   stream.once('data', function (data) {
18     assert.equal(data, emptyFile)
19     cb()
20   })
21
22   stream.write(emptyFile)
23
24   stream.end()
25 })
26
27 it('should transform css with multiple processors', function (cb) {
28
29   var stream = postcss(
30     [ asyncDoubler, objectDoubler() ]
31   )
32
33   stream.on('data', function (file) {
34     var result = file.contents.toString('utf8')
35     var target = 'a { color: black; color: black; color: black; color: black }'
36     assert.equal( result, target )
37     cb()
38   })
39
40   stream.write(new gutil.File({
41     contents: new Buffer('a { color: black }')
42   }))
43
44   stream.end()
45
46 })
47
48
49 it('should correctly wrap postcss errors', function (cb) {
50
51   var stream = postcss([ doubler ])
52
53   stream.on('error', function (err) {
54     assert.ok(err instanceof gutil.PluginError)
55     assert.equal(err.plugin, 'gulp-postcss')
56     assert.equal(err.showStack, false)
57     assert.equal(err.fileName, 'testpath')
58     cb()
59   })
60
61   stream.write(new gutil.File({
62     contents: new Buffer('a {'),
63     path: 'testpath'
64   }))
65
66   stream.end()
67
68 })
69
70 it('should respond with error on stream files', function (cb) {
71
72   var stream = postcss([ doubler ])
73
74   stream.on('error', function (err) {
75     assert.ok(err instanceof gutil.PluginError)
76     assert.equal(err.plugin, 'gulp-postcss')
77     assert.equal(err.showStack, true)
78     assert.equal(err.fileName, 'testpath')
79     cb()
80   })
81
82   var streamFile = {
83     isStream: function () { return true },
84     isNull: function() { return false },
85     path: 'testpath'
86   };
87
88   stream.write(streamFile)
89
90   stream.end()
91
92 })
93
94 it('should generate source maps', function (cb) {
95
96   var init = sourceMaps.init()
97   var write = sourceMaps.write()
98   var css = postcss(
99     [ doubler, asyncDoubler ]
100   )
101
102   init
103     .pipe(css)
104     .pipe(write)
105
106   write.on('data', function (file) {
107     assert.equal(file.sourceMap.mappings, 'AAAA,IAAI,aAAY,CAAZ,aAAY,CAAZ,aAAY,CAAZ,YAAY,EAAE')
108     assert(/sourceMappingURL=data:application\/json;(?:charset=\w+;)?base64/.test(file.contents.toString()))
109     cb()
110   })
111
112   init.write(new gutil.File({
113     base: __dirname,
114     path: __dirname + '/fixture.css',
115     contents: new Buffer('a { color: black }')
116   }))
117
118   init.end()
119
120 })
121
122
123 it('should correctly generate relative source map', function (cb) {
124
125   var init = sourceMaps.init()
126   var css = postcss(
127     [ doubler, doubler ]
128   )
129
130   init.pipe(css)
131
132   css.on('data', function (file) {
133     assert.equal(file.sourceMap.file, 'fixture.css')
134     assert.deepEqual(file.sourceMap.sources, ['fixture.css'])
135     cb()
136   })
137
138   init.write(new gutil.File({
139     base: __dirname + '/src',
140     path: __dirname + '/src/fixture.css',
141     contents: new Buffer('a { color: black }')
142   }))
143
144   init.end()
145
146 })
147
148
149 describe('PostCSS Guidelines', function () {
150
151   var sandbox = sinon.sandbox.create()
152   var CssSyntaxError = function (message, sourceCode) {
153     this.name = 'CssSyntaxError'
154     this.message = message
155     this.sourceCode = sourceCode
156     this.showSourceCode = function () {
157       return this.sourceCode
158     }
159   }
160   var postcssStub = {
161     use: function () {}
162   , process: function () {}
163   }
164   var postcssLoadConfigStub
165   var postcss = proxyquire('./index', {
166     postcss: function (plugins) {
167       postcssStub.use(plugins)
168       return postcssStub
169     }
170   , 'postcss-load-config': function (ctx, configPath) {
171       return postcssLoadConfigStub(ctx, configPath)
172     }
173   , 'vinyl-sourcemaps-apply': function () {
174       return {}
175     }
176   })
177
178   beforeEach(function () {
179     postcssLoadConfigStub = sandbox.stub()
180     sandbox.stub(postcssStub, 'use')
181     sandbox.stub(postcssStub, 'process')
182   })
183
184   afterEach(function () {
185     sandbox.restore()
186   })
187
188   it('should set `from` and `to` processing options to `file.path`', function (cb) {
189
190     var stream = postcss([ doubler ])
191     var cssPath = __dirname + '/src/fixture.css'
192     postcssStub.process.returns(Promise.resolve({
193       css: ''
194     , warnings: function () {
195         return []
196       }
197     }))
198
199     stream.on('data', function () {
200       assert.equal(postcssStub.process.getCall(0).args[1].to, cssPath)
201       assert.equal(postcssStub.process.getCall(0).args[1].from, cssPath)
202       cb()
203     })
204
205     stream.write(new gutil.File({
206       contents: new Buffer('a {}')
207     , path: cssPath
208     }))
209
210     stream.end()
211
212   })
213
214   it('should allow override of `to` processing option', function (cb) {
215
216     var stream = postcss([ doubler ], {to: 'overriden'})
217     postcssStub.process.returns(Promise.resolve({
218       css: ''
219     , warnings: function () {
220         return []
221       }
222     }))
223
224     stream.on('data', function () {
225       assert.equal(postcssStub.process.getCall(0).args[1].to, 'overriden')
226       cb()
227     })
228
229     stream.write(new gutil.File({
230       contents: new Buffer('a {}')
231     }))
232
233     stream.end()
234
235   })
236
237   it('should take plugins and options from callback', function (cb) {
238
239     var cssPath = __dirname + '/fixture.css'
240     var file = new gutil.File({
241       contents: new Buffer('a {}')
242     , path: cssPath
243     })
244     var plugins = [ doubler ]
245     var callback = sandbox.stub().returns({
246       plugins: plugins
247     , options: { to: 'overriden' }
248     })
249     var stream = postcss(callback)
250
251     postcssStub.process.returns(Promise.resolve({
252       css: ''
253     , warnings: function () {
254         return []
255       }
256     }))
257
258     stream.on('data', function () {
259       assert.equal(callback.getCall(0).args[0], file)
260       assert.equal(postcssStub.use.getCall(0).args[0], plugins)
261       assert.equal(postcssStub.process.getCall(0).args[1].to, 'overriden')
262       cb()
263     })
264
265     stream.end(file)
266
267   })
268
269   it('should take plugins and options from postcss-load-config', function (cb) {
270
271     var cssPath = __dirname + '/fixture.css'
272     var file = new gutil.File({
273       contents: new Buffer('a {}')
274     , path: cssPath
275     })
276     var stream = postcss({ to: 'initial' })
277     var plugins = [ doubler ]
278
279     postcssLoadConfigStub.returns(Promise.resolve({
280       plugins: plugins
281     , options: { to: 'overriden' }
282     }))
283
284     postcssStub.process.returns(Promise.resolve({
285       css: ''
286     , warnings: function () {
287         return []
288       }
289     }))
290
291     stream.on('data', function () {
292       assert.deepEqual(postcssLoadConfigStub.getCall(0).args[0], {
293         file: file
294       , options: { to: 'initial' }
295       })
296       assert.equal(postcssStub.use.getCall(0).args[0], plugins)
297       assert.equal(postcssStub.process.getCall(0).args[1].to, 'overriden')
298       cb()
299     })
300
301     stream.end(file)
302
303   })
304
305   it('should point the config location to file directory', function (cb) {
306     var cssPath = __dirname + '/fixture.css'
307     var stream = postcss()
308     postcssLoadConfigStub.returns(Promise.resolve({ plugins: [] }))
309     postcssStub.process.returns(Promise.resolve({
310       css: ''
311     , warnings: function () {
312         return []
313       }
314     }))
315     stream.on('data', function () {
316       assert.deepEqual(postcssLoadConfigStub.getCall(0).args[1], __dirname)
317       cb()
318     })
319     stream.end(new gutil.File({
320       contents: new Buffer('a {}')
321     , path: cssPath
322     }))
323   })
324
325   it('should set the config location from option', function (cb) {
326     var cssPath = __dirname + '/fixture.css'
327     var stream = postcss({ config: '/absolute/path' })
328     postcssLoadConfigStub.returns(Promise.resolve({ plugins: [] }))
329     postcssStub.process.returns(Promise.resolve({
330       css: ''
331     , warnings: function () {
332         return []
333       }
334     }))
335     stream.on('data', function () {
336       assert.deepEqual(postcssLoadConfigStub.getCall(0).args[1], '/absolute/path')
337       cb()
338     })
339     stream.end(new gutil.File({
340       contents: new Buffer('a {}')
341     , path: cssPath
342     }))
343   })
344
345   it('should set the config location from option relative to the base dir', function (cb) {
346     var cssPath = __dirname + '/src/fixture.css'
347     var stream = postcss({ config: './relative/path' })
348     postcssLoadConfigStub.returns(Promise.resolve({ plugins: [] }))
349     postcssStub.process.returns(Promise.resolve({
350       css: ''
351     , warnings: function () {
352         return []
353       }
354     }))
355     stream.on('data', function () {
356       assert.deepEqual(postcssLoadConfigStub.getCall(0).args[1], __dirname + '/relative/path')
357       cb()
358     })
359     stream.end(new gutil.File({
360       contents: new Buffer('a {}')
361     , path: cssPath
362     , base: __dirname
363     }))
364   })
365
366   it('should not override `from` and `map` if using gulp-sourcemaps', function (cb) {
367     var stream = postcss([ doubler ], { from: 'overriden', map: 'overriden' })
368     var cssPath = __dirname + '/fixture.css'
369     postcssStub.process.returns(Promise.resolve({
370       css: ''
371     , warnings: function () {
372         return []
373       }
374     , map: {
375         toJSON: function () {
376           return {
377             sources: [],
378             file: ''
379           }
380         }
381       }
382     }))
383
384     sandbox.stub(gutil, 'log')
385
386     stream.on('data', function () {
387       assert.deepEqual(postcssStub.process.getCall(0).args[1].from, cssPath)
388       assert.deepEqual(postcssStub.process.getCall(0).args[1].map, { annotation: false })
389       var firstMessage = gutil.log.getCall(0).args[1]
390       var secondMessage = gutil.log.getCall(1).args[1]
391       assert(firstMessage, '/fixture.css\nCannot override from option, because it is required by gulp-sourcemaps')
392       assert(secondMessage, '/fixture.css\nCannot override map option, because it is required by gulp-sourcemaps')
393       cb()
394     })
395
396     var file = new gutil.File({
397       contents: new Buffer('a {}')
398     , path: cssPath
399     })
400     file.sourceMap = {}
401     stream.end(file)
402   })
403
404   it('should not output js stack trace for `CssSyntaxError`', function (cb) {
405
406     var stream = postcss([ doubler ])
407     var cssSyntaxError = new CssSyntaxError('message', 'sourceCode')
408     postcssStub.process.returns(Promise.reject(cssSyntaxError))
409
410     stream.on('error', function (error) {
411       assert.equal(error.showStack, false)
412       assert.equal(error.message, 'message' + '\n\nsourceCode\n')
413       cb()
414     })
415
416     stream.write(new gutil.File({
417       contents: new Buffer('a {}')
418     }))
419
420     stream.end()
421
422   })
423
424
425   it('should display `result.warnings()` content', function (cb) {
426
427     var stream = postcss([ doubler ])
428     var cssPath = __dirname + '/src/fixture.css'
429     function Warning (msg) {
430       this.toString = function () {
431         return msg
432       }
433     }
434
435     sandbox.stub(gutil, 'log')
436     postcssStub.process.returns(Promise.resolve({
437       css: ''
438     , warnings: function () {
439         return [new Warning('msg1'), new Warning('msg2')]
440       }
441     }))
442
443     stream.on('data', function () {
444       assert(gutil.log.calledWith('gulp-postcss:', 'src' +  path.sep + 'fixture.css\nmsg1\nmsg2'))
445       cb()
446     })
447
448     stream.write(new gutil.File({
449       contents: new Buffer('a {}')
450     , path: cssPath
451     }))
452
453     stream.end()
454
455   })
456
457   it('should pass options down to PostCSS', function (cb) {
458
459     var customSyntax = function () {}
460     var options = {
461       syntax: customSyntax
462     }
463
464     var stream = postcss([ doubler ], options)
465     var cssPath = __dirname + '/src/fixture.css'
466     postcssStub.process.returns(Promise.resolve({
467       css: ''
468     , warnings: function () {
469         return []
470       }
471     }))
472
473     stream.on('data', function () {
474       var resultOptions = postcssStub.process.getCall(0).args[1]
475       // remove automatically set options
476       delete resultOptions.from
477       delete resultOptions.to
478       delete resultOptions.map
479       assert.deepEqual(resultOptions, options)
480       cb()
481     })
482
483     stream.write(new gutil.File({
484       contents: new Buffer('a {}')
485     , path: cssPath
486     }))
487
488     stream.end()
489
490   })
491
492 })
493
494
495 function doubler (css) {
496   css.walkDecls(function (decl) {
497     decl.parent.prepend(decl.clone())
498   })
499 }
500
501 function asyncDoubler (css) {
502   return new Promise(function (resolve) {
503     setTimeout(function () {
504       doubler(css)
505       resolve()
506     })
507   })
508 }
509
510 function objectDoubler () {
511   var processor = require('postcss')()
512   processor.use(doubler)
513   return processor
514 }