true 2.1.3 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a6a3b24624df5c06f4fcdb1da05e91c508e43d1f
4
- data.tar.gz: dc4fbcdbd8bd5e8ad8d33a4354ee8eacb94e1312
3
+ metadata.gz: 43b01a67a1a718450d44cbfde4148435092d885e
4
+ data.tar.gz: 2a9662ae8300f2983a2de95e1eb5555a3b5f6138
5
5
  SHA512:
6
- metadata.gz: f0bc90f7aecd98a9fcf877487c13cfccff8b5ef1617d37e86e44b82d412e3f63b9f5199cd743ffa44df248845339252cbc6d059605928e6627f7cfe2bfba8768
7
- data.tar.gz: 1dfa2bcd589cdb764dda6720c0cf0dd3fdc244c2831e62d215df77c6b579cb0b6fb7fd1fb2227fc0bdc8f10be16d3f436988ce9c3f70b0bd94ba0dcc150c377a
6
+ metadata.gz: aad2c6319c983bad8e96b4364c936d7f0f18a2a3ad2aae8ff5e042fe0f9cdebf873079b9074f65681a2f4b9ca4a7c618d9d46a6b777559999fc9e3e86dd2dba9
7
+ data.tar.gz: b62531759187d5970e96fd946df5e1031e43bd0c9e3384f25184c9ad1243aa5eefdf4649c429dd40d531aef7284cf52568e9e9db3c380fef9e596dcd56d4663b
@@ -2,6 +2,23 @@ True Changelog
2
2
  ==============
3
3
 
4
4
 
5
+ 2.2.0 UNRELEASED
6
+ ----------------
7
+ - Output CSS context around Mocha parsing errors.
8
+ - Added `$fail-on-error` argument to `report()` mixin.
9
+ Set to `true` if you need the Sass compiler to fail
10
+ on broken tests.
11
+ - Fix bug with `assert-false` causing it to fail on `null` values.
12
+ - Allow unquoted descriptions and test/module names.
13
+ - Fix bug throwing off test-count and reporting.
14
+
15
+
16
+ 2.1.4 (12/22/16)
17
+ ----------------
18
+ - Fix default assertion messages
19
+ - Upgrade dependencies
20
+
21
+
5
22
  2.0.2 (5/13/15)
6
23
  ---------------
7
24
  - Fixes debug inspector.
data/README.md CHANGED
@@ -1,5 +1,4 @@
1
- True
2
- ====
1
+ # True
3
2
 
4
3
  [![Build Status](https://api.travis-ci.org/oddbird/true.svg)](https://travis-ci.org/oddbird/true)
5
4
 
@@ -13,8 +12,7 @@ True
13
12
  *True your sweet plugin before you deploy.*
14
13
 
15
14
 
16
- Install
17
- -------
15
+ ## Install
18
16
 
19
17
  in command line:
20
18
 
@@ -30,11 +28,9 @@ npm install sass-true
30
28
  ```
31
29
 
32
30
 
33
- Usage
34
- -----
31
+ ## Usage
35
32
 
36
- With any Sass compiler
37
- ~~~~~~~~~~~~~~~~~~~~~~
33
+ ### With any Sass compiler
38
34
 
39
35
  ```scss
40
36
  @import "true";
@@ -85,8 +81,7 @@ in the output code.
85
81
  Version control can make that much easier than it sounds.
86
82
 
87
83
 
88
- With node-sass and Mocha (or other JS test runners)
89
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
84
+ ### With node-sass and Mocha (or other JS test runners)
90
85
 
91
86
  1. Install `true` via npm (`npm install sass-true`).
92
87
 
@@ -94,7 +89,7 @@ With node-sass and Mocha (or other JS test runners)
94
89
 
95
90
  3. Write a shim JS test file in `test/test_sass.js`:
96
91
 
97
- ```js
92
+ ```javascript
98
93
  var path = require('path');
99
94
  var sassTrue = require('sass-true');
100
95
 
@@ -116,6 +111,12 @@ Any other JS test runner with equivalents to Mocha's `describe` and `it` should
116
111
  be usable in the same way; just pass your test runner's `describe` and `it`
117
112
  equivalents into `runSass`.
118
113
 
114
+ If True's Mocha plugin can't parse the CSS output from True, it'll give you
115
+ some context lines of CSS as part of the error message. This context will
116
+ likely be helpful in understanding the parse failure. By default it provides up
117
+ to 10 lines of context; if you need more, you can provide a numeric fourth
118
+ argument to `runSass`, the maximum number of context lines to provide.
119
+
119
120
 
120
121
  #### With Grunt...
121
122
 
@@ -124,7 +125,7 @@ Run Mocha using the Grunt task supplied by
124
125
 
125
126
  Install `grunt-mocha-cli`:
126
127
 
127
- ```
128
+ ```bash
128
129
  npm install grunt-mocha-cli --save-dev
129
130
  ```
130
131
 
@@ -144,18 +145,17 @@ Run tests:
144
145
  grunt mochacli
145
146
  ```
146
147
 
147
-
148
- With ruby-sass on the command line
149
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
148
+ ### With ruby-sass on the command line
150
149
 
151
150
  ```bash
152
151
  true-cli [options] PATH
153
152
  ```
154
153
 
155
154
  Options:
156
- * `-s` silent
157
- * `-c` config file
158
- * `-d` debug config file settings
155
+
156
+ * `-s` silent
157
+ * `-c` config file
158
+ * `-d` debug config file settings
159
159
 
160
160
  Config file (optional):
161
161
 
@@ -166,14 +166,13 @@ options:
166
166
  # require ruby sass extension libraries
167
167
  require:
168
168
  - "compass"
169
- - "serialy_sassy"
169
+ - "serialy/sassy"
170
170
  ```
171
171
 
172
172
  default location: `test/true.yml`
173
173
 
174
174
 
175
- Settings
176
- --------
175
+ ## Settings
177
176
 
178
177
  There is only one setting:
179
178
  `$true-terminal-output`
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.1.2
1
+ 2.2.0
@@ -24,7 +24,7 @@ var EXPECTED_START_TOKEN = 'EXPECTED';
24
24
  var EXPECTED_END_TOKEN = 'END_EXPECTED';
25
25
  var ASSERT_END_TOKEN = 'END_ASSERT';
26
26
 
27
- module.exports.runSass = function (options, describe, it) {
27
+ module.exports.runSass = function (options, describe, it, contextLines) {
28
28
  var sassPath = path.join(__dirname, '..', 'sass');
29
29
  if (options.includePaths) {
30
30
  options.includePaths.push(sassPath);
@@ -32,7 +32,7 @@ module.exports.runSass = function (options, describe, it) {
32
32
  options.includePaths = [sassPath];
33
33
  }
34
34
  var css = sass.renderSync(options).css.toString();
35
- var modules = parse(css);
35
+ var modules = parse(css, contextLines);
36
36
 
37
37
  _.each(modules, function (module) {
38
38
  describeModule(module, describe, it);
@@ -70,212 +70,227 @@ var describeModule = function (module, describe, it) {
70
70
  };
71
71
 
72
72
 
73
- var parse = module.exports.parse = function (rawCss) {
74
- var ast = css.parse(rawCss);
75
- var ctx = { modules: [] };
76
- var handler = parseModule;
77
-
78
- _.each(ast.stylesheet.rules, function (rule) {
79
- handler = handler(rule, ctx);
80
- });
81
-
82
- finishCurrentModule(ctx);
83
-
84
- return ctx.modules;
85
- };
73
+ var parse = module.exports.parse = function (rawCss, contextLines) {
74
+ var contextLines = (typeof contextLines === 'undefined') ? 10 : contextLines;
75
+ var lines = rawCss.split(/\r?\n/);
86
76
 
77
+ var parseCss = function () {
78
+ var ast = css.parse(rawCss);
79
+ var ctx = { modules: [] };
80
+ var handler = parseModule;
87
81
 
88
- var parseError = function (msg, seeking, pos) {
89
- return new Error(
90
- 'Line ' + pos.start.line + ', ' +
91
- 'column ' + pos.start.column + ': ' +
92
- msg + '; ' +
93
- 'looking for ' + seeking
94
- );
95
- }
82
+ _.each(ast.stylesheet.rules, function (rule) {
83
+ handler = handler(rule, ctx);
84
+ });
96
85
 
86
+ finishCurrentModule(ctx);
97
87
 
98
- var parseModule = function (rule, ctx) {
99
- if (rule.type === 'charset') { return parseModule; }
100
- if (rule.type === 'comment') {
101
- var text = rule.comment.trim();
102
- if (!text) { return parseModule; }
103
- if (startsWith(text, MODULE_TOKEN)) {
104
- finishCurrentModule(ctx);
105
- ctx.currentModule = { module: text.substring(MODULE_TOKEN.length), tests: [] };
106
- return parseTest;
107
- }
108
- if (startsWith(text, SUMMARY_TOKEN)) {
109
- return ignoreUntilEndSummary;
110
- }
111
- // ignore un-recognized comments, keep looking for module header.
112
- return parseModule;
88
+ return ctx.modules;
113
89
  }
114
- throw parseError('Unexpected rule type "' + rule.type + '"', 'module header', rule.position);
115
- };
116
90
 
117
91
 
118
- var ignoreUntilEndSummary = function (rule, ctx) {
119
- if (rule.type === 'comment') {
120
- var text = rule.comment.trim();
121
- if (startsWith(text, END_SUMMARY_TOKEN)) {
122
- return parseModule;
123
- }
124
- return ignoreUntilEndSummary;
92
+ var parseError = function (msg, seeking, pos) {
93
+ return new Error(
94
+ 'Line ' + pos.start.line + ', ' +
95
+ 'column ' + pos.start.column + ': ' +
96
+ msg + '; ' +
97
+ 'looking for ' + seeking + '.\n' +
98
+ '-- Context --\n' +
99
+ lines.slice(
100
+ Math.max(0, pos.start.line - contextLines),
101
+ pos.start.line
102
+ ).join('\n') + '\n' +
103
+ (' '.repeat(pos.start.column - 1)) + '^\n'
104
+ );
125
105
  }
126
- throw parseError('Unexpected rule type "' + rule.type + '"', 'end summary', rule.position);
127
- };
128
106
 
129
107
 
130
- var parseTest = function (rule, ctx) {
131
- if (rule.type === 'comment') {
132
- var text = rule.comment.trim();
133
- if (!text) { return parseTest; }
134
- if (text.match(/^-+$/)) {
135
- return parseTest;
136
- }
137
- if (startsWith(text, TEST_TOKEN)) {
138
- finishCurrentTest(ctx);
139
- ctx.currentTest = { test: text.substring(TEST_TOKEN.length), assertions: [] };
140
- return parseAssertion;
108
+ var parseModule = function (rule, ctx) {
109
+ if (rule.type === 'charset') { return parseModule; }
110
+ if (rule.type === 'comment') {
111
+ var text = rule.comment.trim();
112
+ if (!text) { return parseModule; }
113
+ if (startsWith(text, MODULE_TOKEN)) {
114
+ finishCurrentModule(ctx);
115
+ ctx.currentModule = { module: text.substring(MODULE_TOKEN.length), tests: [] };
116
+ return parseTest;
117
+ }
118
+ if (startsWith(text, SUMMARY_TOKEN)) {
119
+ return ignoreUntilEndSummary;
120
+ }
121
+ // ignore un-recognized comments, keep looking for module header.
122
+ return parseModule;
141
123
  }
142
- return parseModule(rule, ctx);
143
- }
144
- throw parseError('Unexpected rule type "' + rule.type + '"', 'test', rule.position);
145
- };
124
+ throw parseError('Unexpected rule type "' + rule.type + '"', 'module header', rule.position);
125
+ };
146
126
 
147
127
 
148
- var parseAssertion = function (rule, ctx) {
149
- if (rule.type === 'comment') {
150
- var text = rule.comment.trimLeft();
151
- if (!text) { return parseAssertion; }
152
- if (startsWith(text, PASS_TOKEN)) {
153
- finishCurrentAssertion(ctx);
154
- ctx.currentAssertion = {
155
- description: text.substring(PASS_TOKEN.length).trim() || '<no description>',
156
- passed: true
157
- };
158
- return parseAssertion;
159
- } else if (startsWith(text, FAIL_TOKEN)) {
160
- finishCurrentAssertion(ctx);
161
- var endAssertionType = text.indexOf(END_FAIL_TOKEN);
162
- ctx.currentAssertion = {
163
- description: text.substring(endAssertionType + 2).trim(),
164
- passed: false,
165
- assertionType: text.substring(FAIL_TOKEN.length, endAssertionType).trim(),
166
- };
167
- return parseFailureDetail;
168
- } else if (startsWith(text, ASSERT_TOKEN)) {
169
- finishCurrentAssertion(ctx);
170
- ctx.currentAssertion = {
171
- description: text.substring(ASSERT_TOKEN.length).trim(),
172
- assertionType: 'equal'
173
- };
174
- return parseAssertionOutputStart;
128
+ var ignoreUntilEndSummary = function (rule, ctx) {
129
+ if (rule.type === 'comment') {
130
+ var text = rule.comment.trim();
131
+ if (startsWith(text, END_SUMMARY_TOKEN)) {
132
+ return parseModule;
133
+ }
134
+ return ignoreUntilEndSummary;
175
135
  }
176
- return parseTest(rule, ctx);
177
- }
178
- throw parseError('Unexpected rule type "' + rule.type + '"', 'assertion', rule.position);
179
- }
136
+ throw parseError('Unexpected rule type "' + rule.type + '"', 'end summary', rule.position);
137
+ };
180
138
 
181
139
 
182
- var parseFailureDetail = function (rule, ctx) {
183
- if (rule.type === 'comment') {
184
- var text = rule.comment.trim();
185
- if (startsWith(text, FAILURE_DETAIL_TOKEN)) {
186
- var startType = text.indexOf(FAILURE_TYPE_START_TOKEN);
187
- var endType = text.indexOf(FAILURE_TYPE_END_TOKEN);
188
- var type = text.substring(startType, endType + 1);
189
- var content = text.substring(endType + 3);
190
- var outputOrExpected;
191
- if (text.substring(FAILURE_DETAIL_TOKEN.length, startType) === OUTPUT_TOKEN) {
192
- outputOrExpected = 'output';
193
- } else if (text.substring(FAILURE_DETAIL_TOKEN.length, startType) === EXPECTED_TOKEN) {
194
- outputOrExpected = 'expected';
140
+ var parseTest = function (rule, ctx) {
141
+ if (rule.type === 'comment') {
142
+ var text = rule.comment.trim();
143
+ if (!text) { return parseTest; }
144
+ if (text.match(/^-+$/)) {
145
+ return parseTest;
195
146
  }
196
- if (outputOrExpected) {
197
- ctx.currentAssertion[outputOrExpected] = type + ' ' + content;
147
+ if (startsWith(text, TEST_TOKEN)) {
148
+ finishCurrentTest(ctx);
149
+ ctx.currentTest = { test: text.substring(TEST_TOKEN.length), assertions: [] };
150
+ return parseAssertion;
151
+ }
152
+ return parseModule(rule, ctx);
153
+ }
154
+ throw parseError('Unexpected rule type "' + rule.type + '"', 'test', rule.position);
155
+ };
156
+
157
+
158
+ var parseAssertion = function (rule, ctx) {
159
+ if (rule.type === 'comment') {
160
+ var text = rule.comment.trimLeft();
161
+ if (!text) { return parseAssertion; }
162
+ if (startsWith(text, PASS_TOKEN)) {
163
+ finishCurrentAssertion(ctx);
164
+ ctx.currentAssertion = {
165
+ description: text.substring(PASS_TOKEN.length).trim() || '<no description>',
166
+ passed: true
167
+ };
168
+ return parseAssertion;
169
+ } else if (startsWith(text, FAIL_TOKEN)) {
170
+ finishCurrentAssertion(ctx);
171
+ var endAssertionType = text.indexOf(END_FAIL_TOKEN);
172
+ ctx.currentAssertion = {
173
+ description: text.substring(endAssertionType + 2).trim(),
174
+ passed: false,
175
+ assertionType: text.substring(FAIL_TOKEN.length, endAssertionType).trim(),
176
+ };
198
177
  return parseFailureDetail;
178
+ } else if (startsWith(text, ASSERT_TOKEN)) {
179
+ finishCurrentAssertion(ctx);
180
+ ctx.currentAssertion = {
181
+ description: text.substring(ASSERT_TOKEN.length).trim(),
182
+ assertionType: 'equal'
183
+ };
184
+ return parseAssertionOutputStart;
199
185
  }
186
+ return parseTest(rule, ctx);
200
187
  }
201
- return parseAssertion(rule, ctx);
188
+ throw parseError('Unexpected rule type "' + rule.type + '"', 'assertion', rule.position);
202
189
  }
203
- throw parseError('Unexpected rule type "' + rule.type + '"', 'output/expected', rule.position);
204
- };
205
190
 
206
191
 
207
- var parseAssertionOutputStart = function (rule, ctx) {
208
- if (rule.type === 'comment') {
209
- var text = rule.comment.trim();
210
- if (!text) { return parseAssertionOutputStart; }
211
- if (text === OUTPUT_START_TOKEN) {
212
- ctx.currentOutputRules = [];
213
- return parseAssertionOutput;
192
+ var parseFailureDetail = function (rule, ctx) {
193
+ if (rule.type === 'comment') {
194
+ var text = rule.comment.trim();
195
+ if (startsWith(text, FAILURE_DETAIL_TOKEN)) {
196
+ var startType = text.indexOf(FAILURE_TYPE_START_TOKEN);
197
+ var endType = text.indexOf(FAILURE_TYPE_END_TOKEN);
198
+ var type = text.substring(startType, endType + 1);
199
+ var content = text.substring(endType + 3);
200
+ var outputOrExpected;
201
+ if (text.substring(FAILURE_DETAIL_TOKEN.length, startType) === OUTPUT_TOKEN) {
202
+ outputOrExpected = 'output';
203
+ } else if (text.substring(FAILURE_DETAIL_TOKEN.length, startType) === EXPECTED_TOKEN) {
204
+ outputOrExpected = 'expected';
205
+ }
206
+ if (outputOrExpected) {
207
+ ctx.currentAssertion[outputOrExpected] = type + ' ' + content;
208
+ return parseFailureDetail;
209
+ }
210
+ }
211
+ return parseAssertion(rule, ctx);
214
212
  }
215
- throw parseError('Unexpected comment "' + text + '"', 'OUTPUT', rule.position);
216
- }
217
- throw parseError('Unexpected rule type "' + rule.type + '"', 'OUTPUT', rule.position);
218
- };
213
+ throw parseError('Unexpected rule type "' + rule.type + '"', 'output/expected', rule.position);
214
+ };
219
215
 
220
216
 
221
- var parseAssertionOutput = function (rule, ctx) {
222
- if (rule.type === 'comment') {
223
- if (rule.comment.trim() === OUTPUT_END_TOKEN) {
224
- ctx.currentAssertion.output = css.stringify(
225
- { stylesheet: { rules: ctx.currentOutputRules }});
226
- delete ctx.currentOutputRules;
227
- return parseAssertionExpectedStart;
217
+ var parseAssertionOutputStart = function (rule, ctx) {
218
+ if (rule.type === 'comment') {
219
+ var text = rule.comment.trim();
220
+ if (!text) { return parseAssertionOutputStart; }
221
+ if (text === OUTPUT_START_TOKEN) {
222
+ ctx.currentOutputRules = [];
223
+ return parseAssertionOutput;
224
+ }
225
+ throw parseError('Unexpected comment "' + text + '"', 'OUTPUT', rule.position);
228
226
  }
229
- }
230
- ctx.currentOutputRules.push(rule);
231
- return parseAssertionOutput;
232
- };
227
+ throw parseError('Unexpected rule type "' + rule.type + '"', 'OUTPUT', rule.position);
228
+ };
233
229
 
234
230
 
235
- var parseAssertionExpectedStart = function (rule, ctx) {
236
- if (rule.type === 'comment') {
237
- var text = rule.comment.trim();
238
- if (!text) { return parseAssertionExpectedStart; }
239
- if (text === EXPECTED_START_TOKEN) {
240
- ctx.currentExpectedRules = [];
241
- return parseAssertionExpected;
231
+ var parseAssertionOutput = function (rule, ctx) {
232
+ if (rule.type === 'comment') {
233
+ if (rule.comment.trim() === OUTPUT_END_TOKEN) {
234
+ ctx.currentAssertion.output = css.stringify(
235
+ { stylesheet: { rules: ctx.currentOutputRules }});
236
+ delete ctx.currentOutputRules;
237
+ return parseAssertionExpectedStart;
238
+ }
242
239
  }
243
- throw parseError('Unexpected comment "' + text + '"', 'EXPECTED', rule.position);
244
- }
245
- throw parseError('Unexpected rule type "' + rule.type + '"', 'EXPECTED', rule.position);
246
- };
247
-
248
-
249
- var parseAssertionExpected = function (rule, ctx) {
250
- if (rule.type === 'comment') {
251
- if (rule.comment.trim() === EXPECTED_END_TOKEN) {
252
- ctx.currentAssertion.expected = css.stringify(
253
- { stylesheet: { rules: ctx.currentExpectedRules }});
254
- delete ctx.currentExpectedRules;
255
- ctx.currentAssertion.passed = (
256
- ctx.currentAssertion.output === ctx.currentAssertion.expected);
257
- return parseEndAssertion;
240
+ ctx.currentOutputRules.push(rule);
241
+ return parseAssertionOutput;
242
+ };
243
+
244
+
245
+ var parseAssertionExpectedStart = function (rule, ctx) {
246
+ if (rule.type === 'comment') {
247
+ var text = rule.comment.trim();
248
+ if (!text) { return parseAssertionExpectedStart; }
249
+ if (text === EXPECTED_START_TOKEN) {
250
+ ctx.currentExpectedRules = [];
251
+ return parseAssertionExpected;
252
+ }
253
+ throw parseError('Unexpected comment "' + text + '"', 'EXPECTED', rule.position);
258
254
  }
259
- }
260
- ctx.currentExpectedRules.push(rule);
261
- return parseAssertionExpected;
262
- };
255
+ throw parseError('Unexpected rule type "' + rule.type + '"', 'EXPECTED', rule.position);
256
+ };
257
+
258
+
259
+ var parseAssertionExpected = function (rule, ctx) {
260
+ if (rule.type === 'comment') {
261
+ if (rule.comment.trim() === EXPECTED_END_TOKEN) {
262
+ ctx.currentAssertion.expected = css.stringify(
263
+ { stylesheet: { rules: ctx.currentExpectedRules }});
264
+ delete ctx.currentExpectedRules;
265
+ ctx.currentAssertion.passed = (
266
+ ctx.currentAssertion.output === ctx.currentAssertion.expected);
267
+ return parseEndAssertion;
268
+ }
269
+ }
270
+ ctx.currentExpectedRules.push(rule);
271
+ return parseAssertionExpected;
272
+ };
273
+
274
+
275
+ var parseEndAssertion = function (rule, ctx) {
276
+ if (rule.type === 'comment') {
277
+ var text = rule.comment.trim();
278
+ if (!text) { return parseEndAssertion; }
279
+ if (text === ASSERT_END_TOKEN) {
280
+ finishCurrentAssertion(ctx);
281
+ return parseAssertion;
282
+ }
283
+ throw parseError('Unexpected comment "' + text + '"', 'END_ASSERT', rule.position);
284
+ }
285
+ throw parseError('Unexpected rule type "' + rule.type + '"', 'END_ASSERT', rule.position);
286
+ };
263
287
 
264
288
 
265
- var parseEndAssertion = function (rule, ctx) {
266
- if (rule.type === 'comment') {
267
- var text = rule.comment.trim();
268
- if (!text) { return parseEndAssertion; }
269
- if (text === ASSERT_END_TOKEN) {
270
- finishCurrentAssertion(ctx);
271
- return parseAssertion;
272
- }
273
- throw parseError('Unexpected comment "' + text + '"', 'END_ASSERT', rule.position);
274
- }
275
- throw parseError('Unexpected rule type "' + rule.type + '"', 'END_ASSERT', rule.position);
289
+ return parseCss();
276
290
  };
277
291
 
278
292
 
293
+
279
294
  var finishCurrentModule = function (ctx) {
280
295
  finishCurrentTest(ctx);
281
296
  if (ctx.currentModule) {