421 lines
14 KiB
JavaScript
421 lines
14 KiB
JavaScript
"use strict";
|
|
|
|
var resolve = require('resolve');
|
|
var path = require('path');
|
|
|
|
var testFolder = path.relative(process.cwd(), path.dirname(resolve.sync('@less/test-data')));
|
|
var lessFolder = path.join(testFolder, 'less');
|
|
|
|
module.exports = function(grunt) {
|
|
grunt.option("stack", true);
|
|
|
|
// Report the elapsed execution time of tasks.
|
|
require("time-grunt")(grunt);
|
|
|
|
var COMPRESS_FOR_TESTS = false;
|
|
var git = require("git-rev");
|
|
|
|
// Sauce Labs browser
|
|
var browsers = [
|
|
// Desktop browsers
|
|
{
|
|
browserName: "chrome",
|
|
version: "latest",
|
|
platform: "Windows 7"
|
|
},
|
|
{
|
|
browserName: "firefox",
|
|
version: "latest",
|
|
platform: "Linux"
|
|
},
|
|
{
|
|
browserName: "safari",
|
|
version: "9",
|
|
platform: "OS X 10.11"
|
|
},
|
|
{
|
|
browserName: "internet explorer",
|
|
version: "8",
|
|
platform: "Windows XP"
|
|
},
|
|
{
|
|
browserName: "internet explorer",
|
|
version: "11",
|
|
platform: "Windows 8.1"
|
|
},
|
|
{
|
|
browserName: "edge",
|
|
version: "13",
|
|
platform: "Windows 10"
|
|
},
|
|
// Mobile browsers
|
|
{
|
|
browserName: "ipad",
|
|
deviceName: "iPad Air Simulator",
|
|
deviceOrientation: "portrait",
|
|
version: "8.4",
|
|
platform: "OS X 10.9"
|
|
},
|
|
{
|
|
browserName: "iphone",
|
|
deviceName: "iPhone 5 Simulator",
|
|
deviceOrientation: "portrait",
|
|
version: "9.3",
|
|
platform: "OS X 10.11"
|
|
},
|
|
{
|
|
browserName: "android",
|
|
deviceName: "Google Nexus 7 HD Emulator",
|
|
deviceOrientation: "portrait",
|
|
version: "4.4",
|
|
platform: "Linux"
|
|
}
|
|
];
|
|
|
|
var sauceJobs = {};
|
|
|
|
var browserTests = [
|
|
"filemanager-plugin",
|
|
"visitor-plugin",
|
|
"global-vars",
|
|
"modify-vars",
|
|
"production",
|
|
"rootpath-relative",
|
|
"rootpath-rewrite-urls",
|
|
"rootpath",
|
|
"relative-urls",
|
|
"rewrite-urls",
|
|
"browser",
|
|
"no-js-errors",
|
|
"legacy"
|
|
];
|
|
|
|
function makeJob(testName) {
|
|
sauceJobs[testName] = {
|
|
options: {
|
|
urls:
|
|
testName === "all"
|
|
? browserTests.map(function(name) {
|
|
return (
|
|
"http://localhost:8081/tmp/browser/test-runner-" +
|
|
name +
|
|
".html"
|
|
);
|
|
})
|
|
: [
|
|
"http://localhost:8081/tmp/browser/test-runner-" +
|
|
testName +
|
|
".html"
|
|
],
|
|
testname:
|
|
testName === "all" ? "Unit Tests for Less.js" : testName,
|
|
browsers: browsers,
|
|
public: "public",
|
|
recordVideo: false,
|
|
videoUploadOnPass: false,
|
|
recordScreenshots: process.env.TRAVIS_BRANCH !== "master",
|
|
build:
|
|
process.env.TRAVIS_BRANCH === "master"
|
|
? process.env.TRAVIS_JOB_ID
|
|
: undefined,
|
|
tags: [
|
|
process.env.TRAVIS_BUILD_NUMBER,
|
|
process.env.TRAVIS_PULL_REQUEST,
|
|
process.env.TRAVIS_BRANCH
|
|
],
|
|
statusCheckAttempts: -1,
|
|
sauceConfig: {
|
|
"idle-timeout": 100
|
|
},
|
|
throttled: 5,
|
|
onTestComplete: function(result, callback) {
|
|
// Called after a unit test is done, per page, per browser
|
|
// 'result' param is the object returned by the test framework's reporter
|
|
// 'callback' is a Node.js style callback function. You must invoke it after you
|
|
// finish your work.
|
|
// Pass a non-null value as the callback's first parameter if you want to throw an
|
|
// exception. If your function is synchronous you can also throw exceptions
|
|
// directly.
|
|
// Passing true or false as the callback's second parameter passes or fails the
|
|
// test. Passing undefined does not alter the test result. Please note that this
|
|
// only affects the grunt task's result. You have to explicitly update the Sauce
|
|
// Labs job's status via its REST API, if you want so.
|
|
|
|
// This should be the encrypted value in Travis
|
|
var user = process.env.SAUCE_USERNAME;
|
|
var pass = process.env.SAUCE_ACCESS_KEY;
|
|
|
|
git.short(function(hash) {
|
|
require("phin")(
|
|
{
|
|
method: "PUT",
|
|
url: [
|
|
"https://saucelabs.com/rest/v1",
|
|
user,
|
|
"jobs",
|
|
result.job_id
|
|
].join("/"),
|
|
auth: { user: user, pass: pass },
|
|
data: {
|
|
passed: result.passed,
|
|
build: "build-" + hash
|
|
}
|
|
},
|
|
function(error, response) {
|
|
if (error) {
|
|
console.log(error);
|
|
callback(error);
|
|
} else if (response.statusCode !== 200) {
|
|
console.log(response);
|
|
callback(
|
|
new Error("Unexpected response status")
|
|
);
|
|
} else {
|
|
callback(null, result.passed);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
// Make the SauceLabs jobs
|
|
["all"].concat(browserTests).map(makeJob);
|
|
|
|
var semver = require('semver');
|
|
var path = require('path');
|
|
|
|
// Handle async / await in Rollup build for tests
|
|
// Remove this when Node 6 is no longer supported for the build/test process
|
|
const nodeVersion = semver.major(process.versions.node);
|
|
const tsNodeRuntime = path.resolve(path.join('node_modules', '.bin', 'ts-node'));
|
|
let scriptRuntime = 'node';
|
|
if (nodeVersion < 8) {
|
|
scriptRuntime = tsNodeRuntime;
|
|
}
|
|
|
|
// Project configuration.
|
|
grunt.initConfig({
|
|
shell: {
|
|
options: {
|
|
stdout: true,
|
|
failOnError: true,
|
|
execOptions: {
|
|
maxBuffer: Infinity
|
|
}
|
|
},
|
|
build: {
|
|
command: [
|
|
/** Browser runtime */
|
|
scriptRuntime + " build/rollup.js --dist",
|
|
/** Copy to repo root */
|
|
"npm run copy:root",
|
|
/** Node.js runtime */
|
|
"npm run build"
|
|
].join(" && ")
|
|
},
|
|
testbuild: {
|
|
command: [
|
|
"npm run build",
|
|
scriptRuntime + " build/rollup.js --browser --out=./tmp/browser/less.min.js"
|
|
].join(" && ")
|
|
},
|
|
testcjs: {
|
|
command: "npm run build"
|
|
},
|
|
testbrowser: {
|
|
command: scriptRuntime + " build/rollup.js --browser --out=./tmp/browser/less.min.js"
|
|
},
|
|
test: {
|
|
command: [
|
|
tsNodeRuntime + " test/test-es6.ts",
|
|
"node test/index.js"
|
|
].join(' && ')
|
|
},
|
|
generatebrowser: {
|
|
command: 'node test/browser/generator/generate.js'
|
|
},
|
|
runbrowser: {
|
|
command: 'node test/browser/generator/runner.js'
|
|
},
|
|
benchmark: {
|
|
command: "node benchmark/index.js"
|
|
},
|
|
opts: {
|
|
// test running with all current options (using `opts` since `options` means something already)
|
|
command: [
|
|
// @TODO: make this more thorough
|
|
// CURRENT OPTIONS
|
|
`node bin/lessc --ie-compat ${lessFolder}/_main/lazy-eval.less tmp/lazy-eval.css`,
|
|
// --math
|
|
`node bin/lessc --math=always ${lessFolder}/_main/lazy-eval.less tmp/lazy-eval.css`,
|
|
`node bin/lessc --math=parens-division ${lessFolder}/_main/lazy-eval.less tmp/lazy-eval.css`,
|
|
`node bin/lessc --math=parens ${lessFolder}/_main/lazy-eval.less tmp/lazy-eval.css`,
|
|
`node bin/lessc --math=strict ${lessFolder}/_main/lazy-eval.less tmp/lazy-eval.css`,
|
|
`node bin/lessc --math=strict-legacy ${lessFolder}/_main/lazy-eval.less tmp/lazy-eval.css`,
|
|
|
|
// DEPRECATED OPTIONS
|
|
// --strict-math
|
|
`node bin/lessc --strict-math=on ${lessFolder}/_main/lazy-eval.less tmp/lazy-eval.css`
|
|
].join(" && ")
|
|
},
|
|
plugin: {
|
|
command: [
|
|
`node bin/lessc --clean-css="--s1 --advanced" ${lessFolder}/_main/lazy-eval.less tmp/lazy-eval.css`,
|
|
"cd lib",
|
|
`node ../bin/lessc --clean-css="--s1 --advanced" ../${lessFolder}/_main/lazy-eval.less ../tmp/lazy-eval.css`,
|
|
"cd ..",
|
|
// Test multiple plugins
|
|
`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`
|
|
].join(" && ")
|
|
},
|
|
"sourcemap-test": {
|
|
// quoted value doesn't seem to get picked up by time-grunt, or isn't output, at least; maybe just "sourcemap" is fine?
|
|
command: [
|
|
`node bin/lessc --source-map=test/sourcemaps/maps/import-map.map ${lessFolder}/_main/import.less test/sourcemaps/import.css`,
|
|
`node bin/lessc --source-map ${lessFolder}/sourcemaps/basic.less test/sourcemaps/basic.css`
|
|
].join(" && ")
|
|
}
|
|
},
|
|
|
|
eslint: {
|
|
target: [
|
|
"test/**/*.js",
|
|
"lib/less*/**/*.js",
|
|
"!test/less/errors/plugin/plugin-error.js"
|
|
],
|
|
options: {
|
|
configFile: ".eslintrc.json",
|
|
fix: true
|
|
}
|
|
},
|
|
|
|
connect: {
|
|
server: {
|
|
options: {
|
|
port: 8081
|
|
}
|
|
}
|
|
},
|
|
|
|
"saucelabs-mocha": sauceJobs,
|
|
|
|
// Clean the version of less built for the tests
|
|
clean: {
|
|
test: ["test/browser/less.js", "tmp", "test/less-bom"],
|
|
"sourcemap-test": [
|
|
"test/sourcemaps/*.css",
|
|
"test/sourcemaps/*.map"
|
|
],
|
|
sauce_log: ["sc_*.log"]
|
|
}
|
|
});
|
|
|
|
// Load these plugins to provide the necessary tasks
|
|
grunt.loadNpmTasks("grunt-saucelabs");
|
|
|
|
require("jit-grunt")(grunt);
|
|
|
|
// by default, run tests
|
|
grunt.registerTask("default", ["test"]);
|
|
|
|
// Release
|
|
grunt.registerTask("dist", [
|
|
"shell:build"
|
|
]);
|
|
|
|
// Create the browser version of less.js
|
|
grunt.registerTask("browsertest-lessjs", [
|
|
"shell:testbrowser"
|
|
]);
|
|
|
|
// Run all browser tests
|
|
grunt.registerTask("browsertest", [
|
|
"browsertest-lessjs",
|
|
"connect",
|
|
"shell:runbrowser"
|
|
]);
|
|
|
|
// setup a web server to run the browser tests in a browser rather than phantom
|
|
grunt.registerTask("browsertest-server", [
|
|
"browsertest-lessjs",
|
|
"shell:generatebrowser",
|
|
"connect::keepalive"
|
|
]);
|
|
|
|
var previous_force_state = grunt.option("force");
|
|
|
|
grunt.registerTask("force", function(set) {
|
|
if (set === "on") {
|
|
grunt.option("force", true);
|
|
} else if (set === "off") {
|
|
grunt.option("force", false);
|
|
} else if (set === "restore") {
|
|
grunt.option("force", previous_force_state);
|
|
}
|
|
});
|
|
|
|
grunt.registerTask("sauce", [
|
|
"browsertest-lessjs",
|
|
"shell:generatebrowser",
|
|
"connect",
|
|
"sauce-after-setup"
|
|
]);
|
|
|
|
grunt.registerTask("sauce-after-setup", [
|
|
"saucelabs-mocha:all",
|
|
"clean:sauce_log"
|
|
]);
|
|
|
|
var testTasks = [
|
|
"clean",
|
|
"eslint",
|
|
"shell:testbuild",
|
|
"shell:test",
|
|
"shell:opts",
|
|
"shell:plugin",
|
|
"connect",
|
|
"shell:runbrowser"
|
|
];
|
|
|
|
if (
|
|
isNaN(Number(process.env.TRAVIS_PULL_REQUEST, 10)) &&
|
|
(process.env.TRAVIS_BRANCH === "master")
|
|
) {
|
|
testTasks.push("force:on");
|
|
testTasks.push("sauce-after-setup");
|
|
testTasks.push("force:off");
|
|
}
|
|
|
|
// Run all tests
|
|
grunt.registerTask("test", testTasks);
|
|
|
|
// Run shell option tests (includes deprecated options)
|
|
grunt.registerTask("shell-options", ["shell:opts"]);
|
|
|
|
// Run shell plugin test
|
|
grunt.registerTask("shell-plugin", ["shell:plugin"]);
|
|
|
|
// Quickly build and run Node tests
|
|
grunt.registerTask("quicktest", [
|
|
"shell:testcjs",
|
|
"shell:test"
|
|
]);
|
|
|
|
// generate a good test environment for testing sourcemaps
|
|
grunt.registerTask("sourcemap-test", [
|
|
"clean:sourcemap-test",
|
|
"shell:build:lessc",
|
|
"shell:sourcemap-test",
|
|
"connect::keepalive"
|
|
]);
|
|
|
|
// Run benchmark
|
|
grunt.registerTask("benchmark", [
|
|
"shell:testcjs",
|
|
"shell:benchmark"
|
|
]);
|
|
};
|