407 lines
12 KiB
JavaScript
407 lines
12 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 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 path = require('path')
|
||
|
|
||
|
// Handle async / await in Rollup build for tests
|
||
|
const tsNodeRuntime = path.resolve(
|
||
|
path.join('node_modules', '.bin', 'ts-node')
|
||
|
)
|
||
|
const crossEnv = path.resolve(path.join('node_modules', '.bin', 'cross-env'))
|
||
|
|
||
|
// Project configuration.
|
||
|
grunt.initConfig({
|
||
|
shell: {
|
||
|
options: {
|
||
|
stdout: true,
|
||
|
failOnError: true,
|
||
|
execOptions: {
|
||
|
maxBuffer: Infinity
|
||
|
}
|
||
|
},
|
||
|
build: {
|
||
|
command: [
|
||
|
/** Browser runtime */
|
||
|
'node build/rollup.js --dist',
|
||
|
/** Copy to repo root */
|
||
|
'npm run copy:root',
|
||
|
/** Node.js runtime */
|
||
|
'npm run build'
|
||
|
].join(' && ')
|
||
|
},
|
||
|
testbuild: {
|
||
|
command: [
|
||
|
'npm run build',
|
||
|
'node build/rollup.js --browser --out=./tmp/browser/less.min.js'
|
||
|
].join(' && ')
|
||
|
},
|
||
|
testcjs: {
|
||
|
command: 'npm run build'
|
||
|
},
|
||
|
testbrowser: {
|
||
|
command:
|
||
|
'node build/rollup.js --browser --out=./tmp/browser/less.min.js'
|
||
|
},
|
||
|
test: {
|
||
|
command: [
|
||
|
// https://github.com/TypeStrong/ts-node/issues/693#issuecomment-848907036
|
||
|
crossEnv + ' TS_NODE_SCOPE=true',
|
||
|
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`,
|
||
|
`node ../bin/lessc --source-map=lazy-eval.css.map --autoprefix ../${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',
|
||
|
'src/less*/**/*.js',
|
||
|
'!test/less/errors/plugin/plugin-error.js'
|
||
|
],
|
||
|
options: {
|
||
|
configFile: '.eslintrc.js',
|
||
|
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'])
|
||
|
}
|