Gruntfile.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. 'use strict';
  2. module.exports = function (grunt) {
  3. // Report the elapsed execution time of tasks.
  4. require('time-grunt')(grunt);
  5. var COMPRESS_FOR_TESTS = true;
  6. // Project configuration.
  7. grunt.initConfig({
  8. // Metadata required for build.
  9. build: grunt.file.readYAML('build/build.yml'),
  10. pkg: grunt.file.readJSON('package.json'),
  11. meta: {
  12. copyright: 'Copyright (c) 2009-<%= grunt.template.today("yyyy") %>',
  13. banner: '/*!\n' +
  14. ' * Less - <%= pkg.description %> v<%= pkg.version %>\n' +
  15. ' * http://lesscss.org\n' +
  16. ' *\n' +
  17. ' * <%= meta.copyright %>, <%= pkg.author.name %> <<%= pkg.author.email %>>\n' +
  18. ' * Licensed under the <%= pkg.license %> License.\n' +
  19. ' *\n' +
  20. ' */\n\n' +
  21. ' /**' +
  22. ' * @license <%= pkg.license %>\n' +
  23. ' */\n\n'
  24. },
  25. shell: {
  26. options: {stdout: true, failOnError: true},
  27. test: {
  28. command: 'node test'
  29. },
  30. benchmark: {
  31. command: 'node benchmark/index.js'
  32. },
  33. "sourcemap-test": {
  34. command: [
  35. 'node bin/lessc --source-map=test/sourcemaps/maps/import-map.map test/less/import.less test/sourcemaps/import.css',
  36. 'node bin/lessc --source-map test/less/sourcemaps/basic.less test/sourcemaps/basic.css'
  37. ].join('&&')
  38. }
  39. },
  40. browserify: {
  41. browser: {
  42. src: ['./lib/less-browser/bootstrap.js'],
  43. options: {
  44. exclude: ["promise"],
  45. browserifyOptions: {
  46. standalone: 'less'
  47. }
  48. },
  49. dest: 'tmp/less.js'
  50. }
  51. },
  52. concat: {
  53. options: {
  54. stripBanners: 'all',
  55. banner: '<%= meta.banner %>'
  56. },
  57. browsertest: {
  58. src: COMPRESS_FOR_TESTS ? '<%= uglify.test.dest %>' : '<%= browserify.browser.dest %>',
  59. dest: 'test/browser/less.js'
  60. },
  61. dist: {
  62. src: '<%= browserify.browser.dest %>',
  63. dest: 'dist/less.js'
  64. },
  65. // Rhino
  66. rhino: {
  67. options: {
  68. banner: '/* Less.js v<%= pkg.version %> RHINO | <%= meta.copyright %>, <%= pkg.author.name %> <<%= pkg.author.email %>> */\n\n',
  69. footer: '' // override task-level footer
  70. },
  71. src: ['<%= build.rhino %>'],
  72. dest: 'dist/less-rhino.js'
  73. },
  74. // lessc for Rhino
  75. rhinolessc: {
  76. options: {
  77. banner: '/* Less.js v<%= pkg.version %> RHINO | <%= meta.copyright %>, <%= pkg.author.name %> <<%= pkg.author.email %>> */\n\n',
  78. footer: '' // override task-level footer
  79. },
  80. src: ['<%= build.rhinolessc %>'],
  81. dest: 'dist/lessc-rhino.js'
  82. }
  83. },
  84. uglify: {
  85. options: {
  86. banner: '<%= meta.banner %>',
  87. mangle: true,
  88. compress: {
  89. pure_getters: true
  90. }
  91. },
  92. dist: {
  93. src: ['<%= concat.dist.dest %>'],
  94. dest: 'dist/less.min.js'
  95. },
  96. test: {
  97. src: '<%= browserify.browser.dest %>',
  98. dest: 'tmp/less.min.js'
  99. }
  100. },
  101. jshint: {
  102. options: {jshintrc: '.jshintrc'},
  103. files: {
  104. src: [
  105. 'Gruntfile.js',
  106. 'lib/less/**/*.js',
  107. 'lib/less-node/**/*.js',
  108. 'lib/less-browser/**/*.js',
  109. 'lib/less-rhino/**/*.js',
  110. 'bin/lessc'
  111. ]
  112. }
  113. },
  114. jscs: {
  115. src: ["test/**/*.js", "lib/less*/**/*.js", "bin/lessc"],
  116. options: {
  117. config: ".jscsrc"
  118. }
  119. },
  120. connect: {
  121. server: {
  122. options: {
  123. port: 8081
  124. }
  125. }
  126. },
  127. jasmine: {
  128. options: {
  129. keepRunner: true,
  130. host: 'http://localhost:8081/',
  131. vendor: ['test/browser/jasmine-jsreporter.js', 'test/browser/common.js', 'test/browser/less.js'],
  132. template: 'test/browser/test-runner-template.tmpl'
  133. },
  134. main: {
  135. // src is used to build list of less files to compile
  136. src: ['test/less/*.less', '!test/less/javascript.less', '!test/less/urls.less', '!test/less/empty.less'],
  137. options: {
  138. helpers: 'test/browser/runner-main-options.js',
  139. specs: 'test/browser/runner-main-spec.js',
  140. outfile: 'tmp/browser/test-runner-main.html'
  141. }
  142. },
  143. legacy: {
  144. src: ['test/less/legacy/*.less'],
  145. options: {
  146. helpers: 'test/browser/runner-legacy-options.js',
  147. specs: 'test/browser/runner-legacy-spec.js',
  148. outfile: 'tmp/browser/test-runner-legacy.html'
  149. }
  150. },
  151. strictUnits: {
  152. src: ['test/less/strict-units/*.less'],
  153. options: {
  154. helpers: 'test/browser/runner-strict-units-options.js',
  155. specs: 'test/browser/runner-strict-units-spec.js',
  156. outfile: 'tmp/browser/test-runner-strict-units.html'
  157. }
  158. },
  159. errors: {
  160. src: ['test/less/errors/*.less', '!test/less/errors/javascript-error.less', 'test/browser/less/errors/*.less'],
  161. options: {
  162. timeout: 20000,
  163. helpers: 'test/browser/runner-errors-options.js',
  164. specs: 'test/browser/runner-errors-spec.js',
  165. outfile: 'tmp/browser/test-runner-errors.html'
  166. }
  167. },
  168. noJsErrors: {
  169. src: ['test/less/no-js-errors/*.less'],
  170. options: {
  171. helpers: 'test/browser/runner-no-js-errors-options.js',
  172. specs: 'test/browser/runner-no-js-errors-spec.js',
  173. outfile: 'tmp/browser/test-runner-no-js-errors.html'
  174. }
  175. },
  176. browser: {
  177. src: ['test/browser/less/*.less'],
  178. options: {
  179. helpers: 'test/browser/runner-browser-options.js',
  180. specs: 'test/browser/runner-browser-spec.js',
  181. outfile: 'tmp/browser/test-runner-browser.html'
  182. }
  183. },
  184. relativeUrls: {
  185. src: ['test/browser/less/relative-urls/*.less'],
  186. options: {
  187. helpers: 'test/browser/runner-relative-urls-options.js',
  188. specs: 'test/browser/runner-relative-urls-spec.js',
  189. outfile: 'tmp/browser/test-runner-relative-urls.html'
  190. }
  191. },
  192. rootpath: {
  193. src: ['test/browser/less/rootpath/*.less'],
  194. options: {
  195. helpers: 'test/browser/runner-rootpath-options.js',
  196. specs: 'test/browser/runner-rootpath-spec.js',
  197. outfile: 'tmp/browser/test-runner-rootpath.html'
  198. }
  199. },
  200. rootpathRelative: {
  201. src: ['test/browser/less/rootpath-relative/*.less'],
  202. options: {
  203. helpers: 'test/browser/runner-rootpath-relative-options.js',
  204. specs: 'test/browser/runner-rootpath-relative-spec.js',
  205. outfile: 'tmp/browser/test-runner-rootpath-relative.html'
  206. }
  207. },
  208. production: {
  209. src: ['test/browser/less/production/*.less'],
  210. options: {
  211. helpers: 'test/browser/runner-production-options.js',
  212. specs: 'test/browser/runner-production-spec.js',
  213. outfile: 'tmp/browser/test-runner-production.html'
  214. }
  215. },
  216. modifyVars: {
  217. src: ['test/browser/less/modify-vars/*.less'],
  218. options: {
  219. helpers: 'test/browser/runner-modify-vars-options.js',
  220. specs: 'test/browser/runner-modify-vars-spec.js',
  221. outfile: 'tmp/browser/test-runner-modify-vars.html'
  222. }
  223. },
  224. globalVars: {
  225. src: ['test/browser/less/global-vars/*.less'],
  226. options: {
  227. helpers: 'test/browser/runner-global-vars-options.js',
  228. specs: 'test/browser/runner-global-vars-spec.js',
  229. outfile: 'tmp/browser/test-runner-global-vars.html'
  230. }
  231. },
  232. postProcessor: {
  233. src: ['test/browser/less/postProcessor/*.less'],
  234. options: {
  235. helpers: 'test/browser/runner-postProcessor-options.js',
  236. specs: 'test/browser/runner-postProcessor.js',
  237. outfile: 'tmp/browser/test-runner-post-processor.html'
  238. }
  239. },
  240. postProcessorPlugin: {
  241. src: ['test/less/postProcessorPlugin/*.less'],
  242. options: {
  243. helpers: ['test/plugins/postprocess/index.js','test/browser/runner-postProcessorPlugin-options.js'],
  244. specs: 'test/browser/runner-postProcessorPlugin.js',
  245. outfile: 'tmp/browser/test-runner-post-processor-plugin.html'
  246. }
  247. },
  248. preProcessorPlugin: {
  249. src: ['test/less/preProcessorPlugin/*.less'],
  250. options: {
  251. helpers: ['test/plugins/preprocess/index.js','test/browser/runner-preProcessorPlugin-options.js'],
  252. specs: 'test/browser/runner-preProcessorPlugin.js',
  253. outfile: 'tmp/browser/test-runner-pre-processor-plugin.html'
  254. }
  255. },
  256. visitorPlugin: {
  257. src: ['test/less/visitorPlugin/*.less'],
  258. options: {
  259. helpers: ['test/plugins/visitor/index.js','test/browser/runner-VisitorPlugin-options.js'],
  260. specs: 'test/browser/runner-VisitorPlugin.js',
  261. outfile: 'tmp/browser/test-runner-visitor-plugin.html'
  262. }
  263. },
  264. filemanagerPlugin: {
  265. src: ['test/less/filemanagerPlugin/*.less'],
  266. options: {
  267. helpers: ['test/plugins/filemanager/index.js','test/browser/runner-filemanagerPlugin-options.js'],
  268. specs: 'test/browser/runner-filemanagerPlugin.js',
  269. outfile: 'tmp/browser/test-runner-filemanager-plugin.html'
  270. }
  271. }
  272. },
  273. 'saucelabs-jasmine': {
  274. all: {
  275. options: {
  276. urls: ["filemanager-plugin","visitor-plugin","pre-processor-plugin","post-processor-plugin","post-processor", "global-vars", "modify-vars", "production", "rootpath-relative",
  277. "rootpath", "relative-urls", "browser", "no-js-errors", "legacy", "strict-units"
  278. ].map(function(testName) {
  279. return "http://localhost:8081/tmp/browser/test-runner-" + testName + ".html";
  280. }),
  281. testname: 'Sauce Unit Test for less.js',
  282. browsers: [{
  283. browserName: "chrome",
  284. version: '',
  285. platform: 'Windows 8'
  286. },
  287. {
  288. browserName: "firefox",
  289. version: '33',
  290. platform: 'Linux'
  291. },
  292. {
  293. browserName: "iPad",
  294. version: '8.0',
  295. platform: 'OS X 10.9',
  296. 'device-orientation': 'portrait'
  297. },
  298. {
  299. browserName: "internet explorer",
  300. version: '8',
  301. platform: 'Windows XP'
  302. },
  303. {
  304. browserName: "internet explorer",
  305. version: '9',
  306. platform: 'Windows 7'
  307. },
  308. {
  309. browserName: "internet explorer",
  310. version: '10',
  311. platform: 'Windows 7'
  312. },
  313. {
  314. browserName: "internet explorer",
  315. version: '11',
  316. platform: 'Windows 8.1'
  317. }],
  318. sauceConfig: {
  319. 'record-video': process.env.TRAVIS_BRANCH !== "master",
  320. 'record-screenshots': process.env.TRAVIS_BRANCH !== "master",
  321. 'idle-timeout': 100, 'max-duration': 120,
  322. build: process.env.TRAVIS_BRANCH === "master" ? process.env.TRAVIS_JOB_ID : undefined,
  323. tags: [process.env.TRAVIS_BUILD_NUMBER, process.env.TRAVIS_PULL_REQUEST, process.env.TRAVIS_BRANCH]
  324. },
  325. throttled: 3
  326. }
  327. }
  328. },
  329. // Clean the version of less built for the tests
  330. clean: {
  331. test: ['test/browser/less.js', 'tmp', 'test/less-bom'],
  332. "sourcemap-test": ['test/sourcemaps/*.css', 'test/sourcemaps/*.map'],
  333. sauce_log: ["sc_*.log"]
  334. }
  335. });
  336. // Load these plugins to provide the necessary tasks
  337. require('jit-grunt')(grunt);
  338. // Actually load this plugin's task(s).
  339. grunt.loadTasks('build/tasks');
  340. // by default, run tests
  341. grunt.registerTask('default', [
  342. 'test'
  343. ]);
  344. // Release
  345. grunt.registerTask('dist', [
  346. 'browserify:browser',
  347. 'concat:dist',
  348. 'uglify:dist'
  349. ]);
  350. // Release Rhino Version
  351. grunt.registerTask('rhino', [
  352. 'browserify:rhino',
  353. 'concat:rhino',
  354. 'concat:rhinolessc'
  355. ]);
  356. // Create the browser version of less.js
  357. grunt.registerTask('browsertest-lessjs', [
  358. 'browserify:browser',
  359. 'uglify:test',
  360. 'concat:browsertest'
  361. ]);
  362. // Run all browser tests
  363. grunt.registerTask('browsertest', [
  364. 'browsertest-lessjs',
  365. 'connect',
  366. 'jasmine'
  367. ]);
  368. // setup a web server to run the browser tests in a browser rather than phantom
  369. grunt.registerTask('browsertest-server', [
  370. 'browsertest-lessjs',
  371. 'jasmine::build',
  372. 'connect::keepalive'
  373. ]);
  374. var previous_force_state = grunt.option("force");
  375. grunt.registerTask("force",function(set) {
  376. if (set === "on") {
  377. grunt.option("force",true);
  378. }
  379. else if (set === "off") {
  380. grunt.option("force",false);
  381. }
  382. else if (set === "restore") {
  383. grunt.option("force",previous_force_state);
  384. }
  385. });
  386. grunt.registerTask('sauce', [
  387. 'browsertest-lessjs',
  388. 'jasmine::build',
  389. 'connect',
  390. 'sauce-after-setup'
  391. ]);
  392. // setup a web server to run the browser tests in a browser rather than phantom
  393. grunt.registerTask('sauce-after-setup', [
  394. 'saucelabs-jasmine',
  395. 'clean:sauce_log'
  396. ]);
  397. var testTasks = [
  398. 'clean',
  399. 'jshint',
  400. 'jscs',
  401. 'shell:test',
  402. 'browsertest'
  403. ];
  404. if (isNaN(Number(process.env.TRAVIS_PULL_REQUEST, 10)) &&
  405. Number(process.env.TRAVIS_NODE_VERSION) === 0.11 &&
  406. (process.env.TRAVIS_BRANCH === "master" || process.env.TRAVIS_BRANCH === "sauce")) {
  407. testTasks.push("force:on");
  408. testTasks.push("sauce-after-setup");
  409. testTasks.push("force:off");
  410. }
  411. // Run all tests
  412. grunt.registerTask('test', testTasks);
  413. // Run all tests
  414. grunt.registerTask('quicktest', testTasks.slice(0, testTasks.length -1));
  415. // generate a good test environment for testing sourcemaps
  416. grunt.registerTask('sourcemap-test', [
  417. 'clean:sourcemap-test',
  418. 'shell:sourcemap-test',
  419. 'connect::keepalive'
  420. ]);
  421. // Run benchmark
  422. grunt.registerTask('benchmark', [
  423. 'shell:benchmark'
  424. ]);
  425. };