UNPKG

14.5 kBJavaScriptView Raw
1"use strict";
2
3var resolve = require('resolve');
4var path = require('path');
5
6var testFolder = path.relative(process.cwd(), path.dirname(resolve.sync('@less/test-data')));
7var lessFolder = path.join(testFolder, 'less');
8
9module.exports = function(grunt) {
10 grunt.option("stack", true);
11
12 // Report the elapsed execution time of tasks.
13 require("time-grunt")(grunt);
14
15 var git = require("git-rev");
16
17 // Sauce Labs browser
18 var browsers = [
19 // Desktop browsers
20 {
21 browserName: "chrome",
22 version: "latest",
23 platform: "Windows 7"
24 },
25 {
26 browserName: "firefox",
27 version: "latest",
28 platform: "Linux"
29 },
30 {
31 browserName: "safari",
32 version: "9",
33 platform: "OS X 10.11"
34 },
35 {
36 browserName: "internet explorer",
37 version: "8",
38 platform: "Windows XP"
39 },
40 {
41 browserName: "internet explorer",
42 version: "11",
43 platform: "Windows 8.1"
44 },
45 {
46 browserName: "edge",
47 version: "13",
48 platform: "Windows 10"
49 },
50 // Mobile browsers
51 {
52 browserName: "ipad",
53 deviceName: "iPad Air Simulator",
54 deviceOrientation: "portrait",
55 version: "8.4",
56 platform: "OS X 10.9"
57 },
58 {
59 browserName: "iphone",
60 deviceName: "iPhone 5 Simulator",
61 deviceOrientation: "portrait",
62 version: "9.3",
63 platform: "OS X 10.11"
64 },
65 {
66 browserName: "android",
67 deviceName: "Google Nexus 7 HD Emulator",
68 deviceOrientation: "portrait",
69 version: "4.4",
70 platform: "Linux"
71 }
72 ];
73
74 var sauceJobs = {};
75
76 var browserTests = [
77 "filemanager-plugin",
78 "visitor-plugin",
79 "global-vars",
80 "modify-vars",
81 "production",
82 "rootpath-relative",
83 "rootpath-rewrite-urls",
84 "rootpath",
85 "relative-urls",
86 "rewrite-urls",
87 "browser",
88 "no-js-errors",
89 "legacy"
90 ];
91
92 function makeJob(testName) {
93 sauceJobs[testName] = {
94 options: {
95 urls:
96 testName === "all"
97 ? browserTests.map(function(name) {
98 return (
99 "http://localhost:8081/tmp/browser/test-runner-" +
100 name +
101 ".html"
102 );
103 })
104 : [
105 "http://localhost:8081/tmp/browser/test-runner-" +
106 testName +
107 ".html"
108 ],
109 testname:
110 testName === "all" ? "Unit Tests for Less.js" : testName,
111 browsers: browsers,
112 public: "public",
113 recordVideo: false,
114 videoUploadOnPass: false,
115 recordScreenshots: process.env.TRAVIS_BRANCH !== "master",
116 build:
117 process.env.TRAVIS_BRANCH === "master"
118 ? process.env.TRAVIS_JOB_ID
119 : undefined,
120 tags: [
121 process.env.TRAVIS_BUILD_NUMBER,
122 process.env.TRAVIS_PULL_REQUEST,
123 process.env.TRAVIS_BRANCH
124 ],
125 statusCheckAttempts: -1,
126 sauceConfig: {
127 "idle-timeout": 100
128 },
129 throttled: 5,
130 onTestComplete: function(result, callback) {
131 // Called after a unit test is done, per page, per browser
132 // 'result' param is the object returned by the test framework's reporter
133 // 'callback' is a Node.js style callback function. You must invoke it after you
134 // finish your work.
135 // Pass a non-null value as the callback's first parameter if you want to throw an
136 // exception. If your function is synchronous you can also throw exceptions
137 // directly.
138 // Passing true or false as the callback's second parameter passes or fails the
139 // test. Passing undefined does not alter the test result. Please note that this
140 // only affects the grunt task's result. You have to explicitly update the Sauce
141 // Labs job's status via its REST API, if you want so.
142
143 // This should be the encrypted value in Travis
144 var user = process.env.SAUCE_USERNAME;
145 var pass = process.env.SAUCE_ACCESS_KEY;
146
147 git.short(function(hash) {
148 require("phin")(
149 {
150 method: "PUT",
151 url: [
152 "https://saucelabs.com/rest/v1",
153 user,
154 "jobs",
155 result.job_id
156 ].join("/"),
157 auth: { user: user, pass: pass },
158 data: {
159 passed: result.passed,
160 build: "build-" + hash
161 }
162 },
163 function(error, response) {
164 if (error) {
165 console.log(error);
166 callback(error);
167 } else if (response.statusCode !== 200) {
168 console.log(response);
169 callback(
170 new Error("Unexpected response status")
171 );
172 } else {
173 callback(null, result.passed);
174 }
175 }
176 );
177 });
178 }
179 }
180 };
181 }
182
183 // Make the SauceLabs jobs
184 ["all"].concat(browserTests).map(makeJob);
185
186 var path = require('path');
187
188 // Handle async / await in Rollup build for tests
189 const tsNodeRuntime = path.resolve(path.join('node_modules', '.bin', 'ts-node'));
190 const crossEnv = path.resolve(path.join('node_modules', '.bin', 'cross-env'));
191
192 // Project configuration.
193 grunt.initConfig({
194 shell: {
195 options: {
196 stdout: true,
197 failOnError: true,
198 execOptions: {
199 maxBuffer: Infinity
200 }
201 },
202 build: {
203 command: [
204 /** Browser runtime */
205 "node build/rollup.js --dist",
206 /** Copy to repo root */
207 "npm run copy:root",
208 /** Node.js runtime */
209 "npm run build"
210 ].join(" && ")
211 },
212 testbuild: {
213 command: [
214 "npm run build",
215 "node build/rollup.js --browser --out=./tmp/browser/less.min.js"
216 ].join(" && ")
217 },
218 testcjs: {
219 command: "npm run build"
220 },
221 testbrowser: {
222 command: "node build/rollup.js --browser --out=./tmp/browser/less.min.js"
223 },
224 test: {
225 command: [
226 // https://github.com/TypeStrong/ts-node/issues/693#issuecomment-848907036
227 crossEnv + " TS_NODE_SCOPE=true",
228 tsNodeRuntime + " test/test-es6.ts",
229 "node test/index.js"
230 ].join(' && ')
231 },
232 generatebrowser: {
233 command: 'node test/browser/generator/generate.js'
234 },
235 runbrowser: {
236 command: 'node test/browser/generator/runner.js'
237 },
238 benchmark: {
239 command: "node benchmark/index.js"
240 },
241 opts: {
242 // test running with all current options (using `opts` since `options` means something already)
243 command: [
244 // @TODO: make this more thorough
245 // CURRENT OPTIONS
246 `node bin/lessc --ie-compat ${lessFolder}/_main/lazy-eval.less tmp/lazy-eval.css`,
247 // --math
248 `node bin/lessc --math=always ${lessFolder}/_main/lazy-eval.less tmp/lazy-eval.css`,
249 `node bin/lessc --math=parens-division ${lessFolder}/_main/lazy-eval.less tmp/lazy-eval.css`,
250 `node bin/lessc --math=parens ${lessFolder}/_main/lazy-eval.less tmp/lazy-eval.css`,
251 `node bin/lessc --math=strict ${lessFolder}/_main/lazy-eval.less tmp/lazy-eval.css`,
252 `node bin/lessc --math=strict-legacy ${lessFolder}/_main/lazy-eval.less tmp/lazy-eval.css`,
253
254 // DEPRECATED OPTIONS
255 // --strict-math
256 `node bin/lessc --strict-math=on ${lessFolder}/_main/lazy-eval.less tmp/lazy-eval.css`
257 ].join(" && ")
258 },
259 plugin: {
260 command: [
261 `node bin/lessc --clean-css="--s1 --advanced" ${lessFolder}/_main/lazy-eval.less tmp/lazy-eval.css`,
262 "cd lib",
263 `node ../bin/lessc --clean-css="--s1 --advanced" ../${lessFolder}/_main/lazy-eval.less ../tmp/lazy-eval.css`,
264 `node ../bin/lessc --source-map=lazy-eval.css.map --autoprefix ../${lessFolder}/_main/lazy-eval.less ../tmp/lazy-eval.css`,
265 "cd ..",
266 // Test multiple plugins
267 `node bin/lessc --plugin=clean-css="--s1 --advanced" --plugin=autoprefix="ie 11,Edge >= 13,Chrome >= 47,Firefox >= 45,iOS >= 9.2,Safari >= 9" ${lessFolder}/_main/lazy-eval.less tmp/lazy-eval.css`
268 ].join(" && ")
269 },
270 "sourcemap-test": {
271 // quoted value doesn't seem to get picked up by time-grunt, or isn't output, at least; maybe just "sourcemap" is fine?
272 command: [
273 `node bin/lessc --source-map=test/sourcemaps/maps/import-map.map ${lessFolder}/_main/import.less test/sourcemaps/import.css`,
274 `node bin/lessc --source-map ${lessFolder}/sourcemaps/basic.less test/sourcemaps/basic.css`
275 ].join(" && ")
276 }
277 },
278
279 eslint: {
280 target: [
281 "test/**/*.js",
282 "src/less*/**/*.js",
283 "!test/less/errors/plugin/plugin-error.js"
284 ],
285 options: {
286 configFile: ".eslintrc.json",
287 fix: true
288 }
289 },
290
291 connect: {
292 server: {
293 options: {
294 port: 8081
295 }
296 }
297 },
298
299 "saucelabs-mocha": sauceJobs,
300
301 // Clean the version of less built for the tests
302 clean: {
303 test: ["test/browser/less.js", "tmp", "test/less-bom"],
304 "sourcemap-test": [
305 "test/sourcemaps/*.css",
306 "test/sourcemaps/*.map"
307 ],
308 sauce_log: ["sc_*.log"]
309 }
310 });
311
312 // Load these plugins to provide the necessary tasks
313 grunt.loadNpmTasks("grunt-saucelabs");
314
315 require("jit-grunt")(grunt);
316
317 // by default, run tests
318 grunt.registerTask("default", ["test"]);
319
320 // Release
321 grunt.registerTask("dist", [
322 "shell:build"
323 ]);
324
325 // Create the browser version of less.js
326 grunt.registerTask("browsertest-lessjs", [
327 "shell:testbrowser"
328 ]);
329
330 // Run all browser tests
331 grunt.registerTask("browsertest", [
332 "browsertest-lessjs",
333 "connect",
334 "shell:runbrowser"
335 ]);
336
337 // setup a web server to run the browser tests in a browser rather than phantom
338 grunt.registerTask("browsertest-server", [
339 "browsertest-lessjs",
340 "shell:generatebrowser",
341 "connect::keepalive"
342 ]);
343
344 var previous_force_state = grunt.option("force");
345
346 grunt.registerTask("force", function(set) {
347 if (set === "on") {
348 grunt.option("force", true);
349 } else if (set === "off") {
350 grunt.option("force", false);
351 } else if (set === "restore") {
352 grunt.option("force", previous_force_state);
353 }
354 });
355
356 grunt.registerTask("sauce", [
357 "browsertest-lessjs",
358 "shell:generatebrowser",
359 "connect",
360 "sauce-after-setup"
361 ]);
362
363 grunt.registerTask("sauce-after-setup", [
364 "saucelabs-mocha:all",
365 "clean:sauce_log"
366 ]);
367
368 var testTasks = [
369 "clean",
370 "eslint",
371 "shell:testbuild",
372 "shell:test",
373 "shell:opts",
374 "shell:plugin",
375 "connect",
376 "shell:runbrowser"
377 ];
378
379 if (
380 isNaN(Number(process.env.TRAVIS_PULL_REQUEST, 10)) &&
381 (process.env.TRAVIS_BRANCH === "master")
382 ) {
383 testTasks.push("force:on");
384 testTasks.push("sauce-after-setup");
385 testTasks.push("force:off");
386 }
387
388 // Run all tests
389 grunt.registerTask("test", testTasks);
390
391 // Run shell option tests (includes deprecated options)
392 grunt.registerTask("shell-options", ["shell:opts"]);
393
394 // Run shell plugin test
395 grunt.registerTask("shell-plugin", ["shell:plugin"]);
396
397 // Quickly build and run Node tests
398 grunt.registerTask("quicktest", [
399 "shell:testcjs",
400 "shell:test"
401 ]);
402
403 // generate a good test environment for testing sourcemaps
404 grunt.registerTask("sourcemap-test", [
405 "clean:sourcemap-test",
406 "shell:build:lessc",
407 "shell:sourcemap-test",
408 "connect::keepalive"
409 ]);
410
411 // Run benchmark
412 grunt.registerTask("benchmark", [
413 "shell:testcjs",
414 "shell:benchmark"
415 ]);
416};