Skip to content

Commit 51e4caa

Browse files
authored
Merge pull request #51 from suitcss/lint-main-file
Allow input file to be linted
2 parents 85316b9 + f5244c3 commit 51e4caa

File tree

9 files changed

+78
-31
lines changed

9 files changed

+78
-31
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
### HEAD
22

3+
* Input file is now linted (previously only imported files were passed through
4+
the linting tools)
35
* Add `--throw-error` (`-e`) to CLI
46
* Enable `lint` option by default
57
* Add `postcss-apply`

README.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,27 @@ Examples:
7474

7575
Returns a [PostCSS promise](http://api.postcss.org/LazyResult.html)
7676

77+
```js
78+
preprocessor(css: String [, options: Object] [, filename: String]);
79+
```
80+
81+
* `css`: CSS input (_required_)
82+
* `options`: Options to the preprocessor (see below) (_optional_)
83+
* `filename`: Filename of the input CSS file (_optional_)
84+
85+
#### Example
86+
7787
```js
7888
var preprocessor = require('suitcss-preprocessor');
7989
var fs = require('fs');
8090

81-
var css = fs.readFileSync('src/components/index.css', 'utf8');
91+
var filename = 'src/components/index.css';
92+
var css = fs.readFileSync(filename, 'utf8');
8293

8394
preprocessor(css, {
8495
root: 'path/to/css',
8596
minify: true,
86-
}).then(function(result) {
97+
}, filename).then(function(result) {
8798
fs.writeFileSync('build/bundle.css', result.css);
8899
});
89100
```

bin/suitcss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ function run() {
123123
});
124124
}
125125

126-
suitcss(css, opts).then(function(result) {
126+
suitcss(css, opts, input).then(function(result) {
127127
if (output) {
128128
writeFileSync(output, result.css + '\n');
129129
} else {

lib/index.js

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,17 @@ var defaults = {
5353
* Process CSS
5454
*
5555
* @param {String} css
56+
* @param {Object} options
57+
* @param {String} filename
5658
* @returns {Promise}
5759
*/
5860

59-
function preprocessor(css, options) {
61+
function preprocessor(css, options, filename) {
6062
options = mergeOptions(options);
6163

6264
var plugins = options.use.map(function(p) {
6365
var plugin = require(p);
6466
var settings = options[p];
65-
6667
return settings ? plugin(settings) : plugin;
6768
});
6869

@@ -72,7 +73,9 @@ function preprocessor(css, options) {
7273
processor.use(cssnano(options.cssnano));
7374
}
7475

75-
return processor.process(css, options.postcss);
76+
return lintFile(css, options, filename).then(function(result) {
77+
return processor.process(result.css, options.postcss);
78+
});
7679
}
7780

7881
/**
@@ -95,7 +98,7 @@ function mergeOptions(options) {
9598

9699
easyImportOpts.transform = function(css, filename) {
97100
var transformedCss = origTransform(css);
98-
return lintImportedFiles(mergedOpts, transformedCss, filename).then(function(result) {
101+
return lintFile(transformedCss, mergedOpts, filename).then(function(result) {
99102
return result.css;
100103
});
101104
};
@@ -116,30 +119,36 @@ function mergeOptions(options) {
116119
}
117120

118121
/**
119-
* Lint each imported component with postcss-bem-linter
120-
* and stylelint
122+
* Lint component with postcss-bem-linter and stylelint
121123
*
124+
* @param {String} css
122125
* @param {Object} options
126+
* @param {String} filename
123127
* @returns {Promise} Used by postcss-import transform
124128
*/
125-
function lintImportedFiles(options, css, filename) {
129+
function lintFile(css, options, filename) {
126130
var processor = postcss();
127131

128132
if (options.lint) {
129133
processor.use(stylelint(options.stylelint || stylelintConfigSuit));
130134
}
131135

136+
// Merge filename alongside any other `postcss` options
137+
assign(options, {
138+
postcss: {from: filename}
139+
});
140+
132141
processor
133142
.use(bemLinter(options['postcss-bem-linter']))
134143
.use(reporter(options['postcss-reporter']));
135144

136145
if (isPromise(css)) {
137146
return css.then(function(css) { // eslint-disable-line no-shadow
138-
return processor.process(css, {from: filename});
147+
return processor.process(css, options.postcss);
139148
});
140149
}
141150

142-
return processor.process(css, {from: filename});
151+
return processor.process(css, options.postcss);
143152
}
144153

145154
function isPromise(obj) {

test/fixtures/component.css

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
/** @define Component */
22

33
@import "./util.css";
4-
54
@custom-media --media-query (min-width: 200px);
65

76
:root {
@@ -12,17 +11,19 @@
1211
}
1312

1413
.Component {
14+
background: color(red a(90%));
1515
font-size: var(--Component-size);
1616
width: calc(100% * 1 / 6);
17-
background: color(red a(90%));
1817
}
1918

2019
.Component-item {
2120
display: flex;
21+
2222
@apply --Component-color;
2323
}
2424

2525
@media (--media-query) {
26+
2627
.Component-item {
2728
color: red;
2829
}

test/fixtures/component.out.css

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,19 @@
55
}
66

77
.Component {
8+
background: rgba(255, 0, 0, 0.9);
89
font-size: 16px;
910
width: 16.66667%;
10-
background: rgba(255, 0, 0, 0.9);
1111
}
1212

1313
.Component-item {
1414
display: flex;
15+
1516
color: green;
1617
}
1718

1819
@media (min-width: 200px) {
20+
1921
.Component-item {
2022
color: red;
2123
}

test/fixtures/config.out.css

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,19 @@
55
}
66

77
.Component {
8+
background: rgba(255, 0, 0, 0.9);
89
font-size: 16px;
910
width: 16.66667%;
10-
background: rgba(255, 0, 0, 0.9);
1111
}
1212

1313
.Component-item {
1414
display: flex;
15+
1516
color: green;
1617
}
1718

1819
@media (min-width: 200px) {
20+
1921
.Component-item {
2022
color: red;
2123
}

test/fixtures/minify.out.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
.u-img{border-radius:50%}.Component{font-size:16px;width:16.66667%;background:rgba(255,0,0,.9)}.Component-item{display:flex;color:green}@media (min-width:200px){.Component-item{color:red}}
1+
.u-img{border-radius:50%}.Component{background:rgba(255,0,0,.9);font-size:16px;width:16.66667%}.Component-item{display:flex;color:green}@media (min-width:200px){.Component-item{color:red}}

test/test.js

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@ var expect = chai.expect;
2020

2121
describe('suitcss', function() {
2222
it('should return a css string', function(done) {
23-
suitcss('body {}').then(function(result) {
23+
suitcss('body {}', {lint: false}).then(function(result) {
2424
expect(result.css).to.be.a('string');
2525
done();
2626
});
2727
});
2828

2929
it('should handle invalid input', function() {
3030
expect(function() {
31-
suitcss(null);
31+
suitcss(null, {lint: false});
3232
}).to.throw(TypeError);
3333
});
3434

@@ -59,7 +59,8 @@ describe('suitcss', function() {
5959
});
6060

6161
suitcss('body {}', {
62-
debug: debug
62+
debug: debug,
63+
lint: false
6364
}).then(function () {
6465
expect(debug.calledOnce).to.be.true;
6566
done();
@@ -102,19 +103,20 @@ describe('suitcss', function() {
102103

103104
beforeEach(function() {
104105
postcssStub = sinon.stub();
105-
processMethodStub = sinon.stub();
106+
processMethodStub = sinon.stub().returns(Promise.resolve());
106107

107108
postcssStub.returns({
108-
use: sinon.spy(),
109+
use: sinon.stub().returns({use: sinon.spy()}),
109110
process: processMethodStub
110111
});
111112
revert = suitcss.__set__('postcss', postcssStub);
112113
suitcss('body {}', {
113114
root: 'something',
115+
lint: false,
114116
postcss: {
115-
from: 'somefile.css'
117+
test: 'testing'
116118
}
117-
});
119+
}, 'filename.css');
118120
});
119121

120122
afterEach(function() {
@@ -123,15 +125,17 @@ describe('suitcss', function() {
123125

124126
it('should pass postcss options to the processor', function() {
125127
expect(processMethodStub.getCall(0).args[1]).to.eql({
126-
from: 'somefile.css'
128+
from: 'filename.css',
129+
test: 'testing'
127130
});
128131
});
129132
});
130133

131134
describe('using the transform option in postcss-import', function() {
132135
it('should use a default transform function that just returns the css', function(done) {
133136
suitcss('@import "./util.css";', {
134-
root: 'test/fixtures'
137+
root: 'test/fixtures',
138+
lint: false
135139
}).then(function(result) {
136140
expect(result.css).to.equal('.u-img {\n border-radius: 50%;\n}');
137141
done();
@@ -144,6 +148,7 @@ describe('suitcss', function() {
144148

145149
suitcss('@import "./util.css";', {
146150
root: 'test/fixtures',
151+
lint: false,
147152
'postcss-easy-import': {
148153
transform: transformStub
149154
}
@@ -159,6 +164,7 @@ describe('suitcss', function() {
159164
it('should also work with a promise returned from the custom transform function', function(done) {
160165
suitcss('@import "./util.css";', {
161166
root: 'test/fixtures',
167+
lint: false,
162168
'postcss-easy-import': {
163169
transform: function() {
164170
return Promise.resolve('body { font: red; }');
@@ -186,7 +192,8 @@ describe('suitcss', function() {
186192

187193
it('should call the updateWatchTaskFiles function with the file paths', function(done) {
188194
suitcss('@import "./util.css";', {
189-
root: 'test/fixtures'
195+
root: 'test/fixtures',
196+
lint: false
190197
}).then(function() {
191198
expect(updateWatchTaskFilesSpy.getCall(0).args[0][0]).to.contain('util.css');
192199
done();
@@ -199,6 +206,7 @@ describe('suitcss', function() {
199206

200207
suitcss('@import "./util.css";', {
201208
root: 'test/fixtures',
209+
lint: false,
202210
'postcss-easy-import': {
203211
onImport: onImportSpy
204212
}
@@ -264,7 +272,7 @@ describe('suitcss', function() {
264272

265273
it('should allow the config to be overidden', function() {
266274
return expect(
267-
suitcss('@import "./stylelint.css"', {
275+
suitcss('@import "./stylelint.css"\n\n', {
268276
root: 'test/fixtures',
269277
stylelint: {
270278
extends: 'stylelint-config-suitcss',
@@ -281,14 +289,24 @@ describe('suitcss', function() {
281289

282290
it('should throw an error if stylelint fails', function() {
283291
return expect(
284-
suitcss('@import "./stylelint.css"', {
292+
suitcss('@import "./stylelint.css"\n\n', {
285293
root: 'test/fixtures',
286294
'postcss-reporter': {
287295
throwError: true
288296
}
289297
})
290298
).to.be.rejectedWith(Error, 'postcss-reporter: warnings or errors were found');
291299
});
300+
301+
it('should lint the input file', function() {
302+
return expect(
303+
suitcss('body {}', {
304+
'postcss-reporter': {
305+
throwError: true
306+
}
307+
})
308+
).to.be.rejectedWith(Error, 'postcss-reporter: warnings or errors were found');
309+
});
292310
});
293311
});
294312
});
@@ -304,6 +322,7 @@ describe('features', function() {
304322

305323
suitcss(input, {
306324
root: 'test/fixtures',
325+
lint: false,
307326
// disable autoprefixer
308327
autoprefixer: {add: false, remove: false}
309328
}).then(function(result) {
@@ -317,6 +336,7 @@ describe('features', function() {
317336
var output = '.test { -webkit-filter: blur(1px); filter: blur(1px) }';
318337

319338
suitcss(input, {
339+
lint: false,
320340
autoprefixer: {
321341
browsers: 'Chrome 50'
322342
}
@@ -349,15 +369,15 @@ describe('cli', function() {
349369
});
350370

351371
it('should read from a file and write to stdout', function(done) {
352-
exec('node bin/suitcss -c test/noautoprefixer.config.js test/fixtures/cli/input.css', function(err, stdout) {
372+
exec('node bin/suitcss -L -c test/noautoprefixer.config.js test/fixtures/cli/input.css', function(err, stdout) {
353373
if (err) return done(err);
354374
expect(stdout).to.equal(output);
355375
done();
356376
});
357377
});
358378

359379
it('should read from stdin and write to stdout', function(done) {
360-
var testChild = exec('node bin/suitcss -c test/noautoprefixer.config.js', function(err, stdout) {
380+
var testChild = exec('node bin/suitcss -L -c test/noautoprefixer.config.js', function(err, stdout) {
361381
if (err) return done(err);
362382
expect(stdout).to.equal(output);
363383
done();

0 commit comments

Comments
 (0)