less 2.3.3 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +5 -0
  3. data/less.gemspec +1 -1
  4. data/lib/less/js/.gitattributes +9 -0
  5. data/lib/less/js/.gitignore +1 -0
  6. data/lib/less/js/.npmignore +1 -1
  7. data/lib/less/js/CHANGELOG.md +68 -0
  8. data/lib/less/js/CONTRIBUTING.md +33 -34
  9. data/lib/less/js/Makefile +24 -9
  10. data/lib/less/js/README.md +2 -2
  11. data/lib/less/js/bin/lessc +102 -25
  12. data/lib/less/js/build/amd.js +1 -1
  13. data/lib/less/js/build/header.js +9 -7
  14. data/lib/less/js/dist/less-1.3.3.js +2 -2
  15. data/lib/less/js/dist/less-1.3.3.min.js +2 -2
  16. data/lib/less/js/dist/less-1.4.0-beta.js +5830 -0
  17. data/lib/less/js/dist/less-1.4.0-beta.min.js +11 -0
  18. data/lib/less/js/dist/less-1.4.0.js +5830 -0
  19. data/lib/less/js/dist/less-1.4.0.min.js +11 -0
  20. data/lib/less/js/dist/less-1.4.1.js +5837 -0
  21. data/lib/less/js/dist/less-1.4.1.min.js +11 -0
  22. data/lib/less/js/dist/less-1.4.2.js +5837 -0
  23. data/lib/less/js/dist/less-1.4.2.min.js +11 -0
  24. data/lib/less/js/dist/less-rhino-1.4.0.js +4273 -0
  25. data/lib/less/js/lib/less/browser.js +131 -101
  26. data/lib/less/js/lib/less/env.js +105 -0
  27. data/lib/less/js/lib/less/extend-visitor.js +391 -0
  28. data/lib/less/js/lib/less/functions.js +174 -19
  29. data/lib/less/js/lib/less/import-visitor.js +107 -0
  30. data/lib/less/js/lib/less/index.js +70 -63
  31. data/lib/less/js/lib/less/join-selector-visitor.js +37 -0
  32. data/lib/less/js/lib/less/lessc_helper.js +13 -4
  33. data/lib/less/js/lib/less/parser.js +353 -264
  34. data/lib/less/js/lib/less/rhino.js +5 -2
  35. data/lib/less/js/lib/less/tree.js +1 -1
  36. data/lib/less/js/lib/less/tree/alpha.js +7 -3
  37. data/lib/less/js/lib/less/tree/anonymous.js +1 -0
  38. data/lib/less/js/lib/less/tree/assignment.js +4 -0
  39. data/lib/less/js/lib/less/tree/call.js +14 -8
  40. data/lib/less/js/lib/less/tree/color.js +50 -5
  41. data/lib/less/js/lib/less/tree/comment.js +1 -0
  42. data/lib/less/js/lib/less/tree/condition.js +35 -28
  43. data/lib/less/js/lib/less/tree/dimension.js +270 -16
  44. data/lib/less/js/lib/less/tree/directive.js +7 -2
  45. data/lib/less/js/lib/less/tree/element.js +57 -21
  46. data/lib/less/js/lib/less/tree/expression.js +29 -4
  47. data/lib/less/js/lib/less/tree/extend.js +43 -0
  48. data/lib/less/js/lib/less/tree/import.js +49 -28
  49. data/lib/less/js/lib/less/tree/javascript.js +1 -0
  50. data/lib/less/js/lib/less/tree/keyword.js +3 -2
  51. data/lib/less/js/lib/less/tree/media.js +20 -4
  52. data/lib/less/js/lib/less/tree/mixin.js +38 -18
  53. data/lib/less/js/lib/less/tree/negative.js +22 -0
  54. data/lib/less/js/lib/less/tree/operation.js +32 -17
  55. data/lib/less/js/lib/less/tree/paren.js +5 -1
  56. data/lib/less/js/lib/less/tree/quoted.js +5 -3
  57. data/lib/less/js/lib/less/tree/rule.js +44 -31
  58. data/lib/less/js/lib/less/tree/ruleset.js +50 -23
  59. data/lib/less/js/lib/less/tree/selector.js +49 -39
  60. data/lib/less/js/lib/less/tree/unicode-descriptor.js +1 -0
  61. data/lib/less/js/lib/less/tree/url.js +9 -5
  62. data/lib/less/js/lib/less/tree/value.js +4 -1
  63. data/lib/less/js/lib/less/tree/variable.js +4 -3
  64. data/lib/less/js/lib/less/visitor.js +54 -0
  65. data/lib/less/js/package.json +69 -19
  66. data/lib/less/js/test/browser-test-prepare.js +23 -6
  67. data/lib/less/js/test/browser/common.js +55 -3
  68. data/lib/less/js/test/browser/css/urls.css +13 -0
  69. data/lib/less/js/test/browser/less/relative-urls/urls.less +1 -1
  70. data/lib/less/js/test/browser/less/urls.less +16 -0
  71. data/lib/less/js/test/browser/phantom-runner.js +7 -5
  72. data/lib/less/js/test/browser/runner-browser.js +5 -1
  73. data/lib/less/js/test/browser/runner-errors.js +5 -0
  74. data/lib/less/js/test/browser/runner-legacy.js +6 -0
  75. data/lib/less/js/test/browser/runner-production.js +7 -0
  76. data/lib/less/js/test/browser/template.htm +6 -6
  77. data/lib/less/js/test/css/comments.css +1 -0
  78. data/lib/less/js/test/css/compression/compression.css +2 -0
  79. data/lib/less/js/test/css/css-3.css +4 -0
  80. data/lib/less/js/test/css/css.css +9 -3
  81. data/lib/less/js/test/css/extend-chaining.css +72 -0
  82. data/lib/less/js/test/css/extend-clearfix.css +19 -0
  83. data/lib/less/js/test/css/extend-exact.css +37 -0
  84. data/lib/less/js/test/css/extend-media.css +24 -0
  85. data/lib/less/js/test/css/extend-nest.css +57 -0
  86. data/lib/less/js/test/css/extend-selector.css +72 -0
  87. data/lib/less/js/test/css/extend.css +76 -0
  88. data/lib/less/js/test/css/functions.css +28 -0
  89. data/lib/less/js/test/css/import-interpolation.css +6 -0
  90. data/lib/less/js/test/css/import.css +18 -1
  91. data/lib/less/js/test/css/legacy/legacy.css +7 -0
  92. data/lib/less/js/test/css/media.css +9 -1
  93. data/lib/less/js/test/css/mixins-args.css +18 -0
  94. data/lib/less/js/test/css/mixins-guards.css +5 -0
  95. data/lib/less/js/test/css/parens.css +18 -5
  96. data/lib/less/js/test/css/selectors.css +14 -6
  97. data/lib/less/js/test/css/urls.css +17 -0
  98. data/lib/less/js/test/css/variables.css +22 -3
  99. data/lib/less/js/test/data/data-uri-fail.png +0 -0
  100. data/lib/less/js/test/data/image.jpg +0 -0
  101. data/lib/less/js/test/data/page.html +1 -0
  102. data/lib/less/js/test/less-test.js +41 -9
  103. data/lib/less/js/test/less/colors.less +4 -4
  104. data/lib/less/js/test/less/comments.less +2 -2
  105. data/lib/less/js/test/less/compression/compression.less +16 -0
  106. data/lib/less/js/test/less/css-3.less +5 -1
  107. data/lib/less/js/test/less/css.less +9 -3
  108. data/lib/less/js/test/less/errors/add-mixed-units.less +3 -0
  109. data/lib/less/js/test/less/errors/add-mixed-units.txt +2 -0
  110. data/lib/less/js/test/less/errors/add-mixed-units2.less +3 -0
  111. data/lib/less/js/test/less/errors/add-mixed-units2.txt +2 -0
  112. data/lib/less/js/test/less/errors/bad-variable-declaration1.txt +1 -1
  113. data/lib/less/js/test/less/errors/color-operation-error.less +3 -0
  114. data/lib/less/js/test/less/errors/color-operation-error.txt +2 -0
  115. data/lib/less/js/test/less/errors/comment-in-selector.txt +1 -1
  116. data/lib/less/js/test/less/errors/divide-mixed-units.less +3 -0
  117. data/lib/less/js/test/less/errors/divide-mixed-units.txt +4 -0
  118. data/lib/less/js/test/less/errors/extend-no-selector.less +3 -0
  119. data/lib/less/js/test/less/errors/extend-no-selector.txt +3 -0
  120. data/lib/less/js/test/less/errors/extend-not-at-end.less +3 -0
  121. data/lib/less/js/test/less/errors/extend-not-at-end.txt +3 -0
  122. data/lib/less/js/test/less/errors/import-missing.less +5 -0
  123. data/lib/less/js/test/less/errors/import-missing.txt +3 -3
  124. data/lib/less/js/test/less/errors/import-no-semi.txt +1 -1
  125. data/lib/less/js/test/less/errors/import-subfolder1.txt +1 -1
  126. data/lib/less/js/test/less/errors/import-subfolder2.txt +1 -1
  127. data/lib/less/js/test/less/errors/javascript-error.txt +1 -1
  128. data/lib/less/js/test/less/errors/mixed-mixin-definition-args-1.txt +1 -1
  129. data/lib/less/js/test/less/errors/mixed-mixin-definition-args-2.txt +1 -1
  130. data/lib/less/js/test/less/errors/mixin-not-defined.txt +1 -1
  131. data/lib/less/js/test/less/errors/mixin-not-matched.txt +1 -1
  132. data/lib/less/js/test/less/errors/mixin-not-matched2.txt +1 -1
  133. data/lib/less/js/test/less/errors/multiply-mixed-units.less +7 -0
  134. data/lib/less/js/test/less/errors/multiply-mixed-units.txt +4 -0
  135. data/lib/less/js/test/less/errors/parens-error-1.less +3 -0
  136. data/lib/less/js/test/less/errors/parens-error-1.txt +4 -0
  137. data/lib/less/js/test/less/errors/parens-error-2.less +3 -0
  138. data/lib/less/js/test/less/errors/parens-error-2.txt +4 -0
  139. data/lib/less/js/test/less/errors/parens-error-3.less +3 -0
  140. data/lib/less/js/test/less/errors/parens-error-3.txt +4 -0
  141. data/lib/less/js/test/less/errors/parse-error-curly-bracket.txt +1 -1
  142. data/lib/less/js/test/less/errors/parse-error-missing-bracket.txt +2 -1
  143. data/lib/less/js/test/less/errors/parse-error-with-import.txt +1 -1
  144. data/lib/less/js/test/less/errors/property-ie5-hack.txt +1 -1
  145. data/lib/less/js/test/less/errors/property-in-root.less +4 -0
  146. data/lib/less/js/test/less/errors/property-in-root.txt +4 -0
  147. data/lib/less/js/test/less/errors/property-in-root2.less +1 -0
  148. data/lib/less/js/test/less/errors/property-in-root2.txt +4 -0
  149. data/lib/less/js/test/less/errors/property-in-root3.less +4 -0
  150. data/lib/less/js/test/less/errors/property-in-root3.txt +3 -0
  151. data/lib/less/js/test/less/errors/recursive-variable.txt +1 -1
  152. data/lib/less/js/test/less/extend-chaining.less +79 -0
  153. data/lib/less/js/test/less/extend-clearfix.less +19 -0
  154. data/lib/less/js/test/less/extend-exact.less +46 -0
  155. data/lib/less/js/test/less/extend-media.less +24 -0
  156. data/lib/less/js/test/less/extend-nest.less +65 -0
  157. data/lib/less/js/test/less/extend-selector.less +84 -0
  158. data/lib/less/js/test/less/extend.less +81 -0
  159. data/lib/less/js/test/less/functions.less +37 -6
  160. data/lib/less/js/test/less/import-interpolation.less +8 -0
  161. data/lib/less/js/test/less/import-once.less +4 -4
  162. data/lib/less/js/test/less/import.less +11 -2
  163. data/lib/less/js/test/less/import/deeper/import-once-test-a.less +1 -1
  164. data/lib/less/js/test/less/import/import-interpolation.less +1 -0
  165. data/lib/less/js/test/less/import/import-interpolation2.less +5 -0
  166. data/lib/less/js/test/less/javascript.less +1 -1
  167. data/lib/less/js/test/less/legacy/legacy.less +7 -0
  168. data/lib/less/js/test/less/media.less +14 -3
  169. data/lib/less/js/test/less/mixins-args.less +43 -5
  170. data/lib/less/js/test/less/mixins-guards.less +13 -0
  171. data/lib/less/js/test/less/mixins-named-args.less +5 -5
  172. data/lib/less/js/test/less/mixins-nested.less +2 -2
  173. data/lib/less/js/test/less/mixins-pattern.less +1 -1
  174. data/lib/less/js/test/less/mixins.less +1 -1
  175. data/lib/less/js/test/less/operations.less +27 -27
  176. data/lib/less/js/test/less/parens.less +20 -5
  177. data/lib/less/js/test/less/selectors.less +14 -7
  178. data/lib/less/js/test/less/urls.less +24 -0
  179. data/lib/less/js/test/less/variables.less +42 -12
  180. data/lib/less/loader.rb +33 -0
  181. data/lib/less/version.rb +1 -1
  182. data/spec/less/parser_spec.rb +5 -5
  183. metadata +76 -6
  184. data/lib/less/js/build/ecma-5.js +0 -120
  185. data/lib/less/js/lib/less/tree/ratio.js +0 -13
@@ -4,6 +4,7 @@ tree.UnicodeDescriptor = function (value) {
4
4
  this.value = value;
5
5
  };
6
6
  tree.UnicodeDescriptor.prototype = {
7
+ type: "UnicodeDescriptor",
7
8
  toCSS: function (env) {
8
9
  return this.value;
9
10
  },
@@ -1,10 +1,14 @@
1
1
  (function (tree) {
2
2
 
3
- tree.URL = function (val, rootpath) {
3
+ tree.URL = function (val, currentFileInfo) {
4
4
  this.value = val;
5
- this.rootpath = rootpath;
5
+ this.currentFileInfo = currentFileInfo;
6
6
  };
7
7
  tree.URL.prototype = {
8
+ type: "Url",
9
+ accept: function (visitor) {
10
+ this.value = visitor.visit(this.value);
11
+ },
8
12
  toCSS: function () {
9
13
  return "url(" + this.value.toCSS() + ")";
10
14
  },
@@ -12,15 +16,15 @@ tree.URL.prototype = {
12
16
  var val = this.value.eval(ctx), rootpath;
13
17
 
14
18
  // Add the base path if the URL is relative
15
- if (typeof val.value === "string" && !/^(?:[a-z-]+:|\/)/.test(val.value)) {
16
- rootpath = this.rootpath;
19
+ rootpath = this.currentFileInfo && this.currentFileInfo.rootpath;
20
+ if (rootpath && typeof val.value === "string" && ctx.isPathRelative(val.value)) {
17
21
  if (!val.quote) {
18
22
  rootpath = rootpath.replace(/[\(\)'"\s]/g, function(match) { return "\\"+match; });
19
23
  }
20
24
  val.value = rootpath + val.value;
21
25
  }
22
26
 
23
- return new(tree.URL)(val, this.rootpath);
27
+ return new(tree.URL)(val, null);
24
28
  }
25
29
  };
26
30
 
@@ -2,9 +2,12 @@
2
2
 
3
3
  tree.Value = function (value) {
4
4
  this.value = value;
5
- this.is = 'value';
6
5
  };
7
6
  tree.Value.prototype = {
7
+ type: "Value",
8
+ accept: function (visitor) {
9
+ this.value = visitor.visit(this.value);
10
+ },
8
11
  eval: function (env) {
9
12
  if (this.value.length === 1) {
10
13
  return this.value[0].eval(env);
@@ -1,7 +1,8 @@
1
1
  (function (tree) {
2
2
 
3
- tree.Variable = function (name, index, file) { this.name = name, this.index = index, this.file = file };
3
+ tree.Variable = function (name, index, currentFileInfo) { this.name = name, this.index = index, this.currentFileInfo = currentFileInfo };
4
4
  tree.Variable.prototype = {
5
+ type: "Variable",
5
6
  eval: function (env) {
6
7
  var variable, v, name = this.name;
7
8
 
@@ -12,7 +13,7 @@ tree.Variable.prototype = {
12
13
  if (this.evaluating) {
13
14
  throw { type: 'Name',
14
15
  message: "Recursive variable definition for " + name,
15
- filename: this.file,
16
+ filename: this.currentFileInfo.file,
16
17
  index: this.index };
17
18
  }
18
19
 
@@ -29,7 +30,7 @@ tree.Variable.prototype = {
29
30
  else {
30
31
  throw { type: 'Name',
31
32
  message: "variable " + name + " is undefined",
32
- filename: this.file,
33
+ filename: this.currentFileInfo.filename,
33
34
  index: this.index };
34
35
  }
35
36
  }
@@ -0,0 +1,54 @@
1
+ (function (tree) {
2
+
3
+ tree.visitor = function(implementation) {
4
+ this._implementation = implementation;
5
+ };
6
+
7
+ tree.visitor.prototype = {
8
+ visit: function(node) {
9
+
10
+ if (node instanceof Array) {
11
+ return this.visitArray(node);
12
+ }
13
+
14
+ if (!node || !node.type) {
15
+ return node;
16
+ }
17
+
18
+ var funcName = "visit" + node.type,
19
+ func = this._implementation[funcName],
20
+ visitArgs, newNode;
21
+ if (func) {
22
+ visitArgs = {visitDeeper: true};
23
+ newNode = func.call(this._implementation, node, visitArgs);
24
+ if (this._implementation.isReplacing) {
25
+ node = newNode;
26
+ }
27
+ }
28
+ if ((!visitArgs || visitArgs.visitDeeper) && node && node.accept) {
29
+ node.accept(this);
30
+ }
31
+ funcName = funcName + "Out";
32
+ if (this._implementation[funcName]) {
33
+ this._implementation[funcName](node);
34
+ }
35
+ return node;
36
+ },
37
+ visitArray: function(nodes) {
38
+ var i, newNodes = [];
39
+ for(i = 0; i < nodes.length; i++) {
40
+ var evald = this.visit(nodes[i]);
41
+ if (evald instanceof Array) {
42
+ newNodes = newNodes.concat(evald);
43
+ } else {
44
+ newNodes.push(evald);
45
+ }
46
+ }
47
+ if (this._implementation.isReplacing) {
48
+ return newNodes;
49
+ }
50
+ return nodes;
51
+ }
52
+ };
53
+
54
+ })(require('./tree'));
@@ -1,23 +1,73 @@
1
1
  {
2
- "name" : "less",
3
- "description" : "Leaner CSS",
4
- "homepage" : "http://lesscss.org",
5
- "keywords" : ["css", "parser", "lesscss", "browser"],
6
- "author" : "Alexis Sellier <self@cloudhead.net>",
7
- "contributors" : [],
8
- "version" : "1.3.3",
9
- "bin" : { "lessc": "./bin/lessc" },
10
- "main" : "./lib/less/index",
11
- "directories" : { "test": "./test" },
12
- "engines" : { "node": ">=0.4.2" },
13
- "optionalDependencies" : { "ycssmin": ">=1.0.1" },
14
- "devDependencies" : { "diff": "~1.0" },
2
+ "name": "less",
3
+ "version": "1.4.2",
4
+ "description": "Leaner CSS",
5
+ "homepage": "http://lesscss.org",
6
+ "author": "Alexis Sellier <self@cloudhead.net>",
7
+ "contributors": [
8
+ "The Core Less Team"
9
+ ],
10
+ "bugs": {
11
+ "url": "https://github.com/less/less.js/issues"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/less/less.js.git"
16
+ },
17
+ "bin": {
18
+ "lessc": "./bin/lessc"
19
+ },
20
+ "main": "./lib/less/index",
21
+ "directories": {
22
+ "test": "./test"
23
+ },
24
+ "jam": {
25
+ "main": "./dist/less-1.4.1.js"
26
+ },
27
+ "engines": {
28
+ "node": ">=0.4.2"
29
+ },
15
30
  "scripts": {
16
- "test": "make test"
31
+ "test": "make test"
32
+ },
33
+ "optionalDependencies": {
34
+ "mime": "1.2.x",
35
+ "request": ">=2.12.0",
36
+ "mkdirp": "~0.3.4",
37
+ "ycssmin": ">=1.0.1"
38
+ },
39
+ "devDependencies": {
40
+ "diff": "~1.0"
17
41
  },
18
- "bugs": { "url" : "https://github.com/cloudhead/less.js/issues"},
19
- "repository" :
20
- { "type" : "git",
21
- "url" : "https://github.com/cloudhead/less.js.git"
22
- }
42
+ "keywords": [
43
+ "compile less",
44
+ "css nesting",
45
+ "css variable",
46
+ "css",
47
+ "gradients css",
48
+ "gradients css3",
49
+ "less compiler",
50
+ "less css",
51
+ "less mixins",
52
+ "less",
53
+ "less.js",
54
+ "lesscss",
55
+ "mixins",
56
+ "nested css",
57
+ "parser",
58
+ "preprocessor",
59
+ "bootstrap css",
60
+ "bootstrap less",
61
+ "style",
62
+ "styles",
63
+ "stylesheet",
64
+ "variables in css",
65
+ "css less"
66
+ ],
67
+ "licenses": [
68
+ {
69
+ "type": "Apache v2",
70
+ "url": "https://github.com/less/less.js/blob/master/LICENSE"
71
+ }
72
+ ]
23
73
  }
@@ -2,19 +2,24 @@ var path = require('path'),
2
2
  fs = require('fs'),
3
3
  sys = require('util');
4
4
 
5
+ var readDirFilesSync = function(dir, regex, callback) {
6
+ fs.readdirSync(dir).forEach(function (file) {
7
+ if (! regex.test(file)) { return; }
8
+ callback(file);
9
+ });
10
+ }
11
+
5
12
  var createTestRunnerPage = function(dir, exclude, testSuiteName, dir2) {
6
13
  var output = '<html><head>\n';
7
14
 
8
- fs.readdirSync(path.join("test", dir, 'less', dir2 || "")).forEach(function (file) {
9
- if (! /\.less/.test(file)) { return; }
10
-
15
+ readDirFilesSync(path.join("test", dir, 'less', dir2 || ""), /\.less$/, function (file) {
11
16
  var name = path.basename(file, '.less'),
12
17
  id = (dir ? dir + '-' : "") + 'less-' + (dir2 ? dir2 + "-" : "") + name;
13
18
 
14
19
  if (exclude && name.match(exclude)) { return; }
15
20
 
16
- output += '<link id="original-less:' + id + '" rel="stylesheet/less" type="text/css" href="http://localhost:8081/' + path.join(dir, 'less', dir2 || "", name) + '.less' +'">\n';
17
- output += '<link id="expected-less:' + id + '" rel="stylesheet" type="text/css" href="http://localhost:8081/' + path.join(dir, 'css', dir2 || "", name) + '.css' + '">\n';
21
+ output += '<link id="original-less:' + id + '" rel="stylesheet/less" type="text/css" href="/' + path.join(dir, 'less', dir2 || "", name) + '.less' +'">\n';
22
+ output += '<link id="expected-less:' + id + '" rel="stylesheet" type="text/css" href="/' + path.join(dir, 'css', dir2 || "", name) + '.css' + '">\n';
18
23
  });
19
24
 
20
25
  output += String(fs.readFileSync(path.join('test/browser', 'template.htm'))).replace("{runner-name}", testSuiteName);
@@ -22,8 +27,20 @@ var createTestRunnerPage = function(dir, exclude, testSuiteName, dir2) {
22
27
  fs.writeFileSync(path.join('test/browser', 'test-runner-'+testSuiteName+'.htm'), output);
23
28
  };
24
29
 
30
+ var removeFiles = function(dir, regex) {
31
+ readDirFilesSync(dir, regex, function(file) {
32
+ fs.unlinkSync(path.join(dir, file), function() {
33
+ console.log("Failed to delete " + file);
34
+ });
35
+ });
36
+ }
37
+
38
+ removeFiles("test/browser", /test-runner-[a-zA-Z-]*\.htm$/);
25
39
  createTestRunnerPage("", /javascript|urls/, "main");
40
+ createTestRunnerPage("", null, "legacy", "legacy");
41
+ createTestRunnerPage("", /javascript/, "errors", "errors");
26
42
  createTestRunnerPage("browser", null, "browser");
27
43
  createTestRunnerPage("browser", null, "relative-urls", "relative-urls");
28
44
  createTestRunnerPage("browser", null, "rootpath", "rootpath");
29
- createTestRunnerPage("browser", null, "rootpath-relative", "rootpath-relative");
45
+ createTestRunnerPage("browser", null, "rootpath-relative", "rootpath-relative");
46
+ createTestRunnerPage("browser", null, "production");
@@ -1,14 +1,30 @@
1
1
  /*if not async then phantomjs fails to run the webserver and the test concurrently*/
2
- var less = { async: true };
2
+ var less = { async: true, strictMath: true };
3
+
4
+ /* record log messages for testing */
5
+ var logMessages = [],
6
+ realConsoleLog = console.log;
7
+ console.log = function(msg) {
8
+ logMessages.push(msg);
9
+ realConsoleLog.call(console, msg);
10
+ };
3
11
 
4
12
  var testLessEqualsInDocument = function() {
13
+ testLessInDocument(testSheet);
14
+ };
15
+
16
+ var testLessErrorsInDocument = function() {
17
+ testLessInDocument(testErrorSheet);
18
+ };
19
+
20
+ var testLessInDocument = function(testFunc) {
5
21
  var links = document.getElementsByTagName('link'),
6
22
  typePattern = /^text\/(x-)?less$/;
7
23
 
8
24
  for (var i = 0; i < links.length; i++) {
9
25
  if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
10
26
  (links[i].type.match(typePattern)))) {
11
- testSheet(links[i]);
27
+ testFunc(links[i]);
12
28
  }
13
29
  }
14
30
  };
@@ -32,12 +48,48 @@ var testSheet = function(sheet) {
32
48
  });
33
49
  };
34
50
 
51
+ var testErrorSheet = function(sheet) {
52
+ it(sheet.id + " should match an error", function() {
53
+ var lessHref = sheet.href,
54
+ id = sheet.id.replace(/^original-less:/, "less-error-message:"),
55
+ errorHref = lessHref.replace(/.less$/, ".txt"),
56
+ errorFile = loadFile(errorHref),
57
+ actualErrorElement = document.getElementById(id),
58
+ actualErrorMsg;
59
+
60
+ describe("the error", function() {
61
+ expect(actualErrorElement).not.toBe(null);
62
+ });
63
+
64
+ actualErrorMsg = actualErrorElement.innerText
65
+ .replace(/\n\d+/g, function(lineNo) { return lineNo + " "; })
66
+ .replace(/\n\s*in /g, " in ")
67
+ .replace("\n\n", "\n");
68
+
69
+ waitsFor(function() {
70
+ return errorFile.loaded;
71
+ }, "failed to load expected outout", 10000);
72
+
73
+ runs(function() {
74
+ var errorTxt = errorFile.text
75
+ .replace("{path}", "")
76
+ .replace("{pathrel}", "")
77
+ .replace("{pathhref}", "http://localhost:8081/less/errors/")
78
+ .replace("{404status}", " (404)");
79
+ expect(actualErrorMsg).toEqual(errorTxt);
80
+ if (errorTxt == actualErrorMsg) {
81
+ actualErrorElement.style.display = "none";
82
+ }
83
+ });
84
+ });
85
+ };
86
+
35
87
  var loadFile = function(href) {
36
88
  var request = new XMLHttpRequest(),
37
89
  response = { loaded: false, text: ""};
38
90
  request.open('GET', href, true);
39
91
  request.onload = function(e) {
40
- response.text = request.response;
92
+ response.text = request.response.replace(/\r/g, "");
41
93
  response.loaded = true;
42
94
  }
43
95
  request.send();
@@ -34,3 +34,16 @@
34
34
  .values {
35
35
  url: url('http://localhost:8081/browser/less/Trebuchet');
36
36
  }
37
+ #data-uri {
38
+ uri: url('http://localhost:8081/browser/less/../../data/image.jpg');
39
+ }
40
+ #data-uri-guess {
41
+ uri: url('http://localhost:8081/browser/less/../../data/image.jpg');
42
+ }
43
+ #data-uri-ascii {
44
+ uri-1: url('http://localhost:8081/browser/less/../../data/page.html');
45
+ uri-2: url('http://localhost:8081/browser/less/../../data/page.html');
46
+ }
47
+ #data-uri-toobig {
48
+ uri: url('http://localhost:8081/browser/less/../../data/data-uri-fail.png');
49
+ }
@@ -1,4 +1,4 @@
1
- @import "../imports/urls.less";
1
+ @import ".././imports/urls.less";
2
2
  @import "http://localhost:8081/browser/less/imports/urls2.less";
3
3
  @font-face {
4
4
  src: url("/fonts/garamond-pro.ttf");
@@ -31,3 +31,19 @@
31
31
  @a: 'Trebuchet';
32
32
  url: url(@a);
33
33
  }
34
+ #data-uri {
35
+ uri: data-uri('image/jpeg;base64', '../../data/image.jpg');
36
+ }
37
+
38
+ #data-uri-guess {
39
+ uri: data-uri('../../data/image.jpg');
40
+ }
41
+
42
+ #data-uri-ascii {
43
+ uri-1: data-uri('text/html', '../../data/page.html');
44
+ uri-2: data-uri('../../data/page.html');
45
+ }
46
+
47
+ #data-uri-toobig {
48
+ uri: data-uri('../../data/data-uri-fail.png');
49
+ }
@@ -40,8 +40,9 @@ if (!listening) {
40
40
  * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
41
41
  * as a callback function.
42
42
  * @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used.
43
+ * @param timeOutErrorMessage the error message if time out occurs
43
44
  */
44
- function waitFor(testFx, onReady, timeOutMillis) {
45
+ function waitFor(testFx, onReady, timeOutMillis, timeOutErrorMessage) {
45
46
  var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 10001, //< Default Max Timeout is 10s
46
47
  start = new Date().getTime(),
47
48
  condition = false,
@@ -52,11 +53,10 @@ function waitFor(testFx, onReady, timeOutMillis) {
52
53
  } else {
53
54
  if(!condition) {
54
55
  // If condition still not fulfilled (timeout but condition is 'false')
55
- console.log("'waitFor()' timeout");
56
+ console.log(timeOutErrorMessage || "'waitFor()' timeout");
56
57
  phantom.exit(1);
57
58
  } else {
58
59
  // Condition fulfilled (timeout and/or condition is 'true')
59
- //console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
60
60
  typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
61
61
  clearInterval(interval); //< Stop this interval
62
62
  }
@@ -88,7 +88,7 @@ function testPage(url) {
88
88
  if (list && list.length > 0) {
89
89
  console.log('');
90
90
  console.log(list.length + ' test(s) FAILED:');
91
- for (i = 0; i < list.length; ++i) {
91
+ for (var i = 0; i < list.length; ++i) {
92
92
  var el = list[i],
93
93
  desc = el.querySelector('.description'),
94
94
  msg = el.querySelector('.resultMessage.fail');
@@ -104,7 +104,9 @@ function testPage(url) {
104
104
  }
105
105
  });
106
106
  testFinished(exitCode);
107
- });
107
+ },
108
+ 10000, // 10 second timeout
109
+ "Test failed waiting for jasmine results on page: " + url);
108
110
  }
109
111
  });
110
112
  }