classiccms 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (369) hide show
  1. data/lib/classiccms/application.rb +2 -3
  2. data/lib/classiccms/cli.rb +6 -0
  3. data/lib/classiccms/scaffold/Gemfile +4 -0
  4. data/lib/classiccms/{mongoid.yml → scaffold/config/mongoid.yml} +3 -4
  5. data/lib/classiccms/scaffold/spec/models/article_spec.rb +8 -0
  6. data/lib/classiccms/scaffold/spec/spec_helper.rb +24 -0
  7. data/lib/classiccms/version.rb +1 -1
  8. data/spec/cli_spec.rb +8 -0
  9. data/vendor/bundle/gems/libv8-3.3.10.4-x86_64-darwin-11/lib/libv8/build/v8/libv8.a +0 -0
  10. data/vendor/bundle/gems/libv8-3.3.10.4-x86_64-darwin-11/lib/libv8/build/v8/libv8preparser.a +0 -0
  11. data/vendor/bundle/gems/libv8-3.3.10.4-x86_64-darwin-11/lib/libv8/v8/include/v8-debug.h +395 -0
  12. data/vendor/bundle/gems/libv8-3.3.10.4-x86_64-darwin-11/lib/libv8/v8/include/v8-preparser.h +117 -0
  13. data/vendor/bundle/gems/libv8-3.3.10.4-x86_64-darwin-11/lib/libv8/v8/include/v8-profiler.h +505 -0
  14. data/vendor/bundle/gems/libv8-3.3.10.4-x86_64-darwin-11/lib/libv8/v8/include/v8-testing.h +104 -0
  15. data/vendor/bundle/gems/libv8-3.3.10.4-x86_64-darwin-11/lib/libv8/v8/include/v8.h +4124 -0
  16. data/vendor/bundle/gems/libv8-3.3.10.4-x86_64-darwin-11/lib/libv8/v8/include/v8stdint.h +53 -0
  17. data/vendor/bundle/gems/libv8-3.3.10.4-x86_64-darwin-11/lib/libv8/version.rb +6 -0
  18. data/vendor/bundle/gems/libv8-3.3.10.4-x86_64-darwin-11/lib/libv8.rb +15 -0
  19. data/vendor/bundle/gems/sass-3.1.19/.yardopts +11 -0
  20. data/vendor/bundle/gems/sass-3.1.19/CONTRIBUTING +3 -0
  21. data/vendor/bundle/gems/sass-3.1.19/MIT-LICENSE +20 -0
  22. data/vendor/bundle/gems/sass-3.1.19/README.md +200 -0
  23. data/vendor/bundle/gems/sass-3.1.19/REVISION +1 -0
  24. data/vendor/bundle/gems/sass-3.1.19/Rakefile +339 -0
  25. data/vendor/bundle/gems/sass-3.1.19/VERSION +1 -0
  26. data/vendor/bundle/gems/sass-3.1.19/VERSION_NAME +1 -0
  27. data/vendor/bundle/gems/sass-3.1.19/bin/sass +8 -0
  28. data/vendor/bundle/gems/sass-3.1.19/bin/sass-convert +7 -0
  29. data/vendor/bundle/gems/sass-3.1.19/bin/scss +8 -0
  30. data/vendor/bundle/gems/sass-3.1.19/extra/update_watch.rb +13 -0
  31. data/vendor/bundle/gems/sass-3.1.19/init.rb +18 -0
  32. data/vendor/bundle/gems/sass-3.1.19/lib/sass/cache_stores/base.rb +86 -0
  33. data/vendor/bundle/gems/sass-3.1.19/lib/sass/cache_stores/chain.rb +33 -0
  34. data/vendor/bundle/gems/sass-3.1.19/lib/sass/cache_stores/filesystem.rb +61 -0
  35. data/vendor/bundle/gems/sass-3.1.19/lib/sass/cache_stores/memory.rb +47 -0
  36. data/vendor/bundle/gems/sass-3.1.19/lib/sass/cache_stores/null.rb +25 -0
  37. data/vendor/bundle/gems/sass-3.1.19/lib/sass/cache_stores.rb +15 -0
  38. data/vendor/bundle/gems/sass-3.1.19/lib/sass/callbacks.rb +66 -0
  39. data/vendor/bundle/gems/sass-3.1.19/lib/sass/css.rb +390 -0
  40. data/vendor/bundle/gems/sass-3.1.19/lib/sass/engine.rb +880 -0
  41. data/vendor/bundle/gems/sass-3.1.19/lib/sass/environment.rb +180 -0
  42. data/vendor/bundle/gems/sass-3.1.19/lib/sass/error.rb +201 -0
  43. data/vendor/bundle/gems/sass-3.1.19/lib/sass/exec.rb +682 -0
  44. data/vendor/bundle/gems/sass-3.1.19/lib/sass/importers/base.rb +139 -0
  45. data/vendor/bundle/gems/sass-3.1.19/lib/sass/importers/filesystem.rb +149 -0
  46. data/vendor/bundle/gems/sass-3.1.19/lib/sass/importers.rb +22 -0
  47. data/vendor/bundle/gems/sass-3.1.19/lib/sass/less.rb +382 -0
  48. data/vendor/bundle/gems/sass-3.1.19/lib/sass/logger/base.rb +32 -0
  49. data/vendor/bundle/gems/sass-3.1.19/lib/sass/logger/log_level.rb +49 -0
  50. data/vendor/bundle/gems/sass-3.1.19/lib/sass/logger.rb +15 -0
  51. data/vendor/bundle/gems/sass-3.1.19/lib/sass/plugin/compiler.rb +384 -0
  52. data/vendor/bundle/gems/sass-3.1.19/lib/sass/plugin/configuration.rb +123 -0
  53. data/vendor/bundle/gems/sass-3.1.19/lib/sass/plugin/generic.rb +15 -0
  54. data/vendor/bundle/gems/sass-3.1.19/lib/sass/plugin/merb.rb +48 -0
  55. data/vendor/bundle/gems/sass-3.1.19/lib/sass/plugin/rack.rb +60 -0
  56. data/vendor/bundle/gems/sass-3.1.19/lib/sass/plugin/rails.rb +47 -0
  57. data/vendor/bundle/gems/sass-3.1.19/lib/sass/plugin/staleness_checker.rb +183 -0
  58. data/vendor/bundle/gems/sass-3.1.19/lib/sass/plugin.rb +132 -0
  59. data/vendor/bundle/gems/sass-3.1.19/lib/sass/railtie.rb +9 -0
  60. data/vendor/bundle/gems/sass-3.1.19/lib/sass/repl.rb +57 -0
  61. data/vendor/bundle/gems/sass-3.1.19/lib/sass/root.rb +7 -0
  62. data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/bool.rb +18 -0
  63. data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/color.rb +475 -0
  64. data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/css_lexer.rb +29 -0
  65. data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/css_parser.rb +31 -0
  66. data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/funcall.rb +175 -0
  67. data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/functions.rb +1381 -0
  68. data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/interpolation.rb +79 -0
  69. data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/lexer.rb +337 -0
  70. data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/list.rb +84 -0
  71. data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/literal.rb +230 -0
  72. data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/node.rb +99 -0
  73. data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/number.rb +452 -0
  74. data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/operation.rb +107 -0
  75. data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/parser.rb +474 -0
  76. data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/string.rb +51 -0
  77. data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/string_interpolation.rb +103 -0
  78. data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/unary_operation.rb +64 -0
  79. data/vendor/bundle/gems/sass-3.1.19/lib/sass/script/variable.rb +58 -0
  80. data/vendor/bundle/gems/sass-3.1.19/lib/sass/script.rb +39 -0
  81. data/vendor/bundle/gems/sass-3.1.19/lib/sass/scss/css_parser.rb +46 -0
  82. data/vendor/bundle/gems/sass-3.1.19/lib/sass/scss/parser.rb +1055 -0
  83. data/vendor/bundle/gems/sass-3.1.19/lib/sass/scss/rx.rb +137 -0
  84. data/vendor/bundle/gems/sass-3.1.19/lib/sass/scss/sass_parser.rb +11 -0
  85. data/vendor/bundle/gems/sass-3.1.19/lib/sass/scss/script_lexer.rb +15 -0
  86. data/vendor/bundle/gems/sass-3.1.19/lib/sass/scss/script_parser.rb +25 -0
  87. data/vendor/bundle/gems/sass-3.1.19/lib/sass/scss/static_parser.rb +40 -0
  88. data/vendor/bundle/gems/sass-3.1.19/lib/sass/scss.rb +17 -0
  89. data/vendor/bundle/gems/sass-3.1.19/lib/sass/selector/abstract_sequence.rb +71 -0
  90. data/vendor/bundle/gems/sass-3.1.19/lib/sass/selector/comma_sequence.rb +86 -0
  91. data/vendor/bundle/gems/sass-3.1.19/lib/sass/selector/sequence.rb +296 -0
  92. data/vendor/bundle/gems/sass-3.1.19/lib/sass/selector/simple.rb +119 -0
  93. data/vendor/bundle/gems/sass-3.1.19/lib/sass/selector/simple_sequence.rb +154 -0
  94. data/vendor/bundle/gems/sass-3.1.19/lib/sass/selector.rb +373 -0
  95. data/vendor/bundle/gems/sass-3.1.19/lib/sass/shared.rb +76 -0
  96. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/charset_node.rb +22 -0
  97. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/comment_node.rb +90 -0
  98. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/debug_node.rb +18 -0
  99. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/directive_node.rb +28 -0
  100. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/each_node.rb +24 -0
  101. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/extend_node.rb +29 -0
  102. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/for_node.rb +36 -0
  103. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/function_node.rb +27 -0
  104. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/if_node.rb +52 -0
  105. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/import_node.rb +68 -0
  106. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/media_node.rb +32 -0
  107. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/mixin_def_node.rb +27 -0
  108. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/mixin_node.rb +32 -0
  109. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/node.rb +188 -0
  110. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/prop_node.rb +148 -0
  111. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/return_node.rb +18 -0
  112. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/root_node.rb +28 -0
  113. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/rule_node.rb +127 -0
  114. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/variable_node.rb +30 -0
  115. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/visitors/base.rb +75 -0
  116. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/visitors/check_nesting.rb +127 -0
  117. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/visitors/convert.rb +262 -0
  118. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/visitors/cssize.rb +206 -0
  119. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/visitors/deep_copy.rb +87 -0
  120. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/visitors/extend.rb +42 -0
  121. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/visitors/perform.rb +357 -0
  122. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/visitors/set_options.rb +97 -0
  123. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/visitors/to_css.rb +219 -0
  124. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/warn_node.rb +18 -0
  125. data/vendor/bundle/gems/sass-3.1.19/lib/sass/tree/while_node.rb +18 -0
  126. data/vendor/bundle/gems/sass-3.1.19/lib/sass/util/multibyte_string_scanner.rb +134 -0
  127. data/vendor/bundle/gems/sass-3.1.19/lib/sass/util/subset_map.rb +101 -0
  128. data/vendor/bundle/gems/sass-3.1.19/lib/sass/util.rb +800 -0
  129. data/vendor/bundle/gems/sass-3.1.19/lib/sass/version.rb +112 -0
  130. data/vendor/bundle/gems/sass-3.1.19/lib/sass.rb +73 -0
  131. data/vendor/bundle/gems/sass-3.1.19/rails/init.rb +1 -0
  132. data/vendor/bundle/gems/sass-3.1.19/test/Gemfile +4 -0
  133. data/vendor/bundle/gems/sass-3.1.19/test/sass/cache_test.rb +89 -0
  134. data/vendor/bundle/gems/sass-3.1.19/test/sass/callbacks_test.rb +61 -0
  135. data/vendor/bundle/gems/sass-3.1.19/test/sass/conversion_test.rb +1245 -0
  136. data/vendor/bundle/gems/sass-3.1.19/test/sass/css2sass_test.rb +397 -0
  137. data/vendor/bundle/gems/sass-3.1.19/test/sass/data/hsl-rgb.txt +319 -0
  138. data/vendor/bundle/gems/sass-3.1.19/test/sass/engine_test.rb +2730 -0
  139. data/vendor/bundle/gems/sass-3.1.19/test/sass/extend_test.rb +1663 -0
  140. data/vendor/bundle/gems/sass-3.1.19/test/sass/fixtures/test_staleness_check_across_importers.css +1 -0
  141. data/vendor/bundle/gems/sass-3.1.19/test/sass/fixtures/test_staleness_check_across_importers.scss +1 -0
  142. data/vendor/bundle/gems/sass-3.1.19/test/sass/functions_test.rb +1047 -0
  143. data/vendor/bundle/gems/sass-3.1.19/test/sass/importer_test.rb +192 -0
  144. data/vendor/bundle/gems/sass-3.1.19/test/sass/less_conversion_test.rb +653 -0
  145. data/vendor/bundle/gems/sass-3.1.19/test/sass/logger_test.rb +58 -0
  146. data/vendor/bundle/gems/sass-3.1.19/test/sass/mock_importer.rb +49 -0
  147. data/vendor/bundle/gems/sass-3.1.19/test/sass/more_results/more1.css +9 -0
  148. data/vendor/bundle/gems/sass-3.1.19/test/sass/more_results/more1_with_line_comments.css +26 -0
  149. data/vendor/bundle/gems/sass-3.1.19/test/sass/more_results/more_import.css +29 -0
  150. data/vendor/bundle/gems/sass-3.1.19/test/sass/more_templates/_more_partial.sass +2 -0
  151. data/vendor/bundle/gems/sass-3.1.19/test/sass/more_templates/more1.sass +23 -0
  152. data/vendor/bundle/gems/sass-3.1.19/test/sass/more_templates/more_import.sass +11 -0
  153. data/vendor/bundle/gems/sass-3.1.19/test/sass/plugin_test.rb +496 -0
  154. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/alt.css +4 -0
  155. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/basic.css +9 -0
  156. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/compact.css +5 -0
  157. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/complex.css +86 -0
  158. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/compressed.css +1 -0
  159. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/expanded.css +19 -0
  160. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/if.css +3 -0
  161. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/import.css +31 -0
  162. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/import_charset.css +5 -0
  163. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/import_charset_1_8.css +5 -0
  164. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/import_charset_ibm866.css +5 -0
  165. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/line_numbers.css +49 -0
  166. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/mixins.css +95 -0
  167. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/multiline.css +24 -0
  168. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/nested.css +22 -0
  169. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/options.css +1 -0
  170. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/parent_ref.css +13 -0
  171. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/script.css +16 -0
  172. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/scss_import.css +31 -0
  173. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/scss_importee.css +2 -0
  174. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
  175. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/subdir/subdir.css +3 -0
  176. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/units.css +11 -0
  177. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/warn.css +0 -0
  178. data/vendor/bundle/gems/sass-3.1.19/test/sass/results/warn_imported.css +0 -0
  179. data/vendor/bundle/gems/sass-3.1.19/test/sass/script_conversion_test.rb +285 -0
  180. data/vendor/bundle/gems/sass-3.1.19/test/sass/script_test.rb +519 -0
  181. data/vendor/bundle/gems/sass-3.1.19/test/sass/scss/css_test.rb +975 -0
  182. data/vendor/bundle/gems/sass-3.1.19/test/sass/scss/rx_test.rb +156 -0
  183. data/vendor/bundle/gems/sass-3.1.19/test/sass/scss/scss_test.rb +1308 -0
  184. data/vendor/bundle/gems/sass-3.1.19/test/sass/scss/test_helper.rb +37 -0
  185. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/_double_import_loop2.sass +1 -0
  186. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/_imported_charset_ibm866.sass +4 -0
  187. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/_imported_charset_utf8.sass +4 -0
  188. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/_partial.sass +2 -0
  189. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/alt.sass +16 -0
  190. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/basic.sass +23 -0
  191. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/bork1.sass +2 -0
  192. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/bork2.sass +2 -0
  193. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/bork3.sass +2 -0
  194. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/bork4.sass +2 -0
  195. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/bork5.sass +3 -0
  196. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/compact.sass +17 -0
  197. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/complex.sass +305 -0
  198. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/compressed.sass +15 -0
  199. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/double_import_loop1.sass +1 -0
  200. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/expanded.sass +17 -0
  201. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/if.sass +11 -0
  202. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/import.sass +12 -0
  203. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/import_charset.sass +9 -0
  204. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/import_charset_1_8.sass +6 -0
  205. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/import_charset_ibm866.sass +11 -0
  206. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/importee.less +2 -0
  207. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/importee.sass +19 -0
  208. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/line_numbers.sass +13 -0
  209. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/mixin_bork.sass +5 -0
  210. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/mixins.sass +76 -0
  211. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/multiline.sass +20 -0
  212. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/nested.sass +25 -0
  213. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/nested_bork1.sass +2 -0
  214. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/nested_bork2.sass +2 -0
  215. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/nested_bork3.sass +2 -0
  216. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/nested_bork4.sass +2 -0
  217. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/nested_bork5.sass +2 -0
  218. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/nested_import.sass +2 -0
  219. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/nested_mixin_bork.sass +6 -0
  220. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/options.sass +2 -0
  221. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/parent_ref.sass +25 -0
  222. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/script.sass +101 -0
  223. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/scss_import.scss +11 -0
  224. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/scss_importee.scss +1 -0
  225. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/single_import_loop.sass +1 -0
  226. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
  227. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
  228. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/subdir/subdir.sass +6 -0
  229. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/units.sass +11 -0
  230. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/warn.sass +3 -0
  231. data/vendor/bundle/gems/sass-3.1.19/test/sass/templates/warn_imported.sass +4 -0
  232. data/vendor/bundle/gems/sass-3.1.19/test/sass/test_helper.rb +8 -0
  233. data/vendor/bundle/gems/sass-3.1.19/test/sass/util/multibyte_string_scanner_test.rb +147 -0
  234. data/vendor/bundle/gems/sass-3.1.19/test/sass/util/subset_map_test.rb +91 -0
  235. data/vendor/bundle/gems/sass-3.1.19/test/sass/util_test.rb +282 -0
  236. data/vendor/bundle/gems/sass-3.1.19/test/test_helper.rb +70 -0
  237. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/CHANGELOG.md +90 -0
  238. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/Gemfile +35 -0
  239. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/Guardfile +8 -0
  240. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/LICENSE +20 -0
  241. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/README.md +312 -0
  242. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/Rakefile +47 -0
  243. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/Vagrantfile +96 -0
  244. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen/adapter.rb +167 -0
  245. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen/adapters/darwin.rb +84 -0
  246. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen/adapters/linux.rb +110 -0
  247. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen/adapters/polling.rb +66 -0
  248. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen/adapters/windows.rb +81 -0
  249. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen/directory_record.rb +317 -0
  250. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen/listener.rb +203 -0
  251. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen/multi_listener.rb +121 -0
  252. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen/turnstile.rb +28 -0
  253. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen/version.rb +3 -0
  254. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/lib/listen.rb +38 -0
  255. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/listen.gemspec +26 -0
  256. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/listen/adapter_spec.rb +142 -0
  257. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/listen/adapters/darwin_spec.rb +31 -0
  258. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/listen/adapters/linux_spec.rb +41 -0
  259. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/listen/adapters/polling_spec.rb +68 -0
  260. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/listen/adapters/windows_spec.rb +24 -0
  261. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/listen/directory_record_spec.rb +1034 -0
  262. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/listen/listener_spec.rb +155 -0
  263. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/listen/multi_listener_spec.rb +156 -0
  264. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/listen/turnstile_spec.rb +56 -0
  265. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/listen_spec.rb +73 -0
  266. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/spec_helper.rb +16 -0
  267. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/support/adapter_helper.rb +716 -0
  268. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/support/directory_record_helper.rb +55 -0
  269. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/support/fixtures_helper.rb +29 -0
  270. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/support/listeners_helper.rb +144 -0
  271. data/vendor/bundle/gems/sass-3.1.19/vendor/listen/spec/support/platform_helper.rb +11 -0
  272. data/vendor/bundle/gems/therubyracer-0.10.1/.gitignore +13 -0
  273. data/vendor/bundle/gems/therubyracer-0.10.1/.gitmodules +3 -0
  274. data/vendor/bundle/gems/therubyracer-0.10.1/.travis.yml +9 -0
  275. data/vendor/bundle/gems/therubyracer-0.10.1/.yardopts +1 -0
  276. data/vendor/bundle/gems/therubyracer-0.10.1/Changelog.md +196 -0
  277. data/vendor/bundle/gems/therubyracer-0.10.1/Gemfile +1 -0
  278. data/vendor/bundle/gems/therubyracer-0.10.1/README.md +167 -0
  279. data/vendor/bundle/gems/therubyracer-0.10.1/Rakefile +23 -0
  280. data/vendor/bundle/gems/therubyracer-0.10.1/bin/therubyracer +11 -0
  281. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/Makefile +213 -0
  282. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/extconf.rb +26 -0
  283. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/gem_make.out +156 -0
  284. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/rr.cpp +189 -0
  285. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/rr.h +41 -0
  286. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8.cpp +48 -0
  287. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_array.cpp +48 -0
  288. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_array.h +8 -0
  289. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_callbacks.cpp +81 -0
  290. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_callbacks.h +8 -0
  291. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_context.cpp +92 -0
  292. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_context.h +6 -0
  293. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_date.cpp +34 -0
  294. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_date.h +6 -0
  295. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_debug.cpp +17 -0
  296. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_debug.h +6 -0
  297. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_exception.cpp +133 -0
  298. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_exception.h +11 -0
  299. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_external.cpp +70 -0
  300. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_external.h +8 -0
  301. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_function.cpp +69 -0
  302. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_function.h +11 -0
  303. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_handle.cpp +186 -0
  304. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_handle.h +48 -0
  305. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_locker.cpp +139 -0
  306. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_locker.h +6 -0
  307. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_message.cpp +67 -0
  308. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_message.h +10 -0
  309. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_object.cpp +122 -0
  310. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_object.h +10 -0
  311. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_script.cpp +36 -0
  312. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_script.h +8 -0
  313. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_string.cpp +52 -0
  314. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_string.h +9 -0
  315. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_template.cpp +344 -0
  316. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_template.h +8 -0
  317. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_try_catch.cpp +70 -0
  318. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_try_catch.h +5 -0
  319. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_v8.cpp +35 -0
  320. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_v8.h +6 -0
  321. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_value.cpp +175 -0
  322. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_value.h +10 -0
  323. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_weakref.cpp +61 -0
  324. data/vendor/bundle/gems/therubyracer-0.10.1/ext/v8/v8_weakref.h +29 -0
  325. data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/access.rb +87 -0
  326. data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/array.rb +17 -0
  327. data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/c/locker.rb +18 -0
  328. data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/cli.rb +133 -0
  329. data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/context.rb +111 -0
  330. data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/error.rb +130 -0
  331. data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/function.rb +44 -0
  332. data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/object.rb +69 -0
  333. data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/portal/caller.rb +37 -0
  334. data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/portal/constructor.rb +98 -0
  335. data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/portal/function.rb +63 -0
  336. data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/portal/interceptors.rb +152 -0
  337. data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/portal/proxies.rb +151 -0
  338. data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/portal/templates.rb +73 -0
  339. data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/portal.rb +86 -0
  340. data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/stack.rb +66 -0
  341. data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/tap.rb +9 -0
  342. data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8/version.rb +3 -0
  343. data/vendor/bundle/gems/therubyracer-0.10.1/lib/v8.rb +23 -0
  344. data/vendor/bundle/gems/therubyracer-0.10.1/spec/ext/array_spec.rb +15 -0
  345. data/vendor/bundle/gems/therubyracer-0.10.1/spec/ext/cxt_spec.rb +57 -0
  346. data/vendor/bundle/gems/therubyracer-0.10.1/spec/ext/ext_spec_helper.rb +27 -0
  347. data/vendor/bundle/gems/therubyracer-0.10.1/spec/ext/func_spec.rb +64 -0
  348. data/vendor/bundle/gems/therubyracer-0.10.1/spec/ext/object_spec.rb +10 -0
  349. data/vendor/bundle/gems/therubyracer-0.10.1/spec/ext/string_spec.rb +11 -0
  350. data/vendor/bundle/gems/therubyracer-0.10.1/spec/ext/try_catch_spec.rb +60 -0
  351. data/vendor/bundle/gems/therubyracer-0.10.1/spec/redjs/.gitignore +1 -0
  352. data/vendor/bundle/gems/therubyracer-0.10.1/spec/redjs/README.txt +8 -0
  353. data/vendor/bundle/gems/therubyracer-0.10.1/spec/redjs/jsapi_spec.rb +922 -0
  354. data/vendor/bundle/gems/therubyracer-0.10.1/spec/redjs/loadme.js +1 -0
  355. data/vendor/bundle/gems/therubyracer-0.10.1/spec/redjs_helper.rb +3 -0
  356. data/vendor/bundle/gems/therubyracer-0.10.1/spec/spec_helper.rb +9 -0
  357. data/vendor/bundle/gems/therubyracer-0.10.1/spec/v8/error_spec.rb +131 -0
  358. data/vendor/bundle/gems/therubyracer-0.10.1/spec/v8/portal/proxies_spec.rb +106 -0
  359. data/vendor/bundle/gems/therubyracer-0.10.1/specmem/handle_memspec.rb +41 -0
  360. data/vendor/bundle/gems/therubyracer-0.10.1/specmem/object_memspec.rb +14 -0
  361. data/vendor/bundle/gems/therubyracer-0.10.1/specmem/proxies_memspec.rb +49 -0
  362. data/vendor/bundle/gems/therubyracer-0.10.1/specmem/spec_helper.rb +24 -0
  363. data/vendor/bundle/gems/therubyracer-0.10.1/specthread/spec_helper.rb +2 -0
  364. data/vendor/bundle/gems/therubyracer-0.10.1/specthread/threading_spec.rb +13 -0
  365. data/vendor/bundle/gems/therubyracer-0.10.1/thefrontside.png +0 -0
  366. data/vendor/bundle/gems/therubyracer-0.10.1/therubyracer.gemspec +29 -0
  367. data/vendor/bundle/specifications/libv8-3.3.10.4-x86_64-darwin-11.gemspec +33 -0
  368. data/vendor/bundle/specifications/sass-3.1.19.gemspec +35 -0
  369. metadata +365 -3
@@ -0,0 +1,2730 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+ require File.dirname(__FILE__) + '/../test_helper'
4
+ require File.dirname(__FILE__) + '/test_helper'
5
+ require 'sass/engine'
6
+ require 'stringio'
7
+ require 'mock_importer'
8
+ require 'pathname'
9
+
10
+ module Sass::Script::Functions::UserFunctions
11
+ def option(name)
12
+ Sass::Script::String.new(@options[name.value.to_sym].to_s)
13
+ end
14
+ end
15
+
16
+ class SassEngineTest < Test::Unit::TestCase
17
+ FAKE_FILE_NAME = __FILE__.gsub(/rb$/,"sass")
18
+ # A map of erroneous Sass documents to the error messages they should produce.
19
+ # The error messages may be arrays;
20
+ # if so, the second element should be the line number that should be reported for the error.
21
+ # If this isn't provided, the tests will assume the line number should be the last line of the document.
22
+ EXCEPTION_MAP = {
23
+ "$a: 1 + " => 'Invalid CSS after "1 +": expected expression (e.g. 1px, bold), was ""',
24
+ "$a: 1 + 2 +" => 'Invalid CSS after "1 + 2 +": expected expression (e.g. 1px, bold), was ""',
25
+ "$a: 1 + 2 + %" => 'Invalid CSS after "1 + 2 + ": expected expression (e.g. 1px, bold), was "%"',
26
+ "$a: foo(\"bar\"" => 'Invalid CSS after "foo("bar"": expected ")", was ""',
27
+ "$a: 1 }" => 'Invalid CSS after "1 ": expected expression (e.g. 1px, bold), was "}"',
28
+ "$a: 1 }foo\"" => 'Invalid CSS after "1 ": expected expression (e.g. 1px, bold), was "}foo""',
29
+ ":" => 'Invalid property: ":".',
30
+ ": a" => 'Invalid property: ": a".',
31
+ "a\n :b" => <<MSG,
32
+ Invalid property: ":b" (no value).
33
+ If ":b" should be a selector, use "\\:b" instead.
34
+ MSG
35
+ "a\n b:" => 'Invalid property: "b:" (no value).',
36
+ "a\n :b: c" => 'Invalid property: ":b: c".',
37
+ "a\n :b:c d" => 'Invalid property: ":b:c d".',
38
+ "a\n :b c;" => 'Invalid CSS after "c": expected expression (e.g. 1px, bold), was ";"',
39
+ "a\n b: c;" => 'Invalid CSS after "c": expected expression (e.g. 1px, bold), was ";"',
40
+ ".foo ^bar\n a: b" => ['Invalid CSS after ".foo ": expected selector, was "^bar"', 1],
41
+ "a\n @extend .foo ^bar" => 'Invalid CSS after ".foo ": expected selector, was "^bar"',
42
+ "a: b" => 'Properties are only allowed within rules, directives, or other properties.',
43
+ ":a b" => 'Properties are only allowed within rules, directives, or other properties.',
44
+ "$" => 'Invalid variable: "$".',
45
+ "$a" => 'Invalid variable: "$a".',
46
+ "$ a" => 'Invalid variable: "$ a".',
47
+ "$a b" => 'Invalid variable: "$a b".',
48
+ "$a: 1b + 2c" => "Incompatible units: 'c' and 'b'.",
49
+ "$a: 1b < 2c" => "Incompatible units: 'c' and 'b'.",
50
+ "$a: 1b > 2c" => "Incompatible units: 'c' and 'b'.",
51
+ "$a: 1b <= 2c" => "Incompatible units: 'c' and 'b'.",
52
+ "$a: 1b >= 2c" => "Incompatible units: 'c' and 'b'.",
53
+ "a\n b: 1b * 2c" => "2b*c isn't a valid CSS value.",
54
+ "a\n b: 1b % 2c" => "Cannot modulo by a number with units: 2c.",
55
+ "$a: 2px + #ccc" => "Cannot add a number with units (2px) to a color (#cccccc).",
56
+ "$a: #ccc + 2px" => "Cannot add a number with units (2px) to a color (#cccccc).",
57
+ "& a\n :b c" => ["Base-level rules cannot contain the parent-selector-referencing character '&'.", 1],
58
+ "a\n :b\n c" => "Illegal nesting: Only properties may be nested beneath properties.",
59
+ "$a: b\n :c d\n" => "Illegal nesting: Nothing may be nested beneath variable declarations.",
60
+ "$a: b\n :c d\n" => "Illegal nesting: Nothing may be nested beneath variable declarations.",
61
+ "@import templates/basic\n foo" => "Illegal nesting: Nothing may be nested beneath import directives.",
62
+ "foo\n @import foo.css" => "CSS import directives may only be used at the root of a document.",
63
+ "@if true\n @import foo" => "Import directives may not be used within control directives or mixins.",
64
+ "@if true\n .foo\n @import foo" => "Import directives may not be used within control directives or mixins.",
65
+ "@mixin foo\n @import foo" => "Import directives may not be used within control directives or mixins.",
66
+ "@mixin foo\n .foo\n @import foo" => "Import directives may not be used within control directives or mixins.",
67
+ "@import foo;" => "Invalid @import: expected end of line, was \";\".",
68
+ '$foo: "bar" "baz" !' => %Q{Invalid CSS after ""bar" "baz" ": expected expression (e.g. 1px, bold), was "!"},
69
+ '$foo: "bar" "baz" $' => %Q{Invalid CSS after ""bar" "baz" ": expected expression (e.g. 1px, bold), was "$"},
70
+ "=foo\n :color red\n.bar\n +bang" => "Undefined mixin 'bang'.",
71
+ "=foo\n :color red\n.bar\n +bang_bop" => "Undefined mixin 'bang_bop'.",
72
+ "=foo\n :color red\n.bar\n +bang-bop" => "Undefined mixin 'bang-bop'.",
73
+ ".bar\n =foo\n :color red\n" => ["Mixins may only be defined at the root of a document.", 2],
74
+ "=foo\n :color red\n.bar\n +foo\n :color red" => "Illegal nesting: Nothing may be nested beneath mixin directives.",
75
+ " a\n b: c" => ["Indenting at the beginning of the document is illegal.", 1],
76
+ " \n \n\t\n a\n b: c" => ["Indenting at the beginning of the document is illegal.", 4],
77
+ "a\n b: c\n b: c" => ["Inconsistent indentation: 1 space was used for indentation, but the rest of the document was indented using 2 spaces.", 3],
78
+ "a\n b: c\na\n b: c" => ["Inconsistent indentation: 1 space was used for indentation, but the rest of the document was indented using 2 spaces.", 4],
79
+ "a\n\t\tb: c\n\tb: c" => ["Inconsistent indentation: 1 tab was used for indentation, but the rest of the document was indented using 2 tabs.", 3],
80
+ "a\n b: c\n b: c" => ["Inconsistent indentation: 3 spaces were used for indentation, but the rest of the document was indented using 2 spaces.", 3],
81
+ "a\n b: c\n a\n d: e" => ["Inconsistent indentation: 3 spaces were used for indentation, but the rest of the document was indented using 2 spaces.", 4],
82
+ "a\n b: c\na\n d: e" => ["The line was indented 2 levels deeper than the previous line.", 4],
83
+ "a\n b: c\n a\n d: e" => ["The line was indented 3 levels deeper than the previous line.", 4],
84
+ "a\n \tb: c" => ["Indentation can't use both tabs and spaces.", 2],
85
+ "=a(" => 'Invalid CSS after "(": expected variable (e.g. $foo), was ""',
86
+ "=a(b)" => 'Invalid CSS after "(": expected variable (e.g. $foo), was "b)"',
87
+ "=a(,)" => 'Invalid CSS after "(": expected variable (e.g. $foo), was ",)"',
88
+ "=a($)" => 'Invalid CSS after "(": expected variable (e.g. $foo), was "$)"',
89
+ "=a($foo bar)" => 'Invalid CSS after "($foo ": expected ")", was "bar)"',
90
+ "=foo\n bar: baz\n+foo" => ["Properties are only allowed within rules, directives, or other properties.", 2],
91
+ "a-\#{$b\n c: d" => ['Invalid CSS after "a-#{$b": expected "}", was ""', 1],
92
+ "=a($b: 1, $c)" => "Required argument $c must come before any optional arguments.",
93
+ "=a($b: 1)\n a: $b\ndiv\n +a(1,2)" => "Mixin a takes 1 argument but 2 were passed.",
94
+ "=a($b: 1)\n a: $b\ndiv\n +a(1,$c: 3)" => "Mixin a doesn't have an argument named $c",
95
+ "=a($b)\n a: $b\ndiv\n +a" => "Mixin a is missing parameter $b.",
96
+ "@function foo()\n 1 + 2" => "Functions can only contain variable declarations and control directives.",
97
+ "@function foo()\n foo: bar" => "Functions can only contain variable declarations and control directives.",
98
+ "@function foo()\n foo: bar\n @return 3" => ["Functions can only contain variable declarations and control directives.", 2],
99
+ "@function foo\n @return 1" => ['Invalid CSS after "": expected "(", was ""', 1],
100
+ "@function foo(\n @return 1" => ['Invalid CSS after "(": expected variable (e.g. $foo), was ""', 1],
101
+ "@function foo(b)\n @return 1" => ['Invalid CSS after "(": expected variable (e.g. $foo), was "b)"', 1],
102
+ "@function foo(,)\n @return 1" => ['Invalid CSS after "(": expected variable (e.g. $foo), was ",)"', 1],
103
+ "@function foo($)\n @return 1" => ['Invalid CSS after "(": expected variable (e.g. $foo), was "$)"', 1],
104
+ "@function foo()\n @return" => 'Invalid @return: expected expression.',
105
+ "@function foo()\n @return 1\n $var: val" => 'Illegal nesting: Nothing may be nested beneath return directives.',
106
+ "foo\n @function bar()\n @return 1" => ['Functions may only be defined at the root of a document.', 2],
107
+ "@function foo($a)\n @return 1\na\n b: foo()" => 'Function foo is missing parameter $a.',
108
+ "@function foo()\n @return 1\na\n b: foo(2)" => 'Wrong number of arguments (1 for 0) for `foo\'',
109
+ "@return 1" => '@return may only be used within a function.',
110
+ "@if true\n @return 1" => '@return may only be used within a function.',
111
+ "@mixin foo\n @return 1\n@include foo" => ['@return may only be used within a function.', 2],
112
+ "@else\n a\n b: c" => ["@else must come after @if.", 1],
113
+ "@if false\n@else foo" => "Invalid else directive '@else foo': expected 'if <expr>'.",
114
+ "@if false\n@else if " => "Invalid else directive '@else if': expected 'if <expr>'.",
115
+ "a\n $b: 12\nc\n d: $b" => 'Undefined variable: "$b".',
116
+ "=foo\n $b: 12\nc\n +foo\n d: $b" => 'Undefined variable: "$b".',
117
+ "c\n d: $b-foo" => 'Undefined variable: "$b-foo".',
118
+ "c\n d: $b_foo" => 'Undefined variable: "$b_foo".',
119
+ '@for $a from "foo" to 1' => '"foo" is not an integer.',
120
+ '@for $a from 1 to "2"' => '"2" is not an integer.',
121
+ '@for $a from 1 to "foo"' => '"foo" is not an integer.',
122
+ '@for $a from 1 to 1.232323' => '1.232 is not an integer.',
123
+ '@for $a from 1px to 3em' => "Incompatible units: 'em' and 'px'.",
124
+ '@if' => "Invalid if directive '@if': expected expression.",
125
+ '@while' => "Invalid while directive '@while': expected expression.",
126
+ '@debug' => "Invalid debug directive '@debug': expected expression.",
127
+ %Q{@debug "a message"\n "nested message"} => "Illegal nesting: Nothing may be nested beneath debug directives.",
128
+ '@warn' => "Invalid warn directive '@warn': expected expression.",
129
+ %Q{@warn "a message"\n "nested message"} => "Illegal nesting: Nothing may be nested beneath warn directives.",
130
+ "/* foo\n bar\n baz" => "Inconsistent indentation: previous line was indented by 4 spaces, but this line was indented by 2 spaces.",
131
+ '+foo(1 + 1: 2)' => 'Invalid CSS after "(1 + 1": expected comma, was ": 2)"',
132
+ '+foo($var: )' => 'Invalid CSS after "($var: ": expected mixin argument, was ")"',
133
+ '+foo($var: a, $var: b)' => 'Keyword argument "$var" passed more than once',
134
+ '+foo($var-var: a, $var_var: b)' => 'Keyword argument "$var-var" passed more than once',
135
+ '+foo($var_var: a, $var-var: b)' => 'Keyword argument "$var_var" passed more than once',
136
+ "a\n b: foo(1 + 1: 2)" => 'Invalid CSS after "foo(1 + 1": expected comma, was ": 2)"',
137
+ "a\n b: foo($var: )" => 'Invalid CSS after "foo($var: ": expected function argument, was ")"',
138
+ "a\n b: foo($var: a, $var: b)" => 'Keyword argument "$var" passed more than once',
139
+ "a\n b: foo($var-var: a, $var_var: b)" => 'Keyword argument "$var-var" passed more than once',
140
+ "a\n b: foo($var_var: a, $var-var: b)" => 'Keyword argument "$var_var" passed more than once',
141
+ "@if foo\n @extend .bar" => ["Extend directives may only be used within rules.", 2],
142
+ "$var: true\n@while $var\n @extend .bar\n $var: false" => ["Extend directives may only be used within rules.", 3],
143
+ "@for $i from 0 to 1\n @extend .bar" => ["Extend directives may only be used within rules.", 2],
144
+ "@mixin foo\n @extend .bar\n@include foo" => ["Extend directives may only be used within rules.", 2],
145
+ "@import \"foo\" // bar" => "Invalid @import: \"\"foo\" // bar\"",
146
+
147
+ # Regression tests
148
+ "a\n b:\n c\n d" => ["Illegal nesting: Only properties may be nested beneath properties.", 3],
149
+ "& foo\n bar: baz\n blat: bang" => ["Base-level rules cannot contain the parent-selector-referencing character '&'.", 1],
150
+ "a\n b: c\n& foo\n bar: baz\n blat: bang" => ["Base-level rules cannot contain the parent-selector-referencing character '&'.", 3],
151
+ }
152
+
153
+ def teardown
154
+ clean_up_sassc
155
+ end
156
+
157
+ def test_basic_render
158
+ renders_correctly "basic", { :style => :compact }
159
+ end
160
+
161
+ def test_empty_render
162
+ assert_equal "", render("")
163
+ end
164
+
165
+ def test_multiple_calls_to_render
166
+ sass = Sass::Engine.new("a\n b: c")
167
+ assert_equal sass.render, sass.render
168
+ end
169
+
170
+ def test_alternate_styles
171
+ renders_correctly "expanded", { :style => :expanded }
172
+ renders_correctly "compact", { :style => :compact }
173
+ renders_correctly "nested", { :style => :nested }
174
+ renders_correctly "compressed", { :style => :compressed }
175
+ end
176
+
177
+ def test_compile
178
+ assert_equal "div { hello: world; }\n", Sass.compile("$who: world\ndiv\n hello: $who", :syntax => :sass, :style => :compact)
179
+ assert_equal "div { hello: world; }\n", Sass.compile("$who: world; div { hello: $who }", :style => :compact)
180
+ end
181
+
182
+ def test_compile_file
183
+ FileUtils.mkdir_p(absolutize("tmp"))
184
+ open(absolutize("tmp/test_compile_file.sass"), "w") {|f| f.write("$who: world\ndiv\n hello: $who")}
185
+ open(absolutize("tmp/test_compile_file.scss"), "w") {|f| f.write("$who: world; div { hello: $who }")}
186
+ assert_equal "div { hello: world; }\n", Sass.compile_file(absolutize("tmp/test_compile_file.sass"), :style => :compact)
187
+ assert_equal "div { hello: world; }\n", Sass.compile_file(absolutize("tmp/test_compile_file.scss"), :style => :compact)
188
+ ensure
189
+ FileUtils.rm_rf(absolutize("tmp"))
190
+ end
191
+
192
+ def test_compile_file_to_css_file
193
+ FileUtils.mkdir_p(absolutize("tmp"))
194
+ open(absolutize("tmp/test_compile_file.sass"), "w") {|f| f.write("$who: world\ndiv\n hello: $who")}
195
+ open(absolutize("tmp/test_compile_file.scss"), "w") {|f| f.write("$who: world; div { hello: $who }")}
196
+ Sass.compile_file(absolutize("tmp/test_compile_file.sass"), absolutize("tmp/test_compile_file_sass.css"), :style => :compact)
197
+ Sass.compile_file(absolutize("tmp/test_compile_file.scss"), absolutize("tmp/test_compile_file_scss.css"), :style => :compact)
198
+ assert_equal "div { hello: world; }\n", File.read(absolutize("tmp/test_compile_file_sass.css"))
199
+ assert_equal "div { hello: world; }\n", File.read(absolutize("tmp/test_compile_file_scss.css"))
200
+ ensure
201
+ FileUtils.rm_rf(absolutize("tmp"))
202
+ end
203
+
204
+ def test_flexible_tabulation
205
+ assert_equal("p {\n a: b; }\n p q {\n c: d; }\n",
206
+ render("p\n a: b\n q\n c: d\n"))
207
+ assert_equal("p {\n a: b; }\n p q {\n c: d; }\n",
208
+ render("p\n\ta: b\n\tq\n\t\tc: d\n"))
209
+ end
210
+
211
+ EXCEPTION_MAP.each do |key, value|
212
+ define_method("test_exception (#{key.inspect})") do
213
+ line = 10
214
+ begin
215
+ silence_warnings {Sass::Engine.new(key, :filename => FAKE_FILE_NAME, :line => line).render}
216
+ rescue Sass::SyntaxError => err
217
+ value = [value] unless value.is_a?(Array)
218
+
219
+ assert_equal(value.first.rstrip, err.message, "Line: #{key}")
220
+ assert_equal(FAKE_FILE_NAME, err.sass_filename)
221
+ assert_equal((value[1] || key.split("\n").length) + line - 1, err.sass_line, "Line: #{key}")
222
+ assert_match(/#{Regexp.escape(FAKE_FILE_NAME)}:[0-9]+/, err.backtrace[0], "Line: #{key}")
223
+ else
224
+ assert(false, "Exception not raised for\n#{key}")
225
+ end
226
+ end
227
+ end
228
+
229
+ def test_exception_line
230
+ to_render = <<SASS
231
+ rule
232
+ :prop val
233
+ // comment!
234
+
235
+ :broken
236
+ SASS
237
+ begin
238
+ Sass::Engine.new(to_render).render
239
+ rescue Sass::SyntaxError => err
240
+ assert_equal(5, err.sass_line)
241
+ else
242
+ assert(false, "Exception not raised for '#{to_render}'!")
243
+ end
244
+ end
245
+
246
+ def test_exception_location
247
+ to_render = <<SASS
248
+ rule
249
+ :prop val
250
+ // comment!
251
+
252
+ :broken
253
+ SASS
254
+ begin
255
+ Sass::Engine.new(to_render, :filename => FAKE_FILE_NAME, :line => (__LINE__-7)).render
256
+ rescue Sass::SyntaxError => err
257
+ assert_equal(FAKE_FILE_NAME, err.sass_filename)
258
+ assert_equal((__LINE__-6), err.sass_line)
259
+ else
260
+ assert(false, "Exception not raised for '#{to_render}'!")
261
+ end
262
+ end
263
+
264
+ def test_imported_exception
265
+ [1, 2, 3, 4, 5].each do |i|
266
+ begin
267
+ Sass::Engine.new("@import bork#{i}", :load_paths => [File.dirname(__FILE__) + '/templates/']).render
268
+ rescue Sass::SyntaxError => err
269
+ assert_equal(2, err.sass_line)
270
+ assert_match(/(\/|^)bork#{i}\.sass$/, err.sass_filename)
271
+
272
+ assert_hash_has(err.sass_backtrace.first,
273
+ :filename => err.sass_filename, :line => err.sass_line)
274
+
275
+ assert_nil(err.sass_backtrace[1][:filename])
276
+ assert_equal(1, err.sass_backtrace[1][:line])
277
+
278
+ assert_match(/(\/|^)bork#{i}\.sass:2$/, err.backtrace.first)
279
+ assert_equal("(sass):1", err.backtrace[1])
280
+ else
281
+ assert(false, "Exception not raised for imported template: bork#{i}")
282
+ end
283
+ end
284
+ end
285
+
286
+ def test_double_imported_exception
287
+ [1, 2, 3, 4, 5].each do |i|
288
+ begin
289
+ Sass::Engine.new("@import nested_bork#{i}", :load_paths => [File.dirname(__FILE__) + '/templates/']).render
290
+ rescue Sass::SyntaxError => err
291
+ assert_equal(2, err.sass_line)
292
+ assert_match(/(\/|^)bork#{i}\.sass$/, err.sass_filename)
293
+
294
+ assert_hash_has(err.sass_backtrace.first,
295
+ :filename => err.sass_filename, :line => err.sass_line)
296
+
297
+ assert_match(/(\/|^)nested_bork#{i}\.sass$/, err.sass_backtrace[1][:filename])
298
+ assert_equal(2, err.sass_backtrace[1][:line])
299
+
300
+ assert_nil(err.sass_backtrace[2][:filename])
301
+ assert_equal(1, err.sass_backtrace[2][:line])
302
+
303
+ assert_match(/(\/|^)bork#{i}\.sass:2$/, err.backtrace.first)
304
+ assert_match(/(\/|^)nested_bork#{i}\.sass:2$/, err.backtrace[1])
305
+ assert_equal("(sass):1", err.backtrace[2])
306
+ else
307
+ assert(false, "Exception not raised for imported template: bork#{i}")
308
+ end
309
+ end
310
+ end
311
+
312
+ def test_selector_tracing
313
+ actual_css = render(<<-SCSS, :syntax => :scss, :trace_selectors => true)
314
+ @mixin mixed {
315
+ .mixed { color: red; }
316
+ }
317
+ .context {
318
+ @include mixed;
319
+ }
320
+ SCSS
321
+ assert_equal(<<CSS,actual_css)
322
+ /* on line 2 of test_selector_tracing_inline.scss, in `mixed'
323
+ from line 5 of test_selector_tracing_inline.scss */
324
+ .context .mixed {
325
+ color: red; }
326
+ CSS
327
+ end
328
+
329
+ def test_mixin_exception
330
+ render(<<SASS)
331
+ =error-mixin($a)
332
+ color: $a * 1em * 1px
333
+
334
+ =outer-mixin($a)
335
+ +error-mixin($a)
336
+
337
+ .error
338
+ +outer-mixin(12)
339
+ SASS
340
+ assert(false, "Exception not raised")
341
+ rescue Sass::SyntaxError => err
342
+ assert_equal(2, err.sass_line)
343
+ assert_equal(filename_for_test, err.sass_filename)
344
+ assert_equal("error-mixin", err.sass_mixin)
345
+
346
+ assert_hash_has(err.sass_backtrace.first, :line => err.sass_line,
347
+ :filename => err.sass_filename, :mixin => err.sass_mixin)
348
+ assert_hash_has(err.sass_backtrace[1], :line => 5,
349
+ :filename => filename_for_test, :mixin => "outer-mixin")
350
+ assert_hash_has(err.sass_backtrace[2], :line => 8,
351
+ :filename => filename_for_test, :mixin => nil)
352
+
353
+ assert_equal("#{filename_for_test}:2:in `error-mixin'", err.backtrace.first)
354
+ assert_equal("#{filename_for_test}:5:in `outer-mixin'", err.backtrace[1])
355
+ assert_equal("#{filename_for_test}:8", err.backtrace[2])
356
+ end
357
+
358
+ def test_mixin_callsite_exception
359
+ render(<<SASS)
360
+ =one-arg-mixin($a)
361
+ color: $a
362
+
363
+ =outer-mixin($a)
364
+ +one-arg-mixin($a, 12)
365
+
366
+ .error
367
+ +outer-mixin(12)
368
+ SASS
369
+ assert(false, "Exception not raised")
370
+ rescue Sass::SyntaxError => err
371
+ assert_hash_has(err.sass_backtrace.first, :line => 5,
372
+ :filename => filename_for_test, :mixin => "one-arg-mixin")
373
+ assert_hash_has(err.sass_backtrace[1], :line => 5,
374
+ :filename => filename_for_test, :mixin => "outer-mixin")
375
+ assert_hash_has(err.sass_backtrace[2], :line => 8,
376
+ :filename => filename_for_test, :mixin => nil)
377
+ end
378
+
379
+ def test_mixin_exception_cssize
380
+ render(<<SASS)
381
+ =parent-ref-mixin
382
+ & foo
383
+ a: b
384
+
385
+ =outer-mixin
386
+ +parent-ref-mixin
387
+
388
+ +outer-mixin
389
+ SASS
390
+ assert(false, "Exception not raised")
391
+ rescue Sass::SyntaxError => err
392
+ assert_hash_has(err.sass_backtrace.first, :line => 2,
393
+ :filename => filename_for_test, :mixin => "parent-ref-mixin")
394
+ assert_hash_has(err.sass_backtrace[1], :line => 6,
395
+ :filename => filename_for_test, :mixin => "outer-mixin")
396
+ assert_hash_has(err.sass_backtrace[2], :line => 8,
397
+ :filename => filename_for_test, :mixin => nil)
398
+ end
399
+
400
+ def test_mixin_and_import_exception
401
+ Sass::Engine.new("@import nested_mixin_bork", :load_paths => [File.dirname(__FILE__) + '/templates/']).render
402
+ assert(false, "Exception not raised")
403
+ rescue Sass::SyntaxError => err
404
+ assert_match(/(\/|^)nested_mixin_bork\.sass$/, err.sass_backtrace.first[:filename])
405
+ assert_hash_has(err.sass_backtrace.first, :mixin => "error-mixin", :line => 4)
406
+
407
+ assert_match(/(\/|^)mixin_bork\.sass$/, err.sass_backtrace[1][:filename])
408
+ assert_hash_has(err.sass_backtrace[1], :mixin => "outer-mixin", :line => 2)
409
+
410
+ assert_match(/(\/|^)mixin_bork\.sass$/, err.sass_backtrace[2][:filename])
411
+ assert_hash_has(err.sass_backtrace[2], :mixin => nil, :line => 5)
412
+
413
+ assert_match(/(\/|^)nested_mixin_bork\.sass$/, err.sass_backtrace[3][:filename])
414
+ assert_hash_has(err.sass_backtrace[3], :mixin => nil, :line => 6)
415
+
416
+ assert_hash_has(err.sass_backtrace[4], :filename => nil, :mixin => nil, :line => 1)
417
+ end
418
+
419
+ def test_basic_mixin_loop_exception
420
+ render <<SASS
421
+ @mixin foo
422
+ @include foo
423
+ @include foo
424
+ SASS
425
+ assert(false, "Exception not raised")
426
+ rescue Sass::SyntaxError => err
427
+ assert_equal("An @include loop has been found: foo includes itself", err.message)
428
+ assert_hash_has(err.sass_backtrace[0], :mixin => "foo", :line => 2)
429
+ end
430
+
431
+ def test_double_mixin_loop_exception
432
+ render <<SASS
433
+ @mixin foo
434
+ @include bar
435
+ @mixin bar
436
+ @include foo
437
+ @include foo
438
+ SASS
439
+ assert(false, "Exception not raised")
440
+ rescue Sass::SyntaxError => err
441
+ assert_equal(<<MESSAGE.rstrip, err.message)
442
+ An @include loop has been found:
443
+ foo includes bar
444
+ bar includes foo
445
+ MESSAGE
446
+ assert_hash_has(err.sass_backtrace[0], :mixin => "bar", :line => 4)
447
+ assert_hash_has(err.sass_backtrace[1], :mixin => "foo", :line => 2)
448
+ end
449
+
450
+ def test_deep_mixin_loop_exception
451
+ render <<SASS
452
+ @mixin foo
453
+ @include bar
454
+
455
+ @mixin bar
456
+ @include baz
457
+
458
+ @mixin baz
459
+ @include foo
460
+
461
+ @include foo
462
+ SASS
463
+ assert(false, "Exception not raised")
464
+ rescue Sass::SyntaxError => err
465
+ assert_equal(<<MESSAGE.rstrip, err.message)
466
+ An @include loop has been found:
467
+ foo includes bar
468
+ bar includes baz
469
+ baz includes foo
470
+ MESSAGE
471
+ assert_hash_has(err.sass_backtrace[0], :mixin => "baz", :line => 8)
472
+ assert_hash_has(err.sass_backtrace[1], :mixin => "bar", :line => 5)
473
+ assert_hash_has(err.sass_backtrace[2], :mixin => "foo", :line => 2)
474
+ end
475
+
476
+ def test_basic_import_loop_exception
477
+ import = filename_for_test
478
+ importer = MockImporter.new
479
+ importer.add_import(import, "@import '#{import}'")
480
+
481
+ engine = Sass::Engine.new("@import '#{import}'", :filename => import,
482
+ :load_paths => [importer])
483
+
484
+ assert_raise_message(Sass::SyntaxError, <<ERR.rstrip) {engine.render}
485
+ An @import loop has been found: #{import} imports itself
486
+ ERR
487
+ end
488
+
489
+ def test_double_import_loop_exception
490
+ importer = MockImporter.new
491
+ importer.add_import("foo", "@import 'bar'")
492
+ importer.add_import("bar", "@import 'foo'")
493
+
494
+ engine = Sass::Engine.new('@import "foo"', :filename => filename_for_test,
495
+ :load_paths => [importer])
496
+
497
+ assert_raise_message(Sass::SyntaxError, <<ERR.rstrip) {engine.render}
498
+ An @import loop has been found:
499
+ #{filename_for_test} imports foo
500
+ foo imports bar
501
+ bar imports foo
502
+ ERR
503
+ end
504
+
505
+ def test_deep_import_loop_exception
506
+ importer = MockImporter.new
507
+ importer.add_import("foo", "@import 'bar'")
508
+ importer.add_import("bar", "@import 'baz'")
509
+ importer.add_import("baz", "@import 'foo'")
510
+
511
+ engine = Sass::Engine.new('@import "foo"', :filename => filename_for_test,
512
+ :load_paths => [importer])
513
+
514
+ assert_raise_message(Sass::SyntaxError, <<ERR.rstrip) {engine.render}
515
+ An @import loop has been found:
516
+ #{filename_for_test} imports foo
517
+ foo imports bar
518
+ bar imports baz
519
+ baz imports foo
520
+ ERR
521
+ end
522
+
523
+ def test_exception_css_with_offset
524
+ opts = {:full_exception => true, :line => 362}
525
+ render(("a\n b: c\n" * 10) + "d\n e:\n" + ("f\n g: h\n" * 10), opts)
526
+ rescue Sass::SyntaxError => e
527
+ assert_equal(<<CSS, Sass::SyntaxError.exception_to_css(e, opts).split("\n")[0..15].join("\n"))
528
+ /*
529
+ Syntax error: Invalid property: "e:" (no value).
530
+ on line 383 of test_exception_css_with_offset_inline.sass
531
+
532
+ 378: a
533
+ 379: b: c
534
+ 380: a
535
+ 381: b: c
536
+ 382: d
537
+ 383: e:
538
+ 384: f
539
+ 385: g: h
540
+ 386: f
541
+ 387: g: h
542
+ 388: f
543
+ CSS
544
+ else
545
+ assert(false, "Exception not raised for test_exception_css_with_offset")
546
+ end
547
+
548
+ def test_exception_css_with_mixins
549
+ opts = {:full_exception => true}
550
+ render(<<SASS, opts)
551
+ =error-mixin($a)
552
+ color: $a * 1em * 1px
553
+
554
+ =outer-mixin($a)
555
+ +error-mixin($a)
556
+
557
+ .error
558
+ +outer-mixin(12)
559
+ SASS
560
+ rescue Sass::SyntaxError => e
561
+ assert_equal(<<CSS, Sass::SyntaxError.exception_to_css(e, opts).split("\n")[0..13].join("\n"))
562
+ /*
563
+ Syntax error: 12em*px isn't a valid CSS value.
564
+ on line 2 of test_exception_css_with_mixins_inline.sass, in `error-mixin'
565
+ from line 5 of test_exception_css_with_mixins_inline.sass, in `outer-mixin'
566
+ from line 8 of test_exception_css_with_mixins_inline.sass
567
+
568
+ 1: =error-mixin($a)
569
+ 2: color: $a * 1em * 1px
570
+ 3:
571
+ 4: =outer-mixin($a)
572
+ 5: +error-mixin($a)
573
+ 6:
574
+ 7: .error
575
+ CSS
576
+ else
577
+ assert(false, "Exception not raised")
578
+ end
579
+
580
+ def test_cssize_exception_css
581
+ opts = {:full_exception => true}
582
+ render(<<SASS, opts)
583
+ .filler
584
+ stuff: "stuff!"
585
+
586
+ a: b
587
+
588
+ .more.filler
589
+ a: b
590
+ SASS
591
+ rescue Sass::SyntaxError => e
592
+ assert_equal(<<CSS, Sass::SyntaxError.exception_to_css(e, opts).split("\n")[0..11].join("\n"))
593
+ /*
594
+ Syntax error: Properties are only allowed within rules, directives, or other properties.
595
+ on line 4 of test_cssize_exception_css_inline.sass
596
+
597
+ 1: .filler
598
+ 2: stuff: "stuff!"
599
+ 3:
600
+ 4: a: b
601
+ 5:
602
+ 6: .more.filler
603
+ 7: a: b
604
+ CSS
605
+ else
606
+ assert(false, "Exception not raised")
607
+ end
608
+
609
+ def test_css_import
610
+ assert_equal("@import url(./fonts.css);\n", render("@import \"./fonts.css\""))
611
+ end
612
+
613
+ def test_http_import
614
+ assert_equal("@import \"http://fonts.googleapis.com/css?family=Droid+Sans\";\n",
615
+ render("@import \"http://fonts.googleapis.com/css?family=Droid+Sans\""))
616
+ end
617
+
618
+ def test_import_with_interpolation
619
+ assert_warning(<<WARNING) do
620
+ DEPRECATION WARNING on line 2 of test_import_with_interpolation_inline.sass:
621
+ @import directives using \#{} interpolation will need to use url() in Sass 3.2.
622
+ For example:
623
+
624
+ @import url("http://\#{$url}/style.css");
625
+ WARNING
626
+ assert_equal("@import \"http://fonts.googleapis.com/css?family=Droid+Sans\";\n",
627
+ render("$family: unquote(\"Droid+Sans\")\n@import \"http://fonts.googleapis.com/css?family=\#{$family}\"\n"))
628
+ end
629
+ assert_equal("@import url(\"http://fonts.googleapis.com/css?family=Droid+Sans\");\n",
630
+ render("$family: unquote(\"Droid+Sans\")\n@import url(\"http://fonts.googleapis.com/css?family=\#{$family}\")\n"))
631
+ end
632
+
633
+ def test_url_import
634
+ assert_equal("@import url(fonts.sass);\n", render("@import url(fonts.sass)"))
635
+ end
636
+
637
+ def test_sass_import
638
+ sassc_file = sassc_path("importee")
639
+ assert !File.exists?(sassc_file)
640
+ renders_correctly "import", { :style => :compact, :load_paths => [File.dirname(__FILE__) + "/templates"] }
641
+ assert File.exists?(sassc_file)
642
+ end
643
+
644
+ def test_sass_pathname_import
645
+ sassc_file = sassc_path("importee")
646
+ assert !File.exists?(sassc_file)
647
+ renders_correctly("import",
648
+ :style => :compact,
649
+ :load_paths => [Pathname.new(File.dirname(__FILE__) + "/templates")])
650
+ assert File.exists?(sassc_file)
651
+ end
652
+
653
+ def test_nonexistent_import
654
+ assert_raise_message(Sass::SyntaxError, <<ERR.rstrip) do
655
+ File to import not found or unreadable: nonexistent.sass.
656
+ Load path: #{Dir.pwd}
657
+ ERR
658
+ render("@import nonexistent.sass")
659
+ end
660
+ end
661
+
662
+ def test_nonexistent_extensionless_import
663
+ assert_raise_message(Sass::SyntaxError, <<ERR.rstrip) do
664
+ File to import not found or unreadable: nonexistent.
665
+ Load path: #{Dir.pwd}
666
+ ERR
667
+ render("@import nonexistent")
668
+ end
669
+ end
670
+
671
+ def test_no_cache
672
+ assert !File.exists?(sassc_path("importee"))
673
+ renders_correctly("import", {
674
+ :style => :compact, :cache => false,
675
+ :load_paths => [File.dirname(__FILE__) + "/templates"],
676
+ })
677
+ assert !File.exists?(sassc_path("importee"))
678
+ end
679
+
680
+ def test_import_in_rule
681
+ assert_equal(<<CSS, render(<<SASS, :load_paths => [File.dirname(__FILE__) + '/templates/']))
682
+ .foo #foo {
683
+ background-color: #bbaaff; }
684
+
685
+ .bar {
686
+ a: b; }
687
+ .bar #foo {
688
+ background-color: #bbaaff; }
689
+ CSS
690
+ .foo
691
+ @import partial
692
+
693
+ .bar
694
+ a: b
695
+ @import partial
696
+ SASS
697
+ end
698
+
699
+ def test_nested_import_with_toplevel_constructs
700
+ Sass::Engine.new(".foo\n @import importee", :load_paths => [File.dirname(__FILE__) + '/templates/']).render
701
+ rescue Sass::SyntaxError => err
702
+ assert_equal(3, err.sass_line)
703
+ assert_match(/(\/|^)importee\.sass$/, err.sass_filename)
704
+
705
+ assert_hash_has(err.sass_backtrace.first,
706
+ :filename => err.sass_filename, :line => err.sass_line)
707
+
708
+ assert_nil(err.sass_backtrace[1][:filename])
709
+ assert_equal(2, err.sass_backtrace[1][:line])
710
+
711
+ assert_match(/(\/|^)importee\.sass:3$/, err.backtrace.first)
712
+ assert_equal("(sass):2", err.backtrace[1])
713
+ else
714
+ assert(false, "Exception not raised for importing mixins nested")
715
+ end
716
+
717
+ def test_units
718
+ renders_correctly "units"
719
+ end
720
+
721
+ def test_default_function
722
+ assert_equal(<<CSS, render(<<SASS))
723
+ foo {
724
+ bar: url("foo.png"); }
725
+ CSS
726
+ foo
727
+ bar: url("foo.png")
728
+ SASS
729
+ assert_equal("foo {\n bar: url(); }\n", render("foo\n bar: url()\n"));
730
+ end
731
+
732
+ def test_string_minus
733
+ assert_equal("foo {\n bar: baz-boom-bat; }\n", render(%Q{foo\n bar: baz-boom-bat}))
734
+ assert_equal("foo {\n bar: -baz-boom; }\n", render(%Q{foo\n bar: -baz-boom}))
735
+ end
736
+
737
+ def test_string_div
738
+ assert_equal("foo {\n bar: baz/boom/bat; }\n", render(%Q{foo\n bar: baz/boom/bat}))
739
+ assert_equal("foo {\n bar: /baz/boom; }\n", render(%Q{foo\n bar: /baz/boom}))
740
+ end
741
+
742
+ def test_basic_multiline_selector
743
+ assert_equal("#foo #bar,\n#baz #boom {\n foo: bar; }\n",
744
+ render("#foo #bar,\n#baz #boom\n :foo bar"))
745
+ assert_equal("#foo #bar,\n#foo #baz {\n foo: bar; }\n",
746
+ render("#foo\n #bar,\n #baz\n :foo bar"))
747
+ assert_equal("#foo,\n#bar {\n foo: bar; }\n #foo #baz,\n #bar #baz {\n foo: bar; }\n",
748
+ render("#foo,\n#bar\n :foo bar\n #baz\n :foo bar"))
749
+ assert_equal("#foo #bar, #baz #boom { foo: bar; }\n",
750
+ render("#foo #bar,\n#baz #boom\n :foo bar", :style => :compact))
751
+
752
+ assert_equal("#foo #bar,#baz #boom{foo:bar}\n",
753
+ render("#foo #bar,\n#baz #boom\n :foo bar", :style => :compressed))
754
+
755
+ assert_equal("#foo #bar,\n#baz #boom {\n foo: bar; }\n",
756
+ render("#foo #bar,,\n,#baz #boom,\n :foo bar"))
757
+
758
+ assert_equal("#bip #bop {\n foo: bar; }\n",
759
+ render("#bip #bop,, ,\n :foo bar"))
760
+ end
761
+
762
+ def test_complex_multiline_selector
763
+ renders_correctly "multiline"
764
+ end
765
+
766
+ def test_colon_only
767
+ begin
768
+ render("a\n b: c", :property_syntax => :old)
769
+ rescue Sass::SyntaxError => e
770
+ assert_equal("Illegal property syntax: can't use new syntax when :property_syntax => :old is set.",
771
+ e.message)
772
+ assert_equal(2, e.sass_line)
773
+ else
774
+ assert(false, "SyntaxError not raised for :property_syntax => :old")
775
+ end
776
+
777
+ begin
778
+ render("a\n :b c", :property_syntax => :new)
779
+ assert_equal(2, e.sass_line)
780
+ rescue Sass::SyntaxError => e
781
+ assert_equal("Illegal property syntax: can't use old syntax when :property_syntax => :new is set.",
782
+ e.message)
783
+ else
784
+ assert(false, "SyntaxError not raised for :property_syntax => :new")
785
+ end
786
+ end
787
+
788
+ def test_pseudo_elements
789
+ assert_equal(<<CSS, render(<<SASS))
790
+ ::first-line {
791
+ size: 10em; }
792
+ CSS
793
+ ::first-line
794
+ size: 10em
795
+ SASS
796
+ end
797
+
798
+ def test_directive
799
+ assert_equal("@a b;\n", render("@a b"))
800
+
801
+ assert_equal("@a {\n b: c; }\n", render("@a\n :b c"))
802
+ assert_equal("@a { b: c; }\n", render("@a\n :b c", :style => :compact))
803
+ assert_equal("@a {\n b: c;\n}\n", render("@a\n :b c", :style => :expanded))
804
+ assert_equal("@a{b:c}\n", render("@a\n :b c", :style => :compressed))
805
+
806
+ assert_equal("@a {\n b: c;\n d: e; }\n",
807
+ render("@a\n :b c\n :d e"))
808
+ assert_equal("@a { b: c; d: e; }\n",
809
+ render("@a\n :b c\n :d e", :style => :compact))
810
+ assert_equal("@a {\n b: c;\n d: e;\n}\n",
811
+ render("@a\n :b c\n :d e", :style => :expanded))
812
+ assert_equal("@a{b:c;d:e}\n",
813
+ render("@a\n :b c\n :d e", :style => :compressed))
814
+
815
+ assert_equal("@a {\n #b {\n c: d; } }\n",
816
+ render("@a\n #b\n :c d"))
817
+ assert_equal("@a { #b { c: d; } }\n",
818
+ render("@a\n #b\n :c d", :style => :compact))
819
+ assert_equal("@a {\n #b {\n c: d;\n }\n}\n",
820
+ render("@a\n #b\n :c d", :style => :expanded))
821
+ assert_equal("@a{#b{c:d}}\n",
822
+ render("@a\n #b\n :c d", :style => :compressed))
823
+
824
+ assert_equal("@a {\n #b {\n a: b; }\n #b #c {\n d: e; } }\n",
825
+ render("@a\n #b\n :a b\n #c\n :d e"))
826
+ assert_equal("@a { #b { a: b; }\n #b #c { d: e; } }\n",
827
+ render("@a\n #b\n :a b\n #c\n :d e", :style => :compact))
828
+ assert_equal("@a {\n #b {\n a: b;\n }\n #b #c {\n d: e;\n }\n}\n",
829
+ render("@a\n #b\n :a b\n #c\n :d e", :style => :expanded))
830
+ assert_equal("@a{#b{a:b}#b #c{d:e}}\n",
831
+ render("@a\n #b\n :a b\n #c\n :d e", :style => :compressed))
832
+
833
+ assert_equal("@a {\n #foo,\n #bar {\n b: c; } }\n",
834
+ render("@a\n #foo, \n #bar\n :b c"))
835
+ assert_equal("@a { #foo, #bar { b: c; } }\n",
836
+ render("@a\n #foo, \n #bar\n :b c", :style => :compact))
837
+ assert_equal("@a {\n #foo,\n #bar {\n b: c;\n }\n}\n",
838
+ render("@a\n #foo, \n #bar\n :b c", :style => :expanded))
839
+ assert_equal("@a{#foo,#bar{b:c}}\n",
840
+ render("@a\n #foo, \n #bar\n :b c", :style => :compressed))
841
+
842
+ to_render = <<END
843
+ @a
844
+ :b c
845
+ #d
846
+ :e f
847
+ :g h
848
+ END
849
+ rendered = <<END
850
+ @a { b: c;
851
+ #d { e: f; }
852
+ g: h; }
853
+ END
854
+ assert_equal(rendered, render(to_render, :style => :compact))
855
+
856
+ assert_equal("@a{b:c;#d{e:f}g:h}\n", render(to_render, :style => :compressed))
857
+ end
858
+
859
+ def test_property_hacks
860
+ assert_equal(<<CSS, render(<<SASS))
861
+ foo {
862
+ _name: val;
863
+ *name: val;
864
+ #name: val;
865
+ .name: val;
866
+ name/**/: val;
867
+ name/*\\**/: val;
868
+ name: val; }
869
+ CSS
870
+ foo
871
+ _name: val
872
+ *name: val
873
+ #name: val
874
+ .name: val
875
+ name/**/: val
876
+ name/*\\**/: val
877
+ name: val
878
+ SASS
879
+ end
880
+
881
+ def test_properties_with_space_after_colon
882
+ assert_equal <<CSS, render(<<SASS)
883
+ foo {
884
+ bar: baz;
885
+ bizz: bap; }
886
+ CSS
887
+ foo
888
+ bar : baz
889
+ bizz : bap
890
+ SASS
891
+ end
892
+
893
+ def test_line_annotations
894
+ assert_equal(<<CSS, render(<<SASS, :line_comments => true, :style => :compact))
895
+ /* line 2, test_line_annotations_inline.sass */
896
+ foo bar { foo: bar; }
897
+ /* line 5, test_line_annotations_inline.sass */
898
+ foo baz { blip: blop; }
899
+
900
+ /* line 9, test_line_annotations_inline.sass */
901
+ floodle { flop: blop; }
902
+
903
+ /* line 18, test_line_annotations_inline.sass */
904
+ bup { mix: on; }
905
+ /* line 15, test_line_annotations_inline.sass */
906
+ bup mixin { moop: mup; }
907
+
908
+ /* line 22, test_line_annotations_inline.sass */
909
+ bip hop, skip hop { a: b; }
910
+ CSS
911
+ foo
912
+ bar
913
+ foo: bar
914
+
915
+ baz
916
+ blip: blop
917
+
918
+
919
+ floodle
920
+
921
+ flop: blop
922
+
923
+ =mxn
924
+ mix: on
925
+ mixin
926
+ moop: mup
927
+
928
+ bup
929
+ +mxn
930
+
931
+ bip, skip
932
+ hop
933
+ a: b
934
+ SASS
935
+ end
936
+
937
+ def test_line_annotations_with_filename
938
+ renders_correctly "line_numbers", :line_comments => true, :load_paths => [File.dirname(__FILE__) + "/templates"]
939
+ end
940
+
941
+ def test_debug_info
942
+ esc_file_name = Sass::SCSS::RX.escape_ident(Sass::Util.scope("test_debug_info_inline.sass"))
943
+
944
+ assert_equal(<<CSS, render(<<SASS, :debug_info => true, :style => :compact))
945
+ @media -sass-debug-info{filename{font-family:file\\:\\/\\/#{esc_file_name}}line{font-family:\\000032}}
946
+ foo bar { foo: bar; }
947
+ @media -sass-debug-info{filename{font-family:file\\:\\/\\/#{esc_file_name}}line{font-family:\\000035}}
948
+ foo baz { blip: blop; }
949
+
950
+ @media -sass-debug-info{filename{font-family:file\\:\\/\\/#{esc_file_name}}line{font-family:\\000039}}
951
+ floodle { flop: blop; }
952
+
953
+ @media -sass-debug-info{filename{font-family:file\\:\\/\\/#{esc_file_name}}line{font-family:\\0000318}}
954
+ bup { mix: on; }
955
+ @media -sass-debug-info{filename{font-family:file\\:\\/\\/#{esc_file_name}}line{font-family:\\0000315}}
956
+ bup mixin { moop: mup; }
957
+
958
+ @media -sass-debug-info{filename{font-family:file\\:\\/\\/#{esc_file_name}}line{font-family:\\0000322}}
959
+ bip hop, skip hop { a: b; }
960
+ CSS
961
+ foo
962
+ bar
963
+ foo: bar
964
+
965
+ baz
966
+ blip: blop
967
+
968
+
969
+ floodle
970
+
971
+ flop: blop
972
+
973
+ =mxn
974
+ mix: on
975
+ mixin
976
+ moop: mup
977
+
978
+ bup
979
+ +mxn
980
+
981
+ bip, skip
982
+ hop
983
+ a: b
984
+ SASS
985
+ end
986
+
987
+ def test_debug_info_without_filename
988
+ assert_equal(<<CSS, Sass::Engine.new(<<SASS, :debug_info => true).render)
989
+ @media -sass-debug-info{filename{font-family:}line{font-family:\\000031}}
990
+ foo {
991
+ a: b; }
992
+ CSS
993
+ foo
994
+ a: b
995
+ SASS
996
+ end
997
+
998
+ def test_debug_info_with_compressed
999
+ assert_equal(<<CSS, render(<<SASS, :debug_info => true, :style => :compressed))
1000
+ foo{a:b}
1001
+ CSS
1002
+ foo
1003
+ a: b
1004
+ SASS
1005
+ end
1006
+
1007
+ def test_debug_info_with_line_annotations
1008
+ esc_file_name = Sass::SCSS::RX.escape_ident(Sass::Util.scope("test_debug_info_with_line_annotations_inline.sass"))
1009
+
1010
+ assert_equal(<<CSS, render(<<SASS, :debug_info => true, :line_comments => true))
1011
+ @media -sass-debug-info{filename{font-family:file\\:\\/\\/#{esc_file_name}}line{font-family:\\000031}}
1012
+ foo {
1013
+ a: b; }
1014
+ CSS
1015
+ foo
1016
+ a: b
1017
+ SASS
1018
+ end
1019
+
1020
+ def test_debug_info_in_keyframes
1021
+ assert_equal(<<CSS, render(<<SASS, :debug_info => true))
1022
+ @-webkit-keyframes warm {
1023
+ from {
1024
+ color: black; }
1025
+
1026
+ to {
1027
+ color: red; } }
1028
+ CSS
1029
+ @-webkit-keyframes warm
1030
+ from
1031
+ color: black
1032
+ to
1033
+ color: red
1034
+ SASS
1035
+ end
1036
+
1037
+ def test_empty_first_line
1038
+ assert_equal("#a {\n b: c; }\n", render("#a\n\n b: c"))
1039
+ end
1040
+
1041
+ def test_escaped_rule
1042
+ assert_equal(":focus {\n a: b; }\n", render("\\:focus\n a: b"))
1043
+ assert_equal("a {\n b: c; }\n a :focus {\n d: e; }\n", render("\\a\n b: c\n \\:focus\n d: e"))
1044
+ end
1045
+
1046
+ def test_cr_newline
1047
+ assert_equal("foo {\n a: b;\n c: d;\n e: f; }\n", render("foo\r a: b\r\n c: d\n\r e: f"))
1048
+ end
1049
+
1050
+ def test_property_with_content_and_nested_props
1051
+ assert_equal(<<CSS, render(<<SASS))
1052
+ foo {
1053
+ a: b;
1054
+ a-c: d;
1055
+ a-c-e: f; }
1056
+ CSS
1057
+ foo
1058
+ a: b
1059
+ c: d
1060
+ e: f
1061
+ SASS
1062
+
1063
+ assert_equal(<<CSS, render(<<SASS))
1064
+ foo {
1065
+ a: b;
1066
+ a-c-e: f; }
1067
+ CSS
1068
+ foo
1069
+ a: b
1070
+ c:
1071
+ e: f
1072
+ SASS
1073
+ end
1074
+
1075
+ def test_guarded_assign
1076
+ assert_equal("foo {\n a: b; }\n", render(%Q{$foo: b\n$foo: c !default\nfoo\n a: $foo}))
1077
+ assert_equal("foo {\n a: b; }\n", render(%Q{$foo: b !default\nfoo\n a: $foo}))
1078
+ end
1079
+
1080
+ def test_mixins
1081
+ renders_correctly "mixins", { :style => :expanded }
1082
+ end
1083
+
1084
+ def test_directive_style_mixins
1085
+ assert_equal <<CSS, render(<<SASS)
1086
+ bar {
1087
+ prop: baz; }
1088
+ CSS
1089
+ @mixin foo($arg)
1090
+ prop: $arg
1091
+
1092
+ bar
1093
+ @include foo(baz)
1094
+ SASS
1095
+ end
1096
+
1097
+ def test_mixins_dont_interfere_with_sibling_combinator
1098
+ assert_equal("foo + bar {\n a: b; }\nfoo + baz {\n c: d; }\n",
1099
+ render("foo\n +\n bar\n a: b\n baz\n c: d"))
1100
+ end
1101
+
1102
+ def test_mixin_args
1103
+ assert_equal("blat {\n baz: hi; }\n", render(<<SASS))
1104
+ =foo($bar)
1105
+ baz: $bar
1106
+ blat
1107
+ +foo(hi)
1108
+ SASS
1109
+ assert_equal("blat {\n baz: 3; }\n", render(<<SASS))
1110
+ =foo($a, $b)
1111
+ baz: $a + $b
1112
+ blat
1113
+ +foo(1, 2)
1114
+ SASS
1115
+ assert_equal("blat {\n baz: 4;\n baz: 3;\n baz: 5;\n bang: 3; }\n", render(<<SASS))
1116
+ =foo($c: (6 + 4) / 2)
1117
+ baz: $c
1118
+ $c: 3
1119
+ blat
1120
+ +foo($c + 1)
1121
+ +foo(($c + 3)/2)
1122
+ +foo
1123
+ bang: $c
1124
+ SASS
1125
+ end
1126
+
1127
+ def test_default_values_for_mixin_arguments
1128
+ assert_equal("white {\n color: white; }\n\nblack {\n color: black; }\n", render(<<SASS))
1129
+ =foo($a: #FFF)
1130
+ :color $a
1131
+ white
1132
+ +foo
1133
+ black
1134
+ +foo(#000)
1135
+ SASS
1136
+ assert_equal(<<CSS, render(<<SASS))
1137
+ one {
1138
+ color: white;
1139
+ padding: 1px;
1140
+ margin: 4px; }
1141
+
1142
+ two {
1143
+ color: white;
1144
+ padding: 2px;
1145
+ margin: 5px; }
1146
+
1147
+ three {
1148
+ color: white;
1149
+ padding: 2px;
1150
+ margin: 3px; }
1151
+ CSS
1152
+ $a: 5px
1153
+ =foo($a, $b: 1px, $c: 3px + $b)
1154
+ :color $a
1155
+ :padding $b
1156
+ :margin $c
1157
+ one
1158
+ +foo(#fff)
1159
+ two
1160
+ +foo(#fff, 2px)
1161
+ three
1162
+ +foo(#fff, 2px, 3px)
1163
+ SASS
1164
+ end
1165
+
1166
+ def test_hyphen_underscore_insensitive_mixins
1167
+ assert_equal(<<CSS, render(<<SASS))
1168
+ a {
1169
+ b: 12;
1170
+ c: foo; }
1171
+ CSS
1172
+ =mixin-hyphen
1173
+ b: 12
1174
+
1175
+ =mixin_under
1176
+ c: foo
1177
+
1178
+ a
1179
+ +mixin_hyphen
1180
+ +mixin-under
1181
+ SASS
1182
+ end
1183
+
1184
+ def test_css_identifier_mixin
1185
+ assert_equal(<<CSS, render(<<SASS))
1186
+ a {
1187
+ foo: 12; }
1188
+ CSS
1189
+ =\\{foo\\(12\\)($a)
1190
+ foo: $a
1191
+
1192
+ a
1193
+ +\\{foo\\(12\\)(12)
1194
+ SASS
1195
+ end
1196
+
1197
+ def test_basic_function
1198
+ assert_equal(<<CSS, render(<<SASS))
1199
+ bar {
1200
+ a: 3; }
1201
+ CSS
1202
+ @function foo()
1203
+ @return 1 + 2
1204
+
1205
+ bar
1206
+ a: foo()
1207
+ SASS
1208
+ end
1209
+
1210
+ def test_function_args
1211
+ assert_equal(<<CSS, render(<<SASS))
1212
+ bar {
1213
+ a: 3; }
1214
+ CSS
1215
+ @function plus($var1, $var2)
1216
+ @return $var1 + $var2
1217
+
1218
+ bar
1219
+ a: plus(1, 2)
1220
+ SASS
1221
+ end
1222
+
1223
+ def test_function_arg_default
1224
+ assert_equal(<<CSS, render(<<SASS))
1225
+ bar {
1226
+ a: 3; }
1227
+ CSS
1228
+ @function plus($var1, $var2: 2)
1229
+ @return $var1 + $var2
1230
+
1231
+ bar
1232
+ a: plus(1)
1233
+ SASS
1234
+ end
1235
+
1236
+ def test_function_arg_keyword
1237
+ assert_equal(<<CSS, render(<<SASS))
1238
+ bar {
1239
+ a: 1bar; }
1240
+ CSS
1241
+ @function plus($var1: 1, $var2: 2)
1242
+ @return $var1 + $var2
1243
+
1244
+ bar
1245
+ a: plus($var2: bar)
1246
+ SASS
1247
+ end
1248
+
1249
+ def test_function_with_if
1250
+ assert_equal(<<CSS, render(<<SASS))
1251
+ bar {
1252
+ a: foo;
1253
+ b: bar; }
1254
+ CSS
1255
+ @function my-if($cond, $val1, $val2)
1256
+ @if $cond
1257
+ @return $val1
1258
+ @else
1259
+ @return $val2
1260
+
1261
+ bar
1262
+ a: my-if(true, foo, bar)
1263
+ b: my-if(false, foo, bar)
1264
+ SASS
1265
+ end
1266
+
1267
+ def test_function_with_var
1268
+ assert_equal(<<CSS, render(<<SASS))
1269
+ bar {
1270
+ a: 1; }
1271
+ CSS
1272
+ @function foo($val1, $val2)
1273
+ $intermediate: $val1 + $val2
1274
+ @return $intermediate/3
1275
+
1276
+ bar
1277
+ a: foo(1, 2)
1278
+ SASS
1279
+ end
1280
+
1281
+ def test_control_directive_in_nested_property
1282
+ assert_equal(<<CSS, render(<<SASS))
1283
+ foo {
1284
+ a-b: c; }
1285
+ CSS
1286
+ foo
1287
+ a:
1288
+ @if true
1289
+ b: c
1290
+ SASS
1291
+ end
1292
+
1293
+ def test_interpolation
1294
+ assert_equal("a-1 {\n b-2-3: c-3; }\n", render(<<SASS))
1295
+ $a: 1
1296
+ $b: 2
1297
+ $c: 3
1298
+ a-\#{$a}
1299
+ b-\#{$b}-\#{$c}: c-\#{$a + $b}
1300
+ SASS
1301
+ end
1302
+
1303
+ def test_complex_property_interpolation
1304
+ assert_equal(<<CSS, render(<<SASS))
1305
+ a-1 {
1306
+ b-2 3-fizzap18: c-3; }
1307
+ CSS
1308
+ $a: 1
1309
+ $b: 2
1310
+ $c: 3
1311
+ a-\#{$a}
1312
+ b-\#{$b $c}-\#{fizzap + ($c + 15)}: c-\#{$a + $b}
1313
+ SASS
1314
+ end
1315
+
1316
+ def test_if_directive
1317
+ assert_equal("a {\n b: 1; }\n", render(<<SASS))
1318
+ $var: true
1319
+ a
1320
+ @if $var
1321
+ b: 1
1322
+ @if not $var
1323
+ b: 2
1324
+ SASS
1325
+ end
1326
+
1327
+ def test_for
1328
+ assert_equal(<<CSS, render(<<SASS))
1329
+ a-0 {
1330
+ two-i: 0; }
1331
+
1332
+ a-1 {
1333
+ two-i: 2; }
1334
+
1335
+ a-2 {
1336
+ two-i: 4; }
1337
+
1338
+ a-3 {
1339
+ two-i: 6; }
1340
+
1341
+ b-1 {
1342
+ j-1: 0; }
1343
+
1344
+ b-2 {
1345
+ j-1: 1; }
1346
+
1347
+ b-3 {
1348
+ j-1: 2; }
1349
+
1350
+ b-4 {
1351
+ j-1: 3; }
1352
+ CSS
1353
+ $a: 3
1354
+ @for $i from 0 to $a + 1
1355
+ a-\#{$i}
1356
+ two-i: 2 * $i
1357
+
1358
+ @for $j from 1 through 4
1359
+ b-\#{$j}
1360
+ j-1: $j - 1
1361
+ SASS
1362
+ end
1363
+
1364
+ def test_while
1365
+ assert_equal(<<CSS, render(<<SASS))
1366
+ a-5 {
1367
+ blooble: gloop; }
1368
+
1369
+ a-4 {
1370
+ blooble: gloop; }
1371
+
1372
+ a-3 {
1373
+ blooble: gloop; }
1374
+
1375
+ a-2 {
1376
+ blooble: gloop; }
1377
+
1378
+ a-1 {
1379
+ blooble: gloop; }
1380
+ CSS
1381
+ $a: 5
1382
+ @while $a != 0
1383
+ a-\#{$a}
1384
+ blooble: gloop
1385
+ $a: $a - 1
1386
+ SASS
1387
+ end
1388
+
1389
+ def test_else
1390
+ assert_equal(<<CSS, render(<<SASS))
1391
+ a {
1392
+ t1: t;
1393
+ t2: t;
1394
+ t3: t;
1395
+ t4: t; }
1396
+ CSS
1397
+ a
1398
+ @if true
1399
+ t1: t
1400
+ @else
1401
+ f1: f
1402
+
1403
+ @if false
1404
+ f2: f
1405
+ @else
1406
+ t2: t
1407
+
1408
+ @if false
1409
+ f3: f1
1410
+ @else if 1 + 1 == 3
1411
+ f3: f2
1412
+ @else
1413
+ t3: t
1414
+
1415
+ @if false
1416
+ f4: f1
1417
+ @else if 1 + 1 == 2
1418
+ t4: t
1419
+ @else
1420
+ f4: f2
1421
+
1422
+ @if false
1423
+ f5: f1
1424
+ @else if false
1425
+ f5: f2
1426
+ SASS
1427
+ end
1428
+
1429
+ def test_each
1430
+ assert_equal(<<CSS, render(<<SASS))
1431
+ a {
1432
+ b: 1px;
1433
+ b: 2px;
1434
+ b: 3px;
1435
+ b: 4px;
1436
+ c: foo;
1437
+ c: bar;
1438
+ c: baz;
1439
+ c: bang;
1440
+ d: blue; }
1441
+ CSS
1442
+ a
1443
+ @each $number in 1px 2px 3px 4px
1444
+ b: $number
1445
+ @each $str in foo, bar, baz, bang
1446
+ c: $str
1447
+ @each $single in blue
1448
+ d: $single
1449
+ SASS
1450
+ end
1451
+
1452
+ def test_variable_reassignment
1453
+ assert_equal(<<CSS, render(<<SASS))
1454
+ a {
1455
+ b: 1;
1456
+ c: 2; }
1457
+ CSS
1458
+ $a: 1
1459
+ a
1460
+ b: $a
1461
+ $a: 2
1462
+ c: $a
1463
+ SASS
1464
+ end
1465
+
1466
+ def test_variable_scope
1467
+ assert_equal(<<CSS, render(<<SASS))
1468
+ a {
1469
+ b-1: c;
1470
+ b-2: c;
1471
+ d: 12; }
1472
+
1473
+ b {
1474
+ d: 17; }
1475
+ CSS
1476
+ $i: 12
1477
+ a
1478
+ @for $i from 1 through 2
1479
+ b-\#{$i}: c
1480
+ d: $i
1481
+
1482
+ =foo
1483
+ $i: 17
1484
+
1485
+ b
1486
+ +foo
1487
+ d: $i
1488
+ SASS
1489
+ end
1490
+
1491
+ def test_hyphen_underscore_insensitive_variables
1492
+ assert_equal(<<CSS, render(<<SASS))
1493
+ a {
1494
+ b: c; }
1495
+
1496
+ d {
1497
+ e: 13;
1498
+ f: foobar; }
1499
+ CSS
1500
+ $var-hyphen: 12
1501
+ $var_under: foo
1502
+
1503
+ a
1504
+ $var_hyphen: 1 + $var_hyphen
1505
+ $var-under: $var-under + bar
1506
+ b: c
1507
+
1508
+ d
1509
+ e: $var-hyphen
1510
+ f: $var_under
1511
+ SASS
1512
+ end
1513
+
1514
+ def test_css_identifier_variable
1515
+ assert_equal(<<CSS, render(<<SASS))
1516
+ a {
1517
+ b: 12; }
1518
+ CSS
1519
+ $\\{foo\\(12\\): 12
1520
+
1521
+ a
1522
+ b: $\\{foo\\(12\\)
1523
+ SASS
1524
+ end
1525
+
1526
+ def test_important
1527
+ assert_equal(<<CSS, render(<<SASS))
1528
+ a {
1529
+ b: 12px !important; }
1530
+ CSS
1531
+ $foo: 12px
1532
+ a
1533
+ b: $foo !important
1534
+ SASS
1535
+ end
1536
+
1537
+ def test_argument_error
1538
+ assert_raise(Sass::SyntaxError) { render("a\n b: hsl(1)") }
1539
+ end
1540
+
1541
+ def test_comments_at_the_top_of_a_document
1542
+ render(<<SASS)
1543
+ //
1544
+ This is a comment that
1545
+ continues to the second line.
1546
+ foo
1547
+ bar: baz
1548
+ SASS
1549
+ end
1550
+
1551
+ def test_loud_comments_containing_a_comment_close
1552
+ actual_css = render(<<SASS)
1553
+ /*
1554
+ This is a comment that
1555
+ continues to the second line. */
1556
+ foo
1557
+ bar: baz
1558
+ SASS
1559
+ assert_equal(<<CSS, actual_css)
1560
+ /* This is a comment that
1561
+ * continues to the second line. */
1562
+ foo {
1563
+ bar: baz; }
1564
+ CSS
1565
+ end
1566
+
1567
+ def test_loud_comments_with_starred_lines
1568
+ assert_equal(<<CSS, render(<<SASS))
1569
+ /* This is a comment that
1570
+ * continues to the second line.
1571
+ * And even to the third! */
1572
+ CSS
1573
+ /* This is a comment that
1574
+ * continues to the second line.
1575
+ * And even to the third!
1576
+ SASS
1577
+ end
1578
+
1579
+ def test_loud_comments_with_no_space_after_starred_lines
1580
+ assert_equal(<<CSS, render(<<SASS))
1581
+ /*bip bop
1582
+ *beep boop
1583
+ *bap blimp */
1584
+ CSS
1585
+ /*bip bop
1586
+ *beep boop
1587
+ *bap blimp
1588
+ SASS
1589
+ end
1590
+
1591
+ def test_comment_indentation_at_beginning_of_doc
1592
+ assert_equal <<CSS, render(<<SASS)
1593
+ /* foo
1594
+ * bar
1595
+ * baz */
1596
+ foo {
1597
+ a: b; }
1598
+ CSS
1599
+ /* foo
1600
+ bar
1601
+ baz
1602
+ foo
1603
+ a: b
1604
+ SASS
1605
+ end
1606
+
1607
+ def test_unusual_comment_indentation
1608
+ assert_equal <<CSS, render(<<SASS)
1609
+ foo {
1610
+ /* foo
1611
+ * bar
1612
+ * baz */ }
1613
+ CSS
1614
+ foo
1615
+ /* foo
1616
+ bar
1617
+ baz
1618
+ SASS
1619
+ end
1620
+
1621
+ def test_loud_comment_with_close
1622
+ assert_equal <<CSS, render(<<SASS)
1623
+ foo {
1624
+ /* foo
1625
+ * bar */ }
1626
+ CSS
1627
+ foo
1628
+ /* foo
1629
+ bar */
1630
+ SASS
1631
+ end
1632
+
1633
+ def test_loud_comment_with_separate_line_close
1634
+ assert_equal <<CSS, render(<<SASS)
1635
+ foo {
1636
+ /* foo
1637
+ * bar
1638
+ */ }
1639
+ CSS
1640
+ foo
1641
+ /* foo
1642
+ * bar
1643
+ */
1644
+ SASS
1645
+ end
1646
+
1647
+ def test_loud_comment_in_compressed_mode
1648
+ assert_equal <<CSS, render(<<SASS, :style => :compressed)
1649
+ foo{color:blue;/* foo
1650
+ * bar
1651
+ */}
1652
+ CSS
1653
+ foo
1654
+ color: blue
1655
+ /*! foo
1656
+ * bar
1657
+ */
1658
+ SASS
1659
+ end
1660
+
1661
+ def test_loud_comment_in_silent_comment
1662
+ silence_warnings {assert_equal <<CSS, render(<<SASS, :style => :compressed)}
1663
+ foo{color:blue;/* foo */
1664
+ /* bar */
1665
+ /* bip */
1666
+ /* baz */}
1667
+ CSS
1668
+ foo
1669
+ color: blue
1670
+ //! foo
1671
+ //! bar
1672
+ //!
1673
+ bip
1674
+ baz
1675
+ SASS
1676
+ end
1677
+
1678
+ def test_loud_comment_is_evaluated
1679
+ assert_equal <<CSS, render(<<SASS)
1680
+ /* Hue: 327.216deg */
1681
+ CSS
1682
+ /*!
1683
+ Hue: \#{hue(#f836a0)}
1684
+ SASS
1685
+ end
1686
+
1687
+ def test_attribute_selector_with_spaces
1688
+ assert_equal(<<CSS, render(<<SASS))
1689
+ a b[foo=bar] {
1690
+ c: d; }
1691
+ CSS
1692
+ a
1693
+ b[foo = bar]
1694
+ c: d
1695
+ SASS
1696
+ end
1697
+
1698
+ def test_quoted_colon
1699
+ assert_equal(<<CSS, render(<<SASS))
1700
+ a b[foo="bar: baz"] {
1701
+ c: d; }
1702
+ CSS
1703
+ a
1704
+ b[foo="bar: baz"]
1705
+ c: d
1706
+ SASS
1707
+ end
1708
+
1709
+ def test_quoted_comma
1710
+ assert_equal(<<CSS, render(<<SASS))
1711
+ a b[foo="bar, baz"] {
1712
+ c: d; }
1713
+ CSS
1714
+ a
1715
+ b[foo="bar, baz"]
1716
+ c: d
1717
+ SASS
1718
+ end
1719
+
1720
+ def test_quoted_ampersand
1721
+ assert_equal(<<CSS, render(<<SASS))
1722
+ a b[foo="bar & baz"] {
1723
+ c: d; }
1724
+ CSS
1725
+ a
1726
+ b[foo="bar & baz"]
1727
+ c: d
1728
+ SASS
1729
+ end
1730
+
1731
+ def test_empty_selector_warning
1732
+ assert_warning(<<END) {render("foo bar")}
1733
+ WARNING on line 1 of test_empty_selector_warning_inline.sass:
1734
+ This selector doesn't have any properties and will not be rendered.
1735
+ END
1736
+ end
1737
+
1738
+ def test_root_level_pseudo_class_with_new_properties
1739
+ assert_equal(<<CSS, render(<<SASS, :property_syntax => :new))
1740
+ :focus {
1741
+ outline: 0; }
1742
+ CSS
1743
+ :focus
1744
+ outline: 0
1745
+ SASS
1746
+ end
1747
+
1748
+ def test_pseudo_class_with_new_properties
1749
+ assert_equal(<<CSS, render(<<SASS, :property_syntax => :new))
1750
+ p :focus {
1751
+ outline: 0; }
1752
+ CSS
1753
+ p
1754
+ :focus
1755
+ outline: 0
1756
+ SASS
1757
+ end
1758
+
1759
+ def test_nil_option
1760
+ assert_equal(<<CSS, render(<<SASS, :format => nil))
1761
+ foo {
1762
+ a: b; }
1763
+ CSS
1764
+ foo
1765
+ a: b
1766
+ SASS
1767
+ end
1768
+
1769
+ def test_interpolation_in_raw_functions
1770
+ assert_equal(<<CSS, render(<<SASS))
1771
+ foo {
1772
+ filter: progid:Microsoft.foo.bar.Baz(flip=foobar, bang=#00ff00cc); }
1773
+ CSS
1774
+ foo
1775
+ filter: progid:Microsoft.foo.bar.Baz(flip=\#{foo + bar}, bang=#00ff00cc)
1776
+ SASS
1777
+ end
1778
+
1779
+ # SassScript string behavior
1780
+
1781
+ def test_plus_preserves_quotedness
1782
+ assert_equal(<<CSS, render(<<SASS))
1783
+ foo {
1784
+ a: "foo1";
1785
+ b: "1foo";
1786
+ c: foo1;
1787
+ d: 1foo;
1788
+ e: "foobar";
1789
+ f: foobar; }
1790
+ CSS
1791
+ foo
1792
+ a: "foo" + 1
1793
+ b: 1 + "foo"
1794
+ c: foo + 1
1795
+ d: 1 + foo
1796
+ e: "foo" + bar
1797
+ f: foo + "bar"
1798
+ SASS
1799
+ end
1800
+
1801
+ def test_colon_properties_preserve_quotedness
1802
+ assert_equal(<<CSS, render(<<SASS))
1803
+ foo {
1804
+ a: "foo";
1805
+ b: bar;
1806
+ c: "foo" bar;
1807
+ d: foo, "bar"; }
1808
+ CSS
1809
+ foo
1810
+ a: "foo"
1811
+ b: bar
1812
+ c: "foo" bar
1813
+ d: foo, "bar"
1814
+ SASS
1815
+ end
1816
+
1817
+ def test_colon_variables_preserve_quotedness
1818
+ assert_equal(<<CSS, render(<<SASS))
1819
+ foo {
1820
+ a: "foo";
1821
+ b: bar; }
1822
+ CSS
1823
+ $a: "foo"
1824
+ $b: bar
1825
+
1826
+ foo
1827
+ a: $a
1828
+ b: $b
1829
+ SASS
1830
+ end
1831
+
1832
+ def test_colon_args_preserve_quotedness
1833
+ assert_equal(<<CSS, render(<<SASS))
1834
+ foo {
1835
+ a: "foo";
1836
+ b: bar;
1837
+ c: "foo" bar;
1838
+ d: foo, "bar"; }
1839
+ CSS
1840
+ =foo($a: "foo", $b: bar, $c: "foo" bar, $d: (foo, "bar"))
1841
+ foo
1842
+ a: $a
1843
+ b: $b
1844
+ c: $c
1845
+ d: $d
1846
+
1847
+ +foo
1848
+ SASS
1849
+ end
1850
+
1851
+ def test_interpolation_unquotes_strings
1852
+ assert_equal(<<CSS, render(<<SASS))
1853
+ .foo-bar {
1854
+ a: b; }
1855
+ CSS
1856
+ .foo-\#{"bar"}
1857
+ a: b
1858
+ SASS
1859
+
1860
+ assert_equal(<<CSS, render(<<SASS))
1861
+ .foo {
1862
+ a: b c; }
1863
+ CSS
1864
+ .foo
1865
+ a: b \#{"c"}
1866
+ SASS
1867
+ end
1868
+
1869
+ def test_interpolation_unquotes_strings_in_vars
1870
+ assert_equal(<<CSS, render(<<SASS))
1871
+ .foo-bar {
1872
+ a: b; }
1873
+ CSS
1874
+ $var: "bar"
1875
+
1876
+ .foo-\#{$var}
1877
+ a: b
1878
+ SASS
1879
+ end
1880
+
1881
+ def test_interpolation_doesnt_deep_unquote_strings
1882
+ assert_equal(<<CSS, render(<<SASS))
1883
+ .foo {
1884
+ a: "bar" "baz"; }
1885
+ CSS
1886
+ .foo
1887
+ a: \#{"bar" "baz"}
1888
+ SASS
1889
+ end
1890
+
1891
+ def test_warn_directive
1892
+ expected_warning = <<EXPECTATION
1893
+ WARNING: this is a warning
1894
+ on line 4 of test_warn_directive_inline.sass
1895
+
1896
+ WARNING: this is a mixin warning
1897
+ on line 2 of test_warn_directive_inline.sass, in `foo'
1898
+ from line 7 of test_warn_directive_inline.sass
1899
+ EXPECTATION
1900
+ assert_warning expected_warning do
1901
+ assert_equal <<CSS, render(<<SASS)
1902
+ bar {
1903
+ c: d; }
1904
+ CSS
1905
+ =foo
1906
+ @warn "this is a mixin warning"
1907
+
1908
+ @warn "this is a warning"
1909
+ bar
1910
+ c: d
1911
+ +foo
1912
+ SASS
1913
+ end
1914
+ end
1915
+
1916
+ def test_warn_directive_when_quiet
1917
+ assert_warning "" do
1918
+ assert_equal <<CSS, render(<<SASS, :quiet => true)
1919
+ CSS
1920
+ @warn "this is a warning"
1921
+ SASS
1922
+ end
1923
+ end
1924
+
1925
+ def test_warn_with_imports
1926
+ expected_warning = <<WARN
1927
+ WARNING: In the main file
1928
+ on line 1 of #{File.dirname(__FILE__)}/templates/warn.sass
1929
+
1930
+ WARNING: Imported
1931
+ on line 1 of #{File.dirname(__FILE__)}/templates/warn_imported.sass
1932
+ from line 2 of #{File.dirname(__FILE__)}/templates/warn.sass
1933
+
1934
+ WARNING: In an imported mixin
1935
+ on line 4 of #{File.dirname(__FILE__)}/templates/warn_imported.sass, in `emits-a-warning'
1936
+ from line 3 of #{File.dirname(__FILE__)}/templates/warn.sass
1937
+ WARN
1938
+ assert_warning expected_warning do
1939
+ renders_correctly "warn", :style => :compact, :load_paths => [File.dirname(__FILE__) + "/templates"]
1940
+ end
1941
+ end
1942
+
1943
+ def test_media_bubbling
1944
+ assert_equal <<CSS, render(<<SASS)
1945
+ .foo {
1946
+ a: b; }
1947
+ @media bar {
1948
+ .foo {
1949
+ c: d; } }
1950
+ .foo .baz {
1951
+ e: f; }
1952
+ @media bip {
1953
+ .foo .baz {
1954
+ g: h; } }
1955
+
1956
+ .other {
1957
+ i: j; }
1958
+ CSS
1959
+ .foo
1960
+ a: b
1961
+ @media bar
1962
+ c: d
1963
+ .baz
1964
+ e: f
1965
+ @media bip
1966
+ g: h
1967
+
1968
+ .other
1969
+ i: j
1970
+ SASS
1971
+
1972
+ assert_equal <<CSS, render(<<SASS, :style => :compact)
1973
+ .foo { a: b; }
1974
+ @media bar { .foo { c: d; } }
1975
+ .foo .baz { e: f; }
1976
+ @media bip { .foo .baz { g: h; } }
1977
+
1978
+ .other { i: j; }
1979
+ CSS
1980
+ .foo
1981
+ a: b
1982
+ @media bar
1983
+ c: d
1984
+ .baz
1985
+ e: f
1986
+ @media bip
1987
+ g: h
1988
+
1989
+ .other
1990
+ i: j
1991
+ SASS
1992
+
1993
+ assert_equal <<CSS, render(<<SASS, :style => :expanded)
1994
+ .foo {
1995
+ a: b;
1996
+ }
1997
+ @media bar {
1998
+ .foo {
1999
+ c: d;
2000
+ }
2001
+ }
2002
+ .foo .baz {
2003
+ e: f;
2004
+ }
2005
+ @media bip {
2006
+ .foo .baz {
2007
+ g: h;
2008
+ }
2009
+ }
2010
+
2011
+ .other {
2012
+ i: j;
2013
+ }
2014
+ CSS
2015
+ .foo
2016
+ a: b
2017
+ @media bar
2018
+ c: d
2019
+ .baz
2020
+ e: f
2021
+ @media bip
2022
+ g: h
2023
+
2024
+ .other
2025
+ i: j
2026
+ SASS
2027
+ end
2028
+
2029
+ def test_double_media_bubbling
2030
+ assert_equal <<CSS, render(<<SASS)
2031
+ @media bar and baz {
2032
+ .foo {
2033
+ c: d; } }
2034
+ CSS
2035
+ @media bar
2036
+ @media baz
2037
+ .foo
2038
+ c: d
2039
+ SASS
2040
+
2041
+ assert_equal <<CSS, render(<<SASS)
2042
+ @media bar {
2043
+ .foo {
2044
+ a: b; } }
2045
+ @media bar and baz {
2046
+ .foo {
2047
+ c: d; } }
2048
+ CSS
2049
+ .foo
2050
+ @media bar
2051
+ a: b
2052
+ @media baz
2053
+ c: d
2054
+ SASS
2055
+ end
2056
+
2057
+ def test_double_media_bubbling_with_commas
2058
+ assert_equal <<CSS, render(<<SASS)
2059
+ @media foo and baz, foo and bang, bar and baz, bar and bang {
2060
+ .foo {
2061
+ c: d; } }
2062
+ CSS
2063
+ @media foo, bar
2064
+ @media baz, bang
2065
+ .foo
2066
+ c: d
2067
+ SASS
2068
+ end
2069
+
2070
+ def test_rule_media_rule_bubbling
2071
+ assert_equal <<CSS, render(<<SASS)
2072
+ @media bar {
2073
+ .foo {
2074
+ a: b;
2075
+ e: f; }
2076
+ .foo .baz {
2077
+ c: d; } }
2078
+ CSS
2079
+ .foo
2080
+ @media bar
2081
+ a: b
2082
+ .baz
2083
+ c: d
2084
+ e: f
2085
+ SASS
2086
+ end
2087
+
2088
+ def test_nested_media_around_properties
2089
+ assert_equal <<CSS, render(<<SASS)
2090
+ .outside {
2091
+ color: red;
2092
+ background: blue; }
2093
+ @media print {
2094
+ .outside {
2095
+ color: black; } }
2096
+ @media print and nested {
2097
+ .outside .inside {
2098
+ border: 1px solid black; } }
2099
+ .outside .middle {
2100
+ display: block; }
2101
+ CSS
2102
+ .outside
2103
+ color: red
2104
+ @media print
2105
+ color: black
2106
+ .inside
2107
+ @media nested
2108
+ border: 1px solid black
2109
+ background: blue
2110
+ .middle
2111
+ display: block
2112
+ SASS
2113
+ end
2114
+
2115
+ def test_media_with_parent_references
2116
+ sass_str = <<SASS
2117
+ .outside
2118
+ @media print
2119
+ &.inside
2120
+ border: 1px solid black
2121
+ SASS
2122
+ css_str = <<CSS
2123
+ @media print {
2124
+ .outside.inside {
2125
+ border: 1px solid black; } }
2126
+ CSS
2127
+ assert_equal css_str, render(sass_str)
2128
+ end
2129
+
2130
+ # Regression tests
2131
+
2132
+ def test_tricky_mixin_loop_exception
2133
+ render <<SASS
2134
+ @mixin foo($a)
2135
+ @if $a
2136
+ @include foo(false)
2137
+ @include foo(true)
2138
+ @else
2139
+ a: b
2140
+
2141
+ a
2142
+ @include foo(true)
2143
+ SASS
2144
+ assert(false, "Exception not raised")
2145
+ rescue Sass::SyntaxError => err
2146
+ assert_equal("An @include loop has been found: foo includes itself", err.message)
2147
+ assert_hash_has(err.sass_backtrace[0], :mixin => "foo", :line => 3)
2148
+ end
2149
+
2150
+ def test_interpolated_comment_in_mixin
2151
+ assert_equal <<CSS, render(<<SASS)
2152
+ /* color: red */
2153
+ .foo {
2154
+ color: red; }
2155
+
2156
+ /* color: blue */
2157
+ .foo {
2158
+ color: blue; }
2159
+
2160
+ /* color: green */
2161
+ .foo {
2162
+ color: green; }
2163
+ CSS
2164
+ =foo($var)
2165
+ /*! color: \#{$var}
2166
+ .foo
2167
+ color: $var
2168
+
2169
+ +foo(red)
2170
+ +foo(blue)
2171
+ +foo(green)
2172
+ SASS
2173
+ end
2174
+
2175
+ def test_parens_in_mixins
2176
+ assert_equal(<<CSS, render(<<SASS))
2177
+ .foo {
2178
+ color: #01ff7f;
2179
+ background-color: #000102; }
2180
+ CSS
2181
+ =foo($c1, $c2: rgb(0, 1, 2))
2182
+ color: $c1
2183
+ background-color: $c2
2184
+
2185
+ .foo
2186
+ +foo(rgb(1,255,127))
2187
+ SASS
2188
+ end
2189
+
2190
+ def test_comment_beneath_prop
2191
+ assert_equal(<<RESULT, render(<<SOURCE))
2192
+ .box {
2193
+ border-style: solid; }
2194
+ RESULT
2195
+ .box
2196
+ :border
2197
+ //:color black
2198
+ :style solid
2199
+ SOURCE
2200
+
2201
+ assert_equal(<<RESULT, render(<<SOURCE))
2202
+ .box {
2203
+ /* :color black */
2204
+ border-style: solid; }
2205
+ RESULT
2206
+ .box
2207
+ :border
2208
+ /* :color black
2209
+ :style solid
2210
+ SOURCE
2211
+
2212
+ assert_equal(<<RESULT, render(<<SOURCE, :style => :compressed))
2213
+ .box{border-style:solid}
2214
+ RESULT
2215
+ .box
2216
+ :border
2217
+ /*:color black
2218
+ :style solid
2219
+ SOURCE
2220
+ end
2221
+
2222
+ def test_compressed_comment_beneath_directive
2223
+ assert_equal(<<RESULT, render(<<SOURCE, :style => :compressed))
2224
+ @foo{a:b}
2225
+ RESULT
2226
+ @foo
2227
+ a: b
2228
+ /*b: c
2229
+ SOURCE
2230
+ end
2231
+
2232
+ def test_comment_with_crazy_indentation
2233
+ assert_equal(<<CSS, render(<<SASS))
2234
+ /* This is a loud comment:
2235
+ * Where the indentation is wonky. */
2236
+ .comment {
2237
+ width: 1px; }
2238
+ CSS
2239
+ /*
2240
+ This is a loud comment:
2241
+ Where the indentation is wonky.
2242
+ //
2243
+ This is a silent comment:
2244
+ Where the indentation is wonky.
2245
+ .comment
2246
+ width: 1px
2247
+ SASS
2248
+ end
2249
+
2250
+ def test_plus_with_space
2251
+ assert_equal(<<CSS, render(<<SASS))
2252
+ a + b {
2253
+ color: green; }
2254
+ CSS
2255
+ a
2256
+ + b
2257
+ color: green
2258
+ SASS
2259
+ end
2260
+
2261
+ def test_empty_line_comment
2262
+ assert_equal(<<CSS, render(<<SASS))
2263
+ /* Foo
2264
+ *
2265
+ * Bar */
2266
+ CSS
2267
+ /*
2268
+ Foo
2269
+
2270
+ Bar
2271
+ SASS
2272
+ end
2273
+
2274
+ def test_empty_comment
2275
+ assert_equal(<<CSS, render(<<SASS))
2276
+ /* */
2277
+ a {
2278
+ /* */
2279
+ b: c; }
2280
+ CSS
2281
+ /*
2282
+ a
2283
+ /*
2284
+ b: c
2285
+ SASS
2286
+ end
2287
+
2288
+ def test_options_available_in_environment
2289
+ assert_equal(<<CSS, render(<<SASS))
2290
+ a {
2291
+ b: nested; }
2292
+ CSS
2293
+ a
2294
+ b: option("style")
2295
+ SASS
2296
+ end
2297
+
2298
+ def test_mixin_no_arg_error
2299
+ assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "($bar,": expected variable (e.g. $foo), was ")"') do
2300
+ render(<<SASS)
2301
+ =foo($bar,)
2302
+ bip: bap
2303
+ SASS
2304
+ end
2305
+ end
2306
+
2307
+ def test_import_with_commas_in_url
2308
+ assert_equal <<CSS, render(<<SASS)
2309
+ @import url(foo.css?bar,baz);
2310
+ CSS
2311
+ @import url(foo.css?bar,baz)
2312
+ SASS
2313
+ end
2314
+
2315
+ def test_silent_comment_in_prop_val_after_important
2316
+ assert_equal(<<CSS, render(<<SASS))
2317
+ .advanced {
2318
+ display: none !important; }
2319
+ CSS
2320
+ .advanced
2321
+ display: none !important // yeah, yeah. it's not really a style anyway.
2322
+ SASS
2323
+ end
2324
+
2325
+ def test_mixin_with_keyword_args
2326
+ assert_equal <<CSS, render(<<SASS)
2327
+ .mixed {
2328
+ required: foo;
2329
+ arg1: default-val1;
2330
+ arg2: non-default-val2; }
2331
+ CSS
2332
+ =a-mixin($required, $arg1: default-val1, $arg2: default-val2)
2333
+ required: $required
2334
+ arg1: $arg1
2335
+ arg2: $arg2
2336
+ .mixed
2337
+ +a-mixin(foo, $arg2: non-default-val2)
2338
+ SASS
2339
+ end
2340
+
2341
+ def test_mixin_with_keyword_arg_variable_value
2342
+ assert_equal <<CSS, render(<<SASS)
2343
+ .mixed {
2344
+ required: foo;
2345
+ arg1: default-val1;
2346
+ arg2: a-value; }
2347
+ CSS
2348
+ =a-mixin($required, $arg1: default-val1, $arg2: default-val2)
2349
+ required: $required
2350
+ arg1: $arg1
2351
+ arg2: $arg2
2352
+ .mixed
2353
+ $a-value: a-value
2354
+ +a-mixin(foo, $arg2: $a-value)
2355
+ SASS
2356
+ end
2357
+
2358
+ def test_mixin_keyword_args_handle_variable_underscore_dash_equivalence
2359
+ assert_equal <<CSS, render(<<SASS)
2360
+ .mixed {
2361
+ required: foo;
2362
+ arg1: non-default-val1;
2363
+ arg2: non-default-val2; }
2364
+ CSS
2365
+ =a-mixin($required, $arg-1: default-val1, $arg_2: default-val2)
2366
+ required: $required
2367
+ arg1: $arg_1
2368
+ arg2: $arg-2
2369
+ .mixed
2370
+ +a-mixin(foo, $arg-2: non-default-val2, $arg_1: non-default-val1)
2371
+ SASS
2372
+ end
2373
+
2374
+ def test_passing_required_args_as_a_keyword_arg
2375
+ assert_equal <<CSS, render(<<SASS)
2376
+ .mixed {
2377
+ required: foo;
2378
+ arg1: default-val1;
2379
+ arg2: default-val2; }
2380
+ CSS
2381
+ =a-mixin($required, $arg1: default-val1, $arg2: default-val2)
2382
+ required: $required
2383
+ arg1: $arg1
2384
+ arg2: $arg2
2385
+ .mixed
2386
+ +a-mixin($required: foo)
2387
+ SASS
2388
+ end
2389
+
2390
+ def test_passing_all_as_keyword_args_in_opposite_order
2391
+ assert_equal <<CSS, render(<<SASS)
2392
+ .mixed {
2393
+ required: foo;
2394
+ arg1: non-default-val1;
2395
+ arg2: non-default-val2; }
2396
+ CSS
2397
+ =a-mixin($required, $arg1: default-val1, $arg2: default-val2)
2398
+ required: $required
2399
+ arg1: $arg1
2400
+ arg2: $arg2
2401
+ .mixed
2402
+ +a-mixin($arg2: non-default-val2, $arg1: non-default-val1, $required: foo)
2403
+ SASS
2404
+ end
2405
+
2406
+ def test_function_output_with_comma
2407
+ assert_equal <<CSS, render(<<SASS)
2408
+ foo {
2409
+ a: b(c), d(e); }
2410
+ CSS
2411
+ foo
2412
+ a: b(c), d(e)
2413
+ SASS
2414
+ end
2415
+
2416
+ def test_interpolation_with_comma
2417
+ assert_equal <<CSS, render(<<SASS)
2418
+ foo {
2419
+ a: foo, bar; }
2420
+ CSS
2421
+ $foo: foo
2422
+ foo
2423
+ a: \#{$foo}, bar
2424
+ SASS
2425
+ end
2426
+
2427
+ def test_string_interpolation_with_comma
2428
+ assert_equal <<CSS, render(<<SASS)
2429
+ foo {
2430
+ a: "bip foo bap", bar; }
2431
+ CSS
2432
+ $foo: foo
2433
+ foo
2434
+ a: "bip \#{$foo} bap", bar
2435
+ SASS
2436
+ end
2437
+
2438
+ def test_unknown_directive
2439
+ assert_equal <<CSS, render(<<SASS)
2440
+ @baz {
2441
+ c: d; }
2442
+ CSS
2443
+ @baz
2444
+ c: d
2445
+ SASS
2446
+ end
2447
+
2448
+ def test_comment_interpolation_warning
2449
+ assert_warning(<<END) {render("/* \#{foo}")}
2450
+ WARNING:
2451
+ On line 1 of 'test_comment_interpolation_warning_inline.sass'
2452
+ Comments will evaluate the contents of interpolations (\#{ ... }) in Sass 3.2.
2453
+ Please escape the interpolation by adding a backslash before the `#`.
2454
+ END
2455
+ end
2456
+
2457
+ def test_loud_silent_comment_warning
2458
+ assert_warning(<<END) {render("//! \#{foo}")}
2459
+ WARNING:
2460
+ On line 1 of 'test_loud_silent_comment_warning_inline.sass'
2461
+ `//` comments will no longer be allowed to use the `!` flag in Sass 3.2.
2462
+ Please change to `/*` comments.
2463
+ END
2464
+ end
2465
+
2466
+ def test_loud_comment_interpolations_can_be_escaped
2467
+ assert_equal <<CSS, render(<<SASS)
2468
+ /* \#{foo} */
2469
+ CSS
2470
+ /* \\\#{foo}
2471
+ SASS
2472
+ assert_equal <<CSS, render(<<SASS)
2473
+ /* \#{foo} */
2474
+ CSS
2475
+ /*! \\\#{foo}
2476
+ SASS
2477
+ end
2478
+
2479
+ def test_selector_compression
2480
+ assert_equal <<CSS, render(<<SASS, :style => :compressed)
2481
+ a>b,c+d,:-moz-any(e,f,g){h:i}
2482
+ CSS
2483
+ a > b, c + d, :-moz-any(e, f, g)
2484
+ h: i
2485
+ SASS
2486
+ end
2487
+
2488
+ def test_comment_like_selector
2489
+ assert_raise_message(Sass::SyntaxError, 'Invalid CSS after "": expected selector, was "/ foo"') {render(<<SASS)}
2490
+ / foo
2491
+ a: b
2492
+ SASS
2493
+ end
2494
+
2495
+ def test_nested_empty_directive
2496
+ assert_equal <<CSS, render(<<SASS)
2497
+ @media screen {
2498
+ .foo {
2499
+ a: b; }
2500
+
2501
+ @unknown-directive; }
2502
+ CSS
2503
+ @media screen
2504
+ .foo
2505
+ a: b
2506
+
2507
+ @unknown-directive
2508
+ SASS
2509
+ end
2510
+
2511
+ # Encodings
2512
+
2513
+ unless Sass::Util.ruby1_8?
2514
+ def test_encoding_error
2515
+ render("foo\nbar\nb\xFEaz".force_encoding("utf-8"))
2516
+ assert(false, "Expected exception")
2517
+ rescue Sass::SyntaxError => e
2518
+ assert_equal(3, e.sass_line)
2519
+ assert_equal('Invalid UTF-8 character "\xFE"', e.message)
2520
+ end
2521
+
2522
+ def test_ascii_incompatible_encoding_error
2523
+ template = "foo\nbar\nb_z".encode("utf-16le")
2524
+ template[9] = "\xFE".force_encoding("utf-16le")
2525
+ render(template)
2526
+ assert(false, "Expected exception")
2527
+ rescue Sass::SyntaxError => e
2528
+ assert_equal(3, e.sass_line)
2529
+ assert_equal('Invalid UTF-16LE character "\xFE"', e.message)
2530
+ end
2531
+
2532
+ def test_same_charset_as_encoding
2533
+ assert_renders_encoded(<<CSS, <<SASS)
2534
+ @charset "UTF-8";
2535
+ fóó {
2536
+ a: b; }
2537
+ CSS
2538
+ @charset "utf-8"
2539
+ fóó
2540
+ a: b
2541
+ SASS
2542
+ end
2543
+
2544
+ def test_different_charset_than_encoding
2545
+ assert_renders_encoded(<<CSS.force_encoding("IBM866"), <<SASS)
2546
+ @charset "IBM866";
2547
+ fóó {
2548
+ a: b; }
2549
+ CSS
2550
+ @charset "ibm866"
2551
+ fóó
2552
+ a: b
2553
+ SASS
2554
+ end
2555
+
2556
+ def test_different_encoding_than_system
2557
+ assert_renders_encoded(<<CSS.encode("IBM866"), <<SASS.encode("IBM866"))
2558
+ @charset "IBM866";
2559
+ тАЬ {
2560
+ a: b; }
2561
+ CSS
2562
+ тАЬ
2563
+ a: b
2564
+ SASS
2565
+ end
2566
+
2567
+ def test_multibyte_charset
2568
+ assert_renders_encoded(<<CSS.encode("UTF-16LE"), <<SASS.encode("UTF-16LE").force_encoding("UTF-8"))
2569
+ @charset "UTF-16LE";
2570
+ fóó {
2571
+ a: b; }
2572
+ CSS
2573
+ @charset "utf-16le"
2574
+ fóó
2575
+ a: b
2576
+ SASS
2577
+ end
2578
+
2579
+ def test_multibyte_charset_without_endian_specifier
2580
+ assert_renders_encoded(<<CSS.encode("UTF-32BE"), <<SASS.encode("UTF-32BE").force_encoding("UTF-8"))
2581
+ @charset "UTF-32BE";
2582
+ fóó {
2583
+ a: b; }
2584
+ CSS
2585
+ @charset "utf-32"
2586
+ fóó
2587
+ a: b
2588
+ SASS
2589
+ end
2590
+
2591
+ def test_utf8_bom
2592
+ assert_renders_encoded(<<CSS, <<SASS.force_encoding("BINARY"))
2593
+ @charset "UTF-8";
2594
+ fóó {
2595
+ a: b; }
2596
+ CSS
2597
+ \uFEFFfóó
2598
+ a: b
2599
+ SASS
2600
+ end
2601
+
2602
+ def test_utf16le_bom
2603
+ assert_renders_encoded(<<CSS.encode("UTF-16LE"), <<SASS.encode("UTF-16LE").force_encoding("BINARY"))
2604
+ @charset "UTF-16LE";
2605
+ fóó {
2606
+ a: b; }
2607
+ CSS
2608
+ \uFEFFfóó
2609
+ a: b
2610
+ SASS
2611
+ end
2612
+
2613
+ def test_utf32be_bom
2614
+ assert_renders_encoded(<<CSS.encode("UTF-32BE"), <<SASS.encode("UTF-32BE").force_encoding("BINARY"))
2615
+ @charset "UTF-32BE";
2616
+ fóó {
2617
+ a: b; }
2618
+ CSS
2619
+ \uFEFFfóó
2620
+ a: b
2621
+ SASS
2622
+ end
2623
+
2624
+ # Encoding Regression Test
2625
+
2626
+ def test_multibyte_prop_name
2627
+ assert_equal(<<CSS, render(<<SASS))
2628
+ @charset "UTF-8";
2629
+ #bar {
2630
+ cölor: blue; }
2631
+ CSS
2632
+ #bar
2633
+ cölor: blue
2634
+ SASS
2635
+ end
2636
+
2637
+ def test_multibyte_and_interpolation
2638
+ assert_equal(<<CSS, render(<<SCSS, :syntax => :scss))
2639
+ #bar {
2640
+ background: a 0%; }
2641
+ CSS
2642
+ #bar {
2643
+ // 
2644
+ background: \#{a} 0%;
2645
+ }
2646
+ SCSS
2647
+ end
2648
+ end
2649
+
2650
+ def test_original_filename_set
2651
+ importer = MockImporter.new
2652
+ importer.add_import("imported", "div{color:red}")
2653
+
2654
+ original_filename = filename_for_test
2655
+ engine = Sass::Engine.new('@import "imported"; div{color:blue}',
2656
+ :filename => original_filename, :load_paths => [importer], :syntax => :scss)
2657
+ engine.render
2658
+
2659
+ assert_equal original_filename, engine.options[:original_filename]
2660
+ assert_equal original_filename, importer.engine("imported").options[:original_filename]
2661
+ end
2662
+
2663
+ def test_deprecated_PRECISION
2664
+ assert_warning(<<END) {assert_equal 1000.0, Sass::Script::Number::PRECISION}
2665
+ Sass::Script::Number::PRECISION is deprecated and will be removed in a future release. Use Sass::Script::Number.precision_factor instead.
2666
+ END
2667
+ end
2668
+ def test_changing_precision
2669
+ begin
2670
+ Sass::Script::Number.precision = 8
2671
+ assert_equal <<CSS, render(<<SASS)
2672
+ div {
2673
+ maximum: 1.00000001;
2674
+ too-much: 1.0; }
2675
+ CSS
2676
+ div
2677
+ maximum : 1.00000001
2678
+ too-much: 1.000000001
2679
+ SASS
2680
+ ensure
2681
+ Sass::Script::Number.precision = 3
2682
+ end
2683
+ end
2684
+
2685
+ private
2686
+
2687
+ def assert_hash_has(hash, expected)
2688
+ expected.each {|k, v| assert_equal(v, hash[k])}
2689
+ end
2690
+
2691
+ def assert_renders_encoded(css, sass)
2692
+ result = render(sass)
2693
+ assert_equal css.encoding, result.encoding
2694
+ assert_equal css, result
2695
+ end
2696
+
2697
+ def render(sass, options = {})
2698
+ munge_filename options
2699
+ Sass::Engine.new(sass, options).render
2700
+ end
2701
+
2702
+ def renders_correctly(name, options={})
2703
+ sass_file = load_file(name, "sass")
2704
+ css_file = load_file(name, "css")
2705
+ options[:filename] ||= filename(name, "sass")
2706
+ options[:syntax] ||= :sass
2707
+ options[:css_filename] ||= filename(name, "css")
2708
+ css_result = Sass::Engine.new(sass_file, options).render
2709
+ assert_equal css_file, css_result
2710
+ end
2711
+
2712
+ def load_file(name, type = "sass")
2713
+ @result = ''
2714
+ File.new(filename(name, type)).each_line { |l| @result += l }
2715
+ @result
2716
+ end
2717
+
2718
+ def filename(name, type)
2719
+ File.dirname(__FILE__) + "/#{type == 'sass' ? 'templates' : 'results'}/#{name}.#{type}"
2720
+ end
2721
+
2722
+ def sassc_path(template)
2723
+ sassc_path = File.join(File.dirname(__FILE__) + "/templates/#{template}.sass")
2724
+ engine = Sass::Engine.new("", :filename => sassc_path,
2725
+ :importer => Sass::Importers::Filesystem.new("."))
2726
+ key = engine.send(:sassc_key)
2727
+ File.join(engine.options[:cache_location], key)
2728
+ end
2729
+ end
2730
+