true 2.1.2 → 2.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +35 -4
- data/VERSION +1 -1
- data/lib/main.js +115 -61
- data/sass/_true.scss +7 -7
- data/sass/true/_assert.scss +21 -10
- data/sass/true/_modules.scss +3 -7
- data/sass/true/_results.scss +19 -124
- data/sass/true/_settings.scss +37 -7
- data/sass/true/_tests.scss +2 -7
- data/sass/true/_utilities.scss +28 -3
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a6a3b24624df5c06f4fcdb1da05e91c508e43d1f
|
4
|
+
data.tar.gz: dc4fbcdbd8bd5e8ad8d33a4354ee8eacb94e1312
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0bc90f7aecd98a9fcf877487c13cfccff8b5ef1617d37e86e44b82d412e3f63b9f5199cd743ffa44df248845339252cbc6d059605928e6627f7cfe2bfba8768
|
7
|
+
data.tar.gz: 1dfa2bcd589cdb764dda6720c0cf0dd3fdc244c2831e62d215df77c6b579cb0b6fb7fd1fb2227fc0bdc8f10be16d3f436988ce9c3f70b0bd94ba0dcc150c377a
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
True
|
2
2
|
====
|
3
3
|
|
4
|
-
[![Build Status](https://travis-ci.org/oddbird/true.
|
4
|
+
[![Build Status](https://api.travis-ci.org/oddbird/true.svg)](https://travis-ci.org/oddbird/true)
|
5
5
|
|
6
6
|
*Verb*
|
7
7
|
|
@@ -33,7 +33,8 @@ npm install sass-true
|
|
33
33
|
Usage
|
34
34
|
-----
|
35
35
|
|
36
|
-
|
36
|
+
With any Sass compiler
|
37
|
+
~~~~~~~~~~~~~~~~~~~~~~
|
37
38
|
|
38
39
|
```scss
|
39
40
|
@import "true";
|
@@ -84,7 +85,8 @@ in the output code.
|
|
84
85
|
Version control can make that much easier than it sounds.
|
85
86
|
|
86
87
|
|
87
|
-
|
88
|
+
With node-sass and Mocha (or other JS test runners)
|
89
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
88
90
|
|
89
91
|
1. Install `true` via npm (`npm install sass-true`).
|
90
92
|
|
@@ -115,7 +117,36 @@ be usable in the same way; just pass your test runner's `describe` and `it`
|
|
115
117
|
equivalents into `runSass`.
|
116
118
|
|
117
119
|
|
118
|
-
|
120
|
+
#### With Grunt...
|
121
|
+
|
122
|
+
Run Mocha using the Grunt task supplied by
|
123
|
+
[grunt-mocha-cli](https://github.com/Rowno/grunt-mocha-cli)
|
124
|
+
|
125
|
+
Install `grunt-mocha-cli`:
|
126
|
+
|
127
|
+
```
|
128
|
+
npm install grunt-mocha-cli --save-dev
|
129
|
+
```
|
130
|
+
|
131
|
+
Configure task:
|
132
|
+
|
133
|
+
```javascript
|
134
|
+
grunt.loadNpmTasks('grunt-mocha');
|
135
|
+
|
136
|
+
mochacli: {
|
137
|
+
all: ['test/test_sass.js']
|
138
|
+
},
|
139
|
+
```
|
140
|
+
|
141
|
+
Run tests:
|
142
|
+
|
143
|
+
```bash
|
144
|
+
grunt mochacli
|
145
|
+
```
|
146
|
+
|
147
|
+
|
148
|
+
With ruby-sass on the command line
|
149
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
119
150
|
|
120
151
|
```bash
|
121
152
|
true-cli [options] PATH
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.1.
|
1
|
+
2.1.2
|
data/lib/main.js
CHANGED
@@ -3,9 +3,28 @@ var css = require('css');
|
|
3
3
|
var path = require('path');
|
4
4
|
var sass = require('node-sass');
|
5
5
|
|
6
|
+
// Tokens defining the True CSS output language.
|
7
|
+
var MODULE_TOKEN = '# Module: ';
|
8
|
+
var MODULE_NESTING_TOKEN = ' :: ';
|
9
|
+
var SUMMARY_TOKEN = '# SUMMARY ';
|
10
|
+
var END_SUMMARY_TOKEN = '----------';
|
11
|
+
var TEST_TOKEN = 'Test: ';
|
12
|
+
var PASS_TOKEN = '✔ ';
|
13
|
+
var FAIL_TOKEN = '✖ FAILED [';
|
14
|
+
var END_FAIL_TOKEN = ']';
|
15
|
+
var ASSERT_TOKEN = 'ASSERT: ';
|
16
|
+
var FAILURE_DETAIL_TOKEN = '- ';
|
17
|
+
var FAILURE_TYPE_START_TOKEN = '[';
|
18
|
+
var FAILURE_TYPE_END_TOKEN = ']';
|
19
|
+
var OUTPUT_TOKEN = 'Output ';
|
20
|
+
var EXPECTED_TOKEN = 'Expected ';
|
21
|
+
var OUTPUT_START_TOKEN = 'OUTPUT';
|
22
|
+
var OUTPUT_END_TOKEN = 'END_OUTPUT';
|
23
|
+
var EXPECTED_START_TOKEN = 'EXPECTED';
|
24
|
+
var EXPECTED_END_TOKEN = 'END_EXPECTED';
|
25
|
+
var ASSERT_END_TOKEN = 'END_ASSERT';
|
6
26
|
|
7
27
|
module.exports.runSass = function (options, describe, it) {
|
8
|
-
var assert = require('assert');
|
9
28
|
var sassPath = path.join(__dirname, '..', 'sass');
|
10
29
|
if (options.includePaths) {
|
11
30
|
options.includePaths.push(sassPath);
|
@@ -16,26 +35,34 @@ module.exports.runSass = function (options, describe, it) {
|
|
16
35
|
var modules = parse(css);
|
17
36
|
|
18
37
|
_.each(modules, function (module) {
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
assertion.
|
36
|
-
|
37
|
-
|
38
|
-
|
38
|
+
describeModule(module, describe, it);
|
39
|
+
});
|
40
|
+
};
|
41
|
+
|
42
|
+
var describeModule = function (module, describe, it) {
|
43
|
+
var assert = require('assert');
|
44
|
+
describe(module.module, function () {
|
45
|
+
_.each(module.modules, function (submodule) {
|
46
|
+
describeModule(submodule, describe, it);
|
47
|
+
});
|
48
|
+
_.each(module.tests, function (test) {
|
49
|
+
it(test.test, function () {
|
50
|
+
_.each(test.assertions, function (assertion) {
|
51
|
+
if (!assertion.passed) {
|
52
|
+
var msg = (
|
53
|
+
assertion.description + ' ("' +
|
54
|
+
assertion.output + '" ' +
|
55
|
+
assertion.assertionType + ' "' +
|
56
|
+
assertion.expected +
|
57
|
+
'")'
|
58
|
+
);
|
59
|
+
assert.fail(
|
60
|
+
assertion.output,
|
61
|
+
assertion.expected,
|
62
|
+
msg,
|
63
|
+
assertion.assertionType
|
64
|
+
);
|
65
|
+
}
|
39
66
|
});
|
40
67
|
});
|
41
68
|
});
|
@@ -59,9 +86,12 @@ var parse = module.exports.parse = function (rawCss) {
|
|
59
86
|
|
60
87
|
|
61
88
|
var parseError = function (msg, seeking, pos) {
|
62
|
-
|
63
|
-
'Line ' + pos.start.line + ',
|
64
|
-
|
89
|
+
return new Error(
|
90
|
+
'Line ' + pos.start.line + ', ' +
|
91
|
+
'column ' + pos.start.column + ': ' +
|
92
|
+
msg + '; ' +
|
93
|
+
'looking for ' + seeking
|
94
|
+
);
|
65
95
|
}
|
66
96
|
|
67
97
|
|
@@ -70,29 +100,30 @@ var parseModule = function (rule, ctx) {
|
|
70
100
|
if (rule.type === 'comment') {
|
71
101
|
var text = rule.comment.trim();
|
72
102
|
if (!text) { return parseModule; }
|
73
|
-
if (text
|
103
|
+
if (startsWith(text, MODULE_TOKEN)) {
|
74
104
|
finishCurrentModule(ctx);
|
75
|
-
ctx.currentModule = { module: text.substring(
|
105
|
+
ctx.currentModule = { module: text.substring(MODULE_TOKEN.length), tests: [] };
|
76
106
|
return parseTest;
|
77
107
|
}
|
78
|
-
if (text
|
108
|
+
if (startsWith(text, SUMMARY_TOKEN)) {
|
79
109
|
return ignoreUntilEndSummary;
|
80
110
|
}
|
81
|
-
|
111
|
+
// ignore un-recognized comments, keep looking for module header.
|
112
|
+
return parseModule;
|
82
113
|
}
|
83
|
-
parseError('Unexpected rule type "' + rule.type + '"', 'module header', rule.position);
|
114
|
+
throw parseError('Unexpected rule type "' + rule.type + '"', 'module header', rule.position);
|
84
115
|
};
|
85
116
|
|
86
117
|
|
87
118
|
var ignoreUntilEndSummary = function (rule, ctx) {
|
88
119
|
if (rule.type === 'comment') {
|
89
120
|
var text = rule.comment.trim();
|
90
|
-
if (text
|
121
|
+
if (startsWith(text, END_SUMMARY_TOKEN)) {
|
91
122
|
return parseModule;
|
92
123
|
}
|
93
124
|
return ignoreUntilEndSummary;
|
94
125
|
}
|
95
|
-
parseError('Unexpected rule type "' + rule.type + '"', 'end summary', rule.position);
|
126
|
+
throw parseError('Unexpected rule type "' + rule.type + '"', 'end summary', rule.position);
|
96
127
|
};
|
97
128
|
|
98
129
|
|
@@ -103,63 +134,63 @@ var parseTest = function (rule, ctx) {
|
|
103
134
|
if (text.match(/^-+$/)) {
|
104
135
|
return parseTest;
|
105
136
|
}
|
106
|
-
if (text
|
137
|
+
if (startsWith(text, TEST_TOKEN)) {
|
107
138
|
finishCurrentTest(ctx);
|
108
|
-
ctx.currentTest = { test: text.substring(
|
139
|
+
ctx.currentTest = { test: text.substring(TEST_TOKEN.length), assertions: [] };
|
109
140
|
return parseAssertion;
|
110
141
|
}
|
111
142
|
return parseModule(rule, ctx);
|
112
143
|
}
|
113
|
-
parseError('Unexpected rule type "' + rule.type + '"', 'test', rule.position);
|
144
|
+
throw parseError('Unexpected rule type "' + rule.type + '"', 'test', rule.position);
|
114
145
|
};
|
115
146
|
|
116
147
|
|
117
148
|
var parseAssertion = function (rule, ctx) {
|
118
149
|
if (rule.type === 'comment') {
|
119
|
-
var text = rule.comment.
|
150
|
+
var text = rule.comment.trimLeft();
|
120
151
|
if (!text) { return parseAssertion; }
|
121
|
-
if (text
|
152
|
+
if (startsWith(text, PASS_TOKEN)) {
|
122
153
|
finishCurrentAssertion(ctx);
|
123
154
|
ctx.currentAssertion = {
|
124
|
-
description: text.substring(
|
155
|
+
description: text.substring(PASS_TOKEN.length).trim() || '<no description>',
|
125
156
|
passed: true
|
126
157
|
};
|
127
158
|
return parseAssertion;
|
128
|
-
} else if (text
|
159
|
+
} else if (startsWith(text, FAIL_TOKEN)) {
|
129
160
|
finishCurrentAssertion(ctx);
|
130
|
-
var endAssertionType = text.indexOf(
|
161
|
+
var endAssertionType = text.indexOf(END_FAIL_TOKEN);
|
131
162
|
ctx.currentAssertion = {
|
132
163
|
description: text.substring(endAssertionType + 2).trim(),
|
133
164
|
passed: false,
|
134
|
-
assertionType: text.substring(
|
165
|
+
assertionType: text.substring(FAIL_TOKEN.length, endAssertionType).trim(),
|
135
166
|
};
|
136
167
|
return parseFailureDetail;
|
137
|
-
} else if (text
|
168
|
+
} else if (startsWith(text, ASSERT_TOKEN)) {
|
138
169
|
finishCurrentAssertion(ctx);
|
139
170
|
ctx.currentAssertion = {
|
140
|
-
description: text.substring(
|
171
|
+
description: text.substring(ASSERT_TOKEN.length).trim(),
|
141
172
|
assertionType: 'equal'
|
142
173
|
};
|
143
174
|
return parseAssertionOutputStart;
|
144
175
|
}
|
145
176
|
return parseTest(rule, ctx);
|
146
177
|
}
|
147
|
-
parseError('Unexpected rule type "' + rule.type + '"', 'assertion', rule.position);
|
178
|
+
throw parseError('Unexpected rule type "' + rule.type + '"', 'assertion', rule.position);
|
148
179
|
}
|
149
180
|
|
150
181
|
|
151
182
|
var parseFailureDetail = function (rule, ctx) {
|
152
183
|
if (rule.type === 'comment') {
|
153
184
|
var text = rule.comment.trim();
|
154
|
-
if (text
|
155
|
-
var startType = text.indexOf(
|
156
|
-
var endType = text.indexOf(
|
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);
|
157
188
|
var type = text.substring(startType, endType + 1);
|
158
189
|
var content = text.substring(endType + 3);
|
159
190
|
var outputOrExpected;
|
160
|
-
if (text.substring(
|
191
|
+
if (text.substring(FAILURE_DETAIL_TOKEN.length, startType) === OUTPUT_TOKEN) {
|
161
192
|
outputOrExpected = 'output';
|
162
|
-
} else if (text.substring(
|
193
|
+
} else if (text.substring(FAILURE_DETAIL_TOKEN.length, startType) === EXPECTED_TOKEN) {
|
163
194
|
outputOrExpected = 'expected';
|
164
195
|
}
|
165
196
|
if (outputOrExpected) {
|
@@ -169,7 +200,7 @@ var parseFailureDetail = function (rule, ctx) {
|
|
169
200
|
}
|
170
201
|
return parseAssertion(rule, ctx);
|
171
202
|
}
|
172
|
-
parseError('Unexpected rule type "' + rule.type + '"', 'output/expected', rule.position);
|
203
|
+
throw parseError('Unexpected rule type "' + rule.type + '"', 'output/expected', rule.position);
|
173
204
|
};
|
174
205
|
|
175
206
|
|
@@ -177,19 +208,19 @@ var parseAssertionOutputStart = function (rule, ctx) {
|
|
177
208
|
if (rule.type === 'comment') {
|
178
209
|
var text = rule.comment.trim();
|
179
210
|
if (!text) { return parseAssertionOutputStart; }
|
180
|
-
if (text ===
|
211
|
+
if (text === OUTPUT_START_TOKEN) {
|
181
212
|
ctx.currentOutputRules = [];
|
182
213
|
return parseAssertionOutput;
|
183
214
|
}
|
184
|
-
parseError('Unexpected comment "' + text + '"', 'OUTPUT', rule.position);
|
215
|
+
throw parseError('Unexpected comment "' + text + '"', 'OUTPUT', rule.position);
|
185
216
|
}
|
186
|
-
parseError('Unexpected rule type "' + rule.type + '"', 'OUTPUT', rule.position);
|
217
|
+
throw parseError('Unexpected rule type "' + rule.type + '"', 'OUTPUT', rule.position);
|
187
218
|
};
|
188
219
|
|
189
220
|
|
190
221
|
var parseAssertionOutput = function (rule, ctx) {
|
191
222
|
if (rule.type === 'comment') {
|
192
|
-
if (rule.comment.trim() ===
|
223
|
+
if (rule.comment.trim() === OUTPUT_END_TOKEN) {
|
193
224
|
ctx.currentAssertion.output = css.stringify(
|
194
225
|
{ stylesheet: { rules: ctx.currentOutputRules }});
|
195
226
|
delete ctx.currentOutputRules;
|
@@ -205,19 +236,19 @@ var parseAssertionExpectedStart = function (rule, ctx) {
|
|
205
236
|
if (rule.type === 'comment') {
|
206
237
|
var text = rule.comment.trim();
|
207
238
|
if (!text) { return parseAssertionExpectedStart; }
|
208
|
-
if (text ===
|
239
|
+
if (text === EXPECTED_START_TOKEN) {
|
209
240
|
ctx.currentExpectedRules = [];
|
210
241
|
return parseAssertionExpected;
|
211
242
|
}
|
212
|
-
parseError('Unexpected comment "' + text + '"', 'EXPECTED', rule.position);
|
243
|
+
throw parseError('Unexpected comment "' + text + '"', 'EXPECTED', rule.position);
|
213
244
|
}
|
214
|
-
parseError('Unexpected rule type "' + rule.type + '"', 'EXPECTED', rule.position);
|
245
|
+
throw parseError('Unexpected rule type "' + rule.type + '"', 'EXPECTED', rule.position);
|
215
246
|
};
|
216
247
|
|
217
248
|
|
218
249
|
var parseAssertionExpected = function (rule, ctx) {
|
219
250
|
if (rule.type === 'comment') {
|
220
|
-
if (rule.comment.trim() ===
|
251
|
+
if (rule.comment.trim() === EXPECTED_END_TOKEN) {
|
221
252
|
ctx.currentAssertion.expected = css.stringify(
|
222
253
|
{ stylesheet: { rules: ctx.currentExpectedRules }});
|
223
254
|
delete ctx.currentExpectedRules;
|
@@ -235,20 +266,22 @@ var parseEndAssertion = function (rule, ctx) {
|
|
235
266
|
if (rule.type === 'comment') {
|
236
267
|
var text = rule.comment.trim();
|
237
268
|
if (!text) { return parseEndAssertion; }
|
238
|
-
if (text ===
|
269
|
+
if (text === ASSERT_END_TOKEN) {
|
239
270
|
finishCurrentAssertion(ctx);
|
240
271
|
return parseAssertion;
|
241
272
|
}
|
242
|
-
parseError('Unexpected comment "' + text + '"', 'END_ASSERT', rule.position);
|
273
|
+
throw parseError('Unexpected comment "' + text + '"', 'END_ASSERT', rule.position);
|
243
274
|
}
|
244
|
-
parseError('Unexpected rule type "' + rule.type + '"', 'END_ASSERT', rule.position);
|
275
|
+
throw parseError('Unexpected rule type "' + rule.type + '"', 'END_ASSERT', rule.position);
|
245
276
|
};
|
246
277
|
|
247
278
|
|
248
279
|
var finishCurrentModule = function (ctx) {
|
249
280
|
finishCurrentTest(ctx);
|
250
281
|
if (ctx.currentModule) {
|
251
|
-
ctx.
|
282
|
+
var path = ctx.currentModule.module.split(MODULE_NESTING_TOKEN);
|
283
|
+
ctx.currentModule.module = _.last(path);
|
284
|
+
insertModule(path, ctx.currentModule, ctx);
|
252
285
|
delete ctx.currentModule;
|
253
286
|
}
|
254
287
|
}
|
@@ -269,3 +302,24 @@ var finishCurrentAssertion = function (ctx) {
|
|
269
302
|
delete ctx.currentAssertion;
|
270
303
|
}
|
271
304
|
}
|
305
|
+
|
306
|
+
|
307
|
+
var insertModule = function (path, module, ctx) {
|
308
|
+
if (!ctx.modules) { ctx.modules = [] };
|
309
|
+
|
310
|
+
if (path.length > 1) {
|
311
|
+
var newCtx = _.findWhere(ctx.modules, {module: path[0]});
|
312
|
+
if (!newCtx) {
|
313
|
+
newCtx = {module: path[0]};
|
314
|
+
ctx.modules.push(newCtx);
|
315
|
+
}
|
316
|
+
insertModule(path.slice(1), module, newCtx);
|
317
|
+
} else {
|
318
|
+
ctx.modules.push(module);
|
319
|
+
}
|
320
|
+
}
|
321
|
+
|
322
|
+
|
323
|
+
var startsWith = function (text, token) {
|
324
|
+
return text.substring(0, token.length) === token;
|
325
|
+
}
|
data/sass/_true.scss
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
// Susy partials
|
2
2
|
// =============
|
3
3
|
|
4
|
-
@import
|
5
|
-
@import
|
6
|
-
@import
|
7
|
-
@import
|
8
|
-
@import
|
9
|
-
@import
|
10
|
-
@import
|
4
|
+
@import 'true/settings';
|
5
|
+
@import 'true/utilities';
|
6
|
+
@import 'true/messages';
|
7
|
+
@import 'true/results';
|
8
|
+
@import 'true/modules';
|
9
|
+
@import 'true/tests';
|
10
|
+
@import 'true/assert';
|
data/sass/true/_assert.scss
CHANGED
@@ -14,8 +14,10 @@
|
|
14
14
|
$assert,
|
15
15
|
$description: ''
|
16
16
|
) {
|
17
|
-
|
18
|
-
|
17
|
+
$default: '"#{inspect($assert)}" should be truthy';
|
18
|
+
|
19
|
+
@include _true-context('assert', $description or $default);
|
20
|
+
@include _true-assert-results('assert-true', not not $assert, true);
|
19
21
|
}
|
20
22
|
|
21
23
|
/// Assert that a parameter is `false`
|
@@ -30,7 +32,9 @@
|
|
30
32
|
$assert,
|
31
33
|
$description: ''
|
32
34
|
) {
|
33
|
-
|
35
|
+
$default: '"#{inspect($assert)}" should be falsey';
|
36
|
+
|
37
|
+
@include _true-context('assert', $description or $default);
|
34
38
|
@include _true-assert-results('assert-false', $assert, false);
|
35
39
|
}
|
36
40
|
|
@@ -48,7 +52,9 @@
|
|
48
52
|
$expected,
|
49
53
|
$description: ''
|
50
54
|
) {
|
51
|
-
|
55
|
+
$default: '"#{inspect($assert)}" and "#{inspect($expected)}" should be equal';
|
56
|
+
|
57
|
+
@include _true-context('assert', $description or $default);
|
52
58
|
@include _true-assert-results('assert-equal', $assert, $expected);
|
53
59
|
}
|
54
60
|
|
@@ -66,7 +72,9 @@
|
|
66
72
|
$expected,
|
67
73
|
$description: ''
|
68
74
|
) {
|
69
|
-
|
75
|
+
$default: '"#{inspect($assert)}" and "#{inspect($expected)}" should not be equal';
|
76
|
+
|
77
|
+
@include _true-context('assert', $description or $default);
|
70
78
|
@include _true-assert-results('assert-unequal', $assert, $expected, 'unequal');
|
71
79
|
}
|
72
80
|
|
@@ -83,18 +91,21 @@
|
|
83
91
|
/// @require {mixin} _true-assert-stop
|
84
92
|
/// @require {function} _true-selector
|
85
93
|
@mixin assert(
|
86
|
-
$description
|
94
|
+
$description: ''
|
87
95
|
) {
|
96
|
+
$default: _true-context('test') or 'CSS output should match expected output';
|
97
|
+
|
88
98
|
@include _true-context('assert', $description);
|
89
99
|
@include _true-message(' ASSERT: #{$description} ', 'comments');
|
90
100
|
|
91
101
|
@content;
|
92
102
|
|
93
|
-
@include _true-update('
|
94
|
-
@include _true-context(
|
103
|
+
@include _true-update('output-to-css');
|
104
|
+
@include _true-context-pop();
|
95
105
|
@include _true-message(' END_ASSERT ', 'comments');
|
96
106
|
}
|
97
107
|
|
108
|
+
|
98
109
|
/// Describe the test content to be evaluated
|
99
110
|
/// The output will be compared against the results of the `expect()` mixin.
|
100
111
|
/// @access public
|
@@ -186,6 +197,6 @@
|
|
186
197
|
}
|
187
198
|
}
|
188
199
|
|
189
|
-
@include _true-update(
|
190
|
-
@include _true-context(
|
200
|
+
@include _true-update($result);
|
201
|
+
@include _true-context-pop();
|
191
202
|
}
|
data/sass/true/_modules.scss
CHANGED
@@ -24,15 +24,14 @@
|
|
24
24
|
/// @access private
|
25
25
|
/// @group x_private
|
26
26
|
/// @param {String} $name - Module name
|
27
|
-
/// @require {mixin} _true-reset
|
28
27
|
/// @require {mixin} _true-context
|
29
28
|
/// @require {mixin} _true-message
|
30
29
|
@mixin _true-module-start(
|
31
30
|
$name
|
32
31
|
) {
|
33
|
-
@include _true-reset(module);
|
34
32
|
@include _true-context(module, $name);
|
35
|
-
|
33
|
+
$modules: _true-context-all('module');
|
34
|
+
@include _true-message('# Module: #{_true-str-join($modules, ' :: ')}', 'comments');
|
36
35
|
|
37
36
|
$underline: '----------';
|
38
37
|
|
@@ -50,12 +49,9 @@
|
|
50
49
|
/// Module stop helper
|
51
50
|
/// @access private
|
52
51
|
/// @group x_private
|
53
|
-
/// @require {mixin} _true-reset
|
54
52
|
/// @require {mixin} _true-context
|
55
53
|
/// @require {mixin} _true-message
|
56
54
|
@mixin _true-module-stop {
|
57
|
-
@include _true-
|
58
|
-
@include _true-reset(module);
|
59
|
-
@include _true-context(module, null);
|
55
|
+
@include _true-context-pop();
|
60
56
|
@include _true-message('', 'comments');
|
61
57
|
}
|
data/sass/true/_results.scss
CHANGED
@@ -1,105 +1,17 @@
|
|
1
1
|
// Results
|
2
2
|
// =======
|
3
3
|
|
4
|
-
///
|
4
|
+
/// Results map
|
5
5
|
/// @access private
|
6
6
|
/// @group x_private
|
7
7
|
/// @type Map
|
8
|
-
$_true-results
|
8
|
+
$_true-results: (
|
9
9
|
run: 0,
|
10
10
|
pass: 0,
|
11
11
|
fail: 0,
|
12
12
|
output-to-css: 0,
|
13
13
|
);
|
14
14
|
|
15
|
-
/// Results map
|
16
|
-
/// @access private
|
17
|
-
/// @group x_private
|
18
|
-
/// @type Map
|
19
|
-
/// @require $_true-results-reset
|
20
|
-
/// @prop {Map} global [$_true-results-reset] - Global results
|
21
|
-
/// @prop {Map} module [$_true-results-reset] - Results for current module
|
22
|
-
/// @prop {Map} test [$_true-results-reset] - Results for current test
|
23
|
-
$_true-results: (
|
24
|
-
global: $_true-results-reset,
|
25
|
-
module: $_true-results-reset,
|
26
|
-
test: $_true-results-reset,
|
27
|
-
);
|
28
|
-
|
29
|
-
|
30
|
-
// Reset
|
31
|
-
// -----
|
32
|
-
|
33
|
-
/// Reset helper
|
34
|
-
/// @access private
|
35
|
-
/// @group x_private
|
36
|
-
/// @param {String} $scope - Scope to reset
|
37
|
-
/// @require $_true-results-reset
|
38
|
-
/// @require $_true-results
|
39
|
-
@mixin _true-reset(
|
40
|
-
$scope
|
41
|
-
) {
|
42
|
-
@if $scope == global {
|
43
|
-
$_true-results: (
|
44
|
-
global: $_true-results-reset,
|
45
|
-
module: $_true-results-reset,
|
46
|
-
test: $_true-results-reset,
|
47
|
-
) !global;
|
48
|
-
} @else if $scope == module {
|
49
|
-
$update: (
|
50
|
-
module: $_true-results-reset,
|
51
|
-
test: $_true-results-reset,
|
52
|
-
);
|
53
|
-
$_true-results: map-merge($_true-results, $update) !global;
|
54
|
-
} @else if $scope == test {
|
55
|
-
$update: (
|
56
|
-
test: $_true-results-reset
|
57
|
-
);
|
58
|
-
$_true-results: map-merge($_true-results, $update) !global;
|
59
|
-
} @else {
|
60
|
-
@warn "#{$scope} is not a valid scope for _true-reset().";
|
61
|
-
}
|
62
|
-
}
|
63
|
-
|
64
|
-
|
65
|
-
// Get Results
|
66
|
-
// -----------
|
67
|
-
|
68
|
-
/// Results getter
|
69
|
-
/// @access private
|
70
|
-
/// @group x_private
|
71
|
-
/// @param {String} $scope - Scope to get results from
|
72
|
-
/// @require $_true-results
|
73
|
-
@function _true-get-results(
|
74
|
-
$scope
|
75
|
-
) {
|
76
|
-
@return map-get($_true-results, $scope);
|
77
|
-
}
|
78
|
-
|
79
|
-
|
80
|
-
// Get Result
|
81
|
-
// ----------
|
82
|
-
|
83
|
-
/// Single result getter
|
84
|
-
/// @access private
|
85
|
-
/// @group x_private
|
86
|
-
/// @param {String} $scope - Scope to get result form
|
87
|
-
/// @require {function} _true-get-results
|
88
|
-
@function _true-get-result(
|
89
|
-
$scope
|
90
|
-
) {
|
91
|
-
$results: _true-get-results($scope);
|
92
|
-
$return: if(map-get($results, output-to-css) > 0, output-to-css, null);
|
93
|
-
|
94
|
-
@if map-get($results, fail) > 0 {
|
95
|
-
@return if($return, $return fail, fail);
|
96
|
-
} @else if map-get($results, pass) > 0 {
|
97
|
-
@return if($return, $return pass, pass);
|
98
|
-
} @else {
|
99
|
-
@return $return;
|
100
|
-
}
|
101
|
-
}
|
102
|
-
|
103
15
|
|
104
16
|
// Update
|
105
17
|
// ------
|
@@ -107,30 +19,14 @@ $_true-results: (
|
|
107
19
|
/// Update results
|
108
20
|
/// @access private
|
109
21
|
/// @group x_private
|
110
|
-
/// @param {String} $
|
111
|
-
/// @param {List} $results - Results
|
112
|
-
/// @require {function} _true-get-results
|
22
|
+
/// @param {String} $result - Result (pass/fail/output-to-css)
|
113
23
|
/// @require {function} _true-map-increment
|
114
24
|
/// @require $_true-results
|
115
|
-
@mixin _true-update(
|
116
|
-
$
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
$update: (run: 1);
|
121
|
-
|
122
|
-
@if $scope == global {
|
123
|
-
$update: _true-get-results(module);
|
124
|
-
} @else {
|
125
|
-
@each $result in $results {
|
126
|
-
@if $result {
|
127
|
-
$update: map-merge($update, ($result: 1));
|
128
|
-
}
|
129
|
-
}
|
130
|
-
}
|
131
|
-
|
132
|
-
$scope: ($scope: _true-map-increment($current, $update));
|
133
|
-
$_true-results: map-merge($_true-results, $scope) !global;
|
25
|
+
@mixin _true-update($result) {
|
26
|
+
$_true-results: _true-map-increment($_true-results, (
|
27
|
+
run: 1,
|
28
|
+
$result: 1,
|
29
|
+
)) !global;
|
134
30
|
}
|
135
31
|
|
136
32
|
|
@@ -148,11 +44,10 @@ $_true-results: (
|
|
148
44
|
$scope: 'test',
|
149
45
|
$lines: 'single'
|
150
46
|
) {
|
151
|
-
$
|
152
|
-
$
|
153
|
-
$
|
154
|
-
$
|
155
|
-
$output-to-css: map-get($results, 'output-to-css');
|
47
|
+
$run: map-get($_true-results, 'run');
|
48
|
+
$pass: map-get($_true-results, 'pass');
|
49
|
+
$fail: map-get($_true-results, 'fail');
|
50
|
+
$output-to-css: map-get($_true-results, 'output-to-css');
|
156
51
|
|
157
52
|
$items: null;
|
158
53
|
$message: null;
|
@@ -160,7 +55,7 @@ $_true-results: (
|
|
160
55
|
@if $scope == 'global' or $scope == 'module' {
|
161
56
|
$items: 'Tests';
|
162
57
|
} @else if $scope == 'test' {
|
163
|
-
$items: Assertions;
|
58
|
+
$items: 'Assertions';
|
164
59
|
}
|
165
60
|
|
166
61
|
@if $lines == 'single' {
|
@@ -187,13 +82,13 @@ $_true-results: (
|
|
187
82
|
@mixin report(
|
188
83
|
$terminal: $true-terminal-output
|
189
84
|
) {
|
190
|
-
$message: _true-report-message(global, multiple);
|
191
|
-
@include _true-message('# SUMMARY ----------', comments);
|
192
|
-
@include _true-message($message, comments);
|
193
|
-
@include _true-message('--------------------', comments);
|
85
|
+
$message: _true-report-message('global', 'multiple');
|
86
|
+
@include _true-message('# SUMMARY ----------', 'comments');
|
87
|
+
@include _true-message($message, 'comments');
|
88
|
+
@include _true-message('--------------------', 'comments');
|
194
89
|
|
195
90
|
@if $terminal {
|
196
|
-
$message: _true-report-message(global, single);
|
197
|
-
@include _true-message($message, debug);
|
91
|
+
$message: _true-report-message('global', 'single');
|
92
|
+
@include _true-message($message, 'debug');
|
198
93
|
}
|
199
94
|
}
|
data/sass/true/_settings.scss
CHANGED
@@ -18,11 +18,7 @@ $true-terminal-output: true !default;
|
|
18
18
|
/// @prop {String} module [null]
|
19
19
|
/// @prop {String} test [null]
|
20
20
|
/// @prop {String} assert [null]
|
21
|
-
$_true-context: (
|
22
|
-
module: null,
|
23
|
-
test: null,
|
24
|
-
assert: null,
|
25
|
-
);
|
21
|
+
$_true-context: ();
|
26
22
|
|
27
23
|
/// Update the current context
|
28
24
|
/// @access private
|
@@ -34,7 +30,15 @@ $_true-context: (
|
|
34
30
|
$scope,
|
35
31
|
$name
|
36
32
|
) {
|
37
|
-
$_true-context:
|
33
|
+
$_true-context: append($_true-context, ($scope, $name)) !global;
|
34
|
+
}
|
35
|
+
|
36
|
+
@mixin _true-context-pop() {
|
37
|
+
$new: ();
|
38
|
+
@for $i from 1 to length($_true-context) {
|
39
|
+
$new: append($new, nth($_true-context, $i));
|
40
|
+
}
|
41
|
+
$_true-context: $new !global;
|
38
42
|
}
|
39
43
|
|
40
44
|
/// Get information on current context
|
@@ -45,5 +49,31 @@ $_true-context: (
|
|
45
49
|
@function _true-context(
|
46
50
|
$scope
|
47
51
|
) {
|
48
|
-
@
|
52
|
+
@for $i from length($_true-context) through 1 {
|
53
|
+
$entry: nth($_true-context, $i);
|
54
|
+
$entry-scope: nth($entry, 1);
|
55
|
+
@if $entry-scope == $scope {
|
56
|
+
@return nth($entry, 2);
|
57
|
+
}
|
58
|
+
}
|
59
|
+
@return null;
|
60
|
+
}
|
61
|
+
|
62
|
+
/// Get list of context names
|
63
|
+
/// @access private
|
64
|
+
/// @group x_private
|
65
|
+
/// @param {String} $scope - Either `module`, `test` or `assert`
|
66
|
+
/// @return {List}
|
67
|
+
@function _true-context-all(
|
68
|
+
$scope
|
69
|
+
) {
|
70
|
+
$list: ();
|
71
|
+
@for $i from 1 through length($_true-context) {
|
72
|
+
$entry: nth($_true-context, $i);
|
73
|
+
$entry-scope: nth($entry, 1);
|
74
|
+
@if $entry-scope == $scope {
|
75
|
+
$list: append($list, nth($entry, 2));
|
76
|
+
}
|
77
|
+
}
|
78
|
+
@return $list;
|
49
79
|
}
|
data/sass/true/_tests.scss
CHANGED
@@ -25,14 +25,12 @@
|
|
25
25
|
/// @access private
|
26
26
|
/// @group x_private
|
27
27
|
/// @param {String} $name - Test name
|
28
|
-
/// @require {mixin} _true-reset
|
29
28
|
/// @require {mixin} _true-context
|
30
29
|
/// @require {mixin} _true-message
|
31
30
|
@mixin _true-test-start(
|
32
31
|
$name
|
33
32
|
) {
|
34
|
-
@include _true-
|
35
|
-
@include _true-context(test, $name);
|
33
|
+
@include _true-context('test', $name);
|
36
34
|
@include _true-message('Test: #{$name}', 'comments');
|
37
35
|
}
|
38
36
|
|
@@ -43,13 +41,10 @@
|
|
43
41
|
/// Test stop helper
|
44
42
|
/// @access private
|
45
43
|
/// @group x_private
|
46
|
-
/// @require {mixin} _true-reset
|
47
44
|
/// @require {mixin} _true-context
|
48
45
|
/// @require {mixin} _true-message
|
49
46
|
/// @require {function} _true-get-result
|
50
47
|
@mixin _true-test-stop {
|
51
|
-
@include _true-
|
52
|
-
@include _true-reset(test);
|
53
|
-
@include _true-context(test, null);
|
48
|
+
@include _true-context-pop();
|
54
49
|
@include _true-message('', 'comments');
|
55
50
|
}
|
data/sass/true/_utilities.scss
CHANGED
@@ -37,7 +37,7 @@
|
|
37
37
|
$strings: ();
|
38
38
|
$found-at: str-index($string, $substring);
|
39
39
|
@while $found-at {
|
40
|
-
$strings: append($strings, if($found-at > 1, str-slice($string, 1, $found-at - 1),
|
40
|
+
$strings: append($strings, if($found-at > 1, str-slice($string, 1, $found-at - 1), ''));
|
41
41
|
$string: str-slice($string, $found-at + str-length($substring));
|
42
42
|
$found-at: str-index($string, $substring);
|
43
43
|
}
|
@@ -45,6 +45,31 @@
|
|
45
45
|
@return $strings;
|
46
46
|
}
|
47
47
|
|
48
|
+
/// Join a list of strings
|
49
|
+
/// @access private
|
50
|
+
/// @group x_private
|
51
|
+
/// @param {List} $list - List to join
|
52
|
+
/// @param {String} $separator - Separator
|
53
|
+
/// @return {String} - Joined string
|
54
|
+
@function _true-str-join(
|
55
|
+
$list,
|
56
|
+
$separator
|
57
|
+
) {
|
58
|
+
$length: length($list);
|
59
|
+
|
60
|
+
@if ($length == 0) {
|
61
|
+
@return '';
|
62
|
+
}
|
63
|
+
|
64
|
+
$result: nth($list, 1);
|
65
|
+
@if $length > 1 {
|
66
|
+
@for $index from 2 through $length {
|
67
|
+
$result: $result + $separator + nth($list, $index);
|
68
|
+
}
|
69
|
+
}
|
70
|
+
@return $result;
|
71
|
+
}
|
72
|
+
|
48
73
|
|
49
74
|
/// Check for strict equality
|
50
75
|
/// @access private
|
@@ -53,9 +78,9 @@
|
|
53
78
|
/// @param {*} $two - Second value
|
54
79
|
/// @return {Bool}
|
55
80
|
@function _true-is-equal($one, $two) {
|
56
|
-
@if type-of($one) == number and type-of($two) == number {
|
81
|
+
@if type-of($one) == 'number' and type-of($two) == 'number' {
|
57
82
|
@if unit($one) == unit($two) {
|
58
|
-
@return $one == $two;
|
83
|
+
@return inspect($one) == inspect($two);
|
59
84
|
} @else {
|
60
85
|
@return false;
|
61
86
|
}
|