wlang 0.10.2 → 2.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (269) hide show
  1. data/CHANGELOG.md +3 -121
  2. data/Gemfile +23 -1
  3. data/Gemfile.lock +32 -28
  4. data/LICENCE.md +18 -21
  5. data/Manifest.txt +4 -5
  6. data/README.md +100 -174
  7. data/Rakefile +1 -13
  8. data/bin/wlang +3 -29
  9. data/lib/wlang.rb +21 -394
  10. data/lib/wlang/command.rb +94 -0
  11. data/lib/wlang/compiler.rb +78 -0
  12. data/lib/wlang/compiler/autospacing.rb +60 -0
  13. data/lib/wlang/compiler/dialect_enforcer.rb +91 -0
  14. data/lib/wlang/compiler/filter.rb +32 -0
  15. data/lib/wlang/compiler/grammar.citrus +67 -0
  16. data/lib/wlang/compiler/parser.rb +26 -0
  17. data/lib/wlang/compiler/proc_call_removal.rb +15 -0
  18. data/lib/wlang/compiler/static_merger.rb +28 -0
  19. data/lib/wlang/compiler/strconcat_flattener.rb +25 -0
  20. data/lib/wlang/compiler/to_ruby_abstraction.rb +22 -0
  21. data/lib/wlang/compiler/to_ruby_code.rb +55 -0
  22. data/lib/wlang/dialect.rb +40 -237
  23. data/lib/wlang/dialect/dispatching.rb +51 -0
  24. data/lib/wlang/dialect/evaluation.rb +30 -0
  25. data/lib/wlang/dialect/tags.rb +50 -0
  26. data/lib/wlang/dummy.rb +32 -0
  27. data/lib/wlang/html.rb +106 -0
  28. data/lib/wlang/loader.rb +6 -0
  29. data/lib/wlang/mustang.rb +90 -0
  30. data/lib/wlang/scope.rb +57 -0
  31. data/lib/wlang/scope/binding_scope.rb +18 -0
  32. data/lib/wlang/scope/object_scope.rb +25 -0
  33. data/lib/wlang/scope/proxy_scope.rb +18 -0
  34. data/lib/wlang/scope/root_scope.rb +24 -0
  35. data/lib/wlang/template.rb +16 -86
  36. data/lib/wlang/version.rb +9 -8
  37. data/spec/fixtures/dialect/foobar.rb +31 -0
  38. data/spec/fixtures/dialect/upcasing.rb +13 -0
  39. data/spec/fixtures/templates/hello.tpl +1 -0
  40. data/spec/integration/examples/1-basics.txt +65 -0
  41. data/spec/integration/examples/2-imperative.txt +51 -0
  42. data/spec/integration/examples/3-partials.txt +76 -0
  43. data/spec/integration/examples/4-recursion.txt +16 -0
  44. data/spec/integration/html/test_ampersand.rb +15 -0
  45. data/spec/integration/html/test_bang.rb +38 -0
  46. data/spec/integration/html/test_caret.rb +33 -0
  47. data/spec/integration/html/test_dollar.rb +16 -0
  48. data/spec/integration/html/test_greater.rb +23 -0
  49. data/spec/integration/html/test_modulo.rb +16 -0
  50. data/spec/integration/html/test_plus.rb +48 -0
  51. data/spec/integration/html/test_question.rb +33 -0
  52. data/spec/integration/html/test_sharp.rb +21 -0
  53. data/spec/integration/html/test_slash.rb +16 -0
  54. data/spec/integration/html/test_star.rb +37 -0
  55. data/spec/integration/test_dummy.rb +51 -0
  56. data/spec/integration/test_examples.rb +29 -0
  57. data/spec/integration/test_mustang.rb +120 -0
  58. data/spec/integration/test_readme.rb +56 -0
  59. data/spec/integration/test_upcasing.rb +22 -0
  60. data/spec/spec_helper.rb +62 -1
  61. data/spec/test_wlang.rb +101 -0
  62. data/spec/unit/compiler/autospacing/test_right_strip.rb +30 -0
  63. data/spec/unit/compiler/autospacing/test_unindent.rb +30 -0
  64. data/spec/unit/compiler/test_dialect_enforcer.rb +168 -0
  65. data/spec/unit/compiler/test_grammar.rb +207 -0
  66. data/spec/unit/compiler/test_parser.rb +69 -0
  67. data/spec/unit/compiler/test_proc_call_removal.rb +24 -0
  68. data/spec/unit/compiler/test_static_merger.rb +29 -0
  69. data/spec/unit/compiler/test_strconcat_flattener.rb +30 -0
  70. data/spec/unit/compiler/test_to_ruby_abstraction.rb +59 -0
  71. data/spec/unit/compiler/test_to_ruby_code.rb +24 -0
  72. data/spec/unit/dialect/test_compile.rb +52 -0
  73. data/spec/unit/dialect/test_dispatching.rb +19 -0
  74. data/spec/unit/dialect/test_evaluate.rb +41 -0
  75. data/spec/unit/dialect/test_render.rb +33 -0
  76. data/spec/unit/dialect/test_tags.rb +32 -0
  77. data/spec/unit/dialect/test_with_scope.rb +18 -0
  78. data/spec/unit/scope/test_binding_scope.rb +27 -0
  79. data/spec/unit/scope/test_coerce.rb +22 -0
  80. data/spec/unit/scope/test_object_scope.rb +38 -0
  81. data/spec/unit/scope/test_proxy_scope.rb +22 -0
  82. data/spec/unit/scope/test_root_scope.rb +22 -0
  83. data/spec/unit/test_assumptions.rb +29 -0
  84. data/spec/unit/test_scope.rb +57 -0
  85. data/tasks/debug_mail.rake +42 -45
  86. data/tasks/gem.rake +22 -17
  87. data/tasks/spec_test.rake +9 -17
  88. data/tasks/unit_test.rake +11 -12
  89. data/tasks/yard.rake +13 -13
  90. data/wlang.gemspec +36 -32
  91. data/wlang.noespec +27 -35
  92. metadata +268 -451
  93. data/doc/specification/about.rdoc +0 -61
  94. data/doc/specification/analytics.wtpl +0 -13
  95. data/doc/specification/dialect.wtpl +0 -14
  96. data/doc/specification/dialects.wtpl +0 -3
  97. data/doc/specification/examples.rb +0 -3
  98. data/doc/specification/glossary.wtpl +0 -14
  99. data/doc/specification/hosting.rdoc +0 -0
  100. data/doc/specification/overview.rdoc +0 -116
  101. data/doc/specification/rulesets.wtpl +0 -87
  102. data/doc/specification/specification.css +0 -53
  103. data/doc/specification/specification.html +0 -1690
  104. data/doc/specification/specification.js +0 -8
  105. data/doc/specification/specification.wtpl +0 -42
  106. data/doc/specification/specification.yml +0 -432
  107. data/doc/specification/symbols.wtpl +0 -16
  108. data/lib/wlang/dialect_dsl.rb +0 -141
  109. data/lib/wlang/dialect_loader.rb +0 -74
  110. data/lib/wlang/dialects/bluecloth_dialect.rb +0 -16
  111. data/lib/wlang/dialects/coderay_dialect.rb +0 -45
  112. data/lib/wlang/dialects/hosted_dialect.rb +0 -50
  113. data/lib/wlang/dialects/plain_text_dialect.rb +0 -69
  114. data/lib/wlang/dialects/rdoc_dialect.rb +0 -33
  115. data/lib/wlang/dialects/redcloth_dialect.rb +0 -16
  116. data/lib/wlang/dialects/ruby_dialect.rb +0 -118
  117. data/lib/wlang/dialects/sql_dialect.rb +0 -38
  118. data/lib/wlang/dialects/standard_dialects.rb +0 -181
  119. data/lib/wlang/dialects/xhtml_dialect.rb +0 -63
  120. data/lib/wlang/dialects/yaml_dialect.rb +0 -30
  121. data/lib/wlang/encoder.rb +0 -62
  122. data/lib/wlang/encoder_set.rb +0 -122
  123. data/lib/wlang/errors.rb +0 -80
  124. data/lib/wlang/ext/hash_methodize.rb +0 -13
  125. data/lib/wlang/ext/string.rb +0 -44
  126. data/lib/wlang/hash_scope.rb +0 -89
  127. data/lib/wlang/hosted_language.rb +0 -146
  128. data/lib/wlang/intelligent_buffer.rb +0 -94
  129. data/lib/wlang/parser.rb +0 -332
  130. data/lib/wlang/parser_state.rb +0 -94
  131. data/lib/wlang/rule.rb +0 -66
  132. data/lib/wlang/rule_set.rb +0 -106
  133. data/lib/wlang/rulesets/basic_ruleset.rb +0 -83
  134. data/lib/wlang/rulesets/buffering_ruleset.rb +0 -115
  135. data/lib/wlang/rulesets/context_ruleset.rb +0 -111
  136. data/lib/wlang/rulesets/encoding_ruleset.rb +0 -73
  137. data/lib/wlang/rulesets/imperative_ruleset.rb +0 -132
  138. data/lib/wlang/rulesets/ruleset_utils.rb +0 -317
  139. data/lib/wlang/wlang_command.rb +0 -51
  140. data/lib/wlang/wlang_command_options.rb +0 -163
  141. data/spec/basic_object.spec +0 -40
  142. data/spec/coderay_dialect.spec +0 -8
  143. data/spec/dialect/apply_post_transform.spec +0 -16
  144. data/spec/global_extensions.rb +0 -2
  145. data/spec/hash_scope.spec +0 -76
  146. data/spec/redcloth_dialect.spec +0 -24
  147. data/spec/test_all.rb +0 -8
  148. data/spec/wlang.spec +0 -53
  149. data/spec/wlang_spec.rb +0 -8
  150. data/spec/xhtml_dialect.spec +0 -22
  151. data/tasks/genspec.rake +0 -5
  152. data/test/blackbox/basic/execution_1.exp +0 -1
  153. data/test/blackbox/basic/execution_1.tpl +0 -1
  154. data/test/blackbox/basic/execution_2.exp +0 -1
  155. data/test/blackbox/basic/execution_2.tpl +0 -1
  156. data/test/blackbox/basic/execution_3.exp +0 -1
  157. data/test/blackbox/basic/execution_3.tpl +0 -1
  158. data/test/blackbox/basic/execution_4.exp +0 -1
  159. data/test/blackbox/basic/execution_4.tpl +0 -1
  160. data/test/blackbox/basic/inclusion_1.exp +0 -1
  161. data/test/blackbox/basic/inclusion_1.tpl +0 -1
  162. data/test/blackbox/basic/inclusion_2.exp +0 -1
  163. data/test/blackbox/basic/inclusion_2.tpl +0 -1
  164. data/test/blackbox/basic/injection_1.exp +0 -1
  165. data/test/blackbox/basic/injection_1.tpl +0 -1
  166. data/test/blackbox/basic/injection_2.exp +0 -1
  167. data/test/blackbox/basic/injection_2.tpl +0 -1
  168. data/test/blackbox/basic/modulation_1.exp +0 -1
  169. data/test/blackbox/basic/modulation_1.tpl +0 -1
  170. data/test/blackbox/basic/modulation_2.exp +0 -1
  171. data/test/blackbox/basic/modulation_2.tpl +0 -1
  172. data/test/blackbox/basic/recursive_app_1.exp +0 -1
  173. data/test/blackbox/basic/recursive_app_1.tpl +0 -1
  174. data/test/blackbox/basic/recursive_app_2.exp +0 -1
  175. data/test/blackbox/basic/recursive_app_2.tpl +0 -1
  176. data/test/blackbox/buffering/data_1.rb +0 -1
  177. data/test/blackbox/buffering/data_assignment_1.exp +0 -1
  178. data/test/blackbox/buffering/data_assignment_1.tpl +0 -1
  179. data/test/blackbox/buffering/data_assignment_2.exp +0 -1
  180. data/test/blackbox/buffering/data_assignment_2.tpl +0 -1
  181. data/test/blackbox/buffering/data_assignment_3.exp +0 -1
  182. data/test/blackbox/buffering/data_assignment_3.tpl +0 -1
  183. data/test/blackbox/buffering/data_assignment_4.exp +0 -1
  184. data/test/blackbox/buffering/data_assignment_4.tpl +0 -1
  185. data/test/blackbox/buffering/input_1.exp +0 -1
  186. data/test/blackbox/buffering/input_1.tpl +0 -1
  187. data/test/blackbox/buffering/input_2.exp +0 -1
  188. data/test/blackbox/buffering/input_2.tpl +0 -1
  189. data/test/blackbox/buffering/input_3.exp +0 -1
  190. data/test/blackbox/buffering/input_3.tpl +0 -1
  191. data/test/blackbox/buffering/input_inclusion.exp +0 -1
  192. data/test/blackbox/buffering/input_inclusion.tpl +0 -1
  193. data/test/blackbox/buffering/input_inclusion_1.exp +0 -0
  194. data/test/blackbox/buffering/input_inclusion_1.tpl +0 -1
  195. data/test/blackbox/buffering/input_inclusion_2.exp +0 -1
  196. data/test/blackbox/buffering/input_inclusion_2.tpl +0 -1
  197. data/test/blackbox/buffering/input_inclusion_3.exp +0 -1
  198. data/test/blackbox/buffering/input_inclusion_3.tpl +0 -1
  199. data/test/blackbox/buffering/input_inclusion_4.exp +0 -0
  200. data/test/blackbox/buffering/input_inclusion_4.tpl +0 -1
  201. data/test/blackbox/buffering/input_inclusion_5.exp +0 -1
  202. data/test/blackbox/buffering/input_inclusion_5.tpl +0 -1
  203. data/test/blackbox/buffering/input_inclusion_6.exp +0 -1
  204. data/test/blackbox/buffering/input_inclusion_6.tpl +0 -1
  205. data/test/blackbox/buffering/input_inclusion_7.exp +0 -0
  206. data/test/blackbox/buffering/input_inclusion_7.tpl +0 -1
  207. data/test/blackbox/buffering/text_1.txt +0 -1
  208. data/test/blackbox/buffering/wlang.txt +0 -1
  209. data/test/blackbox/context/assignment_1.exp +0 -1
  210. data/test/blackbox/context/assignment_1.tpl +0 -1
  211. data/test/blackbox/context/assignment_2.exp +0 -1
  212. data/test/blackbox/context/assignment_2.tpl +0 -1
  213. data/test/blackbox/context/assignment_3.exp +0 -2
  214. data/test/blackbox/context/assignment_3.tpl +0 -2
  215. data/test/blackbox/context/assignment_4.exp +0 -1
  216. data/test/blackbox/context/assignment_4.tpl +0 -1
  217. data/test/blackbox/context/block_assignment_1.exp +0 -1
  218. data/test/blackbox/context/block_assignment_1.tpl +0 -1
  219. data/test/blackbox/context/block_assignment_2.exp +0 -1
  220. data/test/blackbox/context/block_assignment_2.tpl +0 -1
  221. data/test/blackbox/context/modulo_assignment_1.exp +0 -1
  222. data/test/blackbox/context/modulo_assignment_1.tpl +0 -1
  223. data/test/blackbox/context/modulo_assignment_2.exp +0 -1
  224. data/test/blackbox/context/modulo_assignment_2.tpl +0 -1
  225. data/test/blackbox/data_1.rb +0 -1
  226. data/test/blackbox/postblock/hello.exp +0 -1
  227. data/test/blackbox/postblock/hello.pre +0 -1
  228. data/test/blackbox/postblock/hello.tpl +0 -1
  229. data/test/blackbox/postblock/hello_input_inclusion.exp +0 -1
  230. data/test/blackbox/postblock/hello_input_inclusion.tpl +0 -1
  231. data/test/blackbox/postblock/hello_to_authors.exp +0 -1
  232. data/test/blackbox/postblock/hello_to_authors.tpl +0 -1
  233. data/test/blackbox/poststring/hello.exp +0 -1
  234. data/test/blackbox/poststring/hello.tpl +0 -1
  235. data/test/blackbox/test_all.rb +0 -70
  236. data/test/standard_dialects/ruby/data.rb +0 -7
  237. data/test/standard_dialects/ruby/inclusion.exp +0 -6
  238. data/test/standard_dialects/ruby/inclusion.tpl +0 -6
  239. data/test/standard_dialects/test_all.rb +0 -29
  240. data/test/standard_dialects/yaml/assumptions_test.rb +0 -13
  241. data/test/standard_dialects/yaml/data.rb +0 -3
  242. data/test/standard_dialects/yaml/inclusion_1.exp +0 -7
  243. data/test/standard_dialects/yaml/inclusion_1.tpl +0 -2
  244. data/test/standard_dialects/yaml/inclusion_2.exp +0 -5
  245. data/test/standard_dialects/yaml/inclusion_2.tpl +0 -3
  246. data/test/unit/test_all.rb +0 -9
  247. data/test/unit/wlang/anagram_bugs_test.rb +0 -111
  248. data/test/unit/wlang/basic_ruleset_test.rb +0 -52
  249. data/test/unit/wlang/buffering_ruleset_test.rb +0 -102
  250. data/test/unit/wlang/buffering_template1.wtpl +0 -1
  251. data/test/unit/wlang/buffering_template2.wtpl +0 -1
  252. data/test/unit/wlang/buffering_template3.wtpl +0 -1
  253. data/test/unit/wlang/buffering_template4.wtpl +0 -1
  254. data/test/unit/wlang/buffering_template5.wtpl +0 -1
  255. data/test/unit/wlang/context_ruleset_test.rb +0 -32
  256. data/test/unit/wlang/data.rb +0 -3
  257. data/test/unit/wlang/encoder_set_test.rb +0 -42
  258. data/test/unit/wlang/imperative_ruleset_test.rb +0 -107
  259. data/test/unit/wlang/intelligent_buffer_test.rb +0 -194
  260. data/test/unit/wlang/othersymbols_test.rb +0 -16
  261. data/test/unit/wlang/parser_test.rb +0 -88
  262. data/test/unit/wlang/plain_text_dialect_test.rb +0 -21
  263. data/test/unit/wlang/ruby_dialect_test.rb +0 -100
  264. data/test/unit/wlang/ruby_expected.rb +0 -3
  265. data/test/unit/wlang/ruby_template.wrb +0 -3
  266. data/test/unit/wlang/ruleset_utils_test.rb +0 -245
  267. data/test/unit/wlang/specification_examples_test.rb +0 -54
  268. data/test/unit/wlang/test_utils.rb +0 -25
  269. data/test/unit/wlang/wlang_test.rb +0 -80
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+ require 'wlang/mustang'
3
+ module WLang
4
+ describe Mustang do
5
+
6
+ describe "The Highlighter example" do
7
+
8
+ class Highlighter < WLang::Dialect
9
+
10
+ def highlight(buf, fn)
11
+ var_name = render(fn)
12
+ var_value = evaluate(var_name)
13
+ buf << var_value.to_s.upcase
14
+ end
15
+
16
+ tag '$', :highlight
17
+ end
18
+
19
+ it 'works as announced' do
20
+ expected = "Hello YOU & THE WORLD!"
21
+ got = Highlighter.render "Hello ${who}!", :who => "you & the world"
22
+ got.should eq(expected)
23
+ end
24
+
25
+ end # Highlighter example
26
+
27
+ describe "the HighLevel example" do
28
+
29
+ class HighLevel < WLang::Dialect
30
+
31
+ def join(buf, expr, main, between)
32
+ evaluate(expr).each_with_index do |val,i|
33
+ buf << render(between, val) unless i==0
34
+ buf << render(main, val).strip
35
+ end
36
+ end
37
+
38
+ def print(buf, fn)
39
+ buf << evaluate(fn).to_s
40
+ end
41
+
42
+ tag '*', :join
43
+ tag '$', :print
44
+ end
45
+
46
+ it 'works as announced' do
47
+ expected = "Hello you and wlang and world !"
48
+ template = 'Hello *{ ${collection} }{ ${self} }{ and } !'
49
+ context = {:collection => 'whos', :whos => [ "you", "wlang", "world" ] }
50
+ got = HighLevel.render template, context
51
+ got.should eq(expected)
52
+ end
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ describe Upcasing do
4
+
5
+ def upcasing(tpl, scope = {})
6
+ Upcasing.render(tpl, scope)
7
+ end
8
+
9
+ it 'upcases the string under $' do
10
+ upcasing("Hello ${world}!").should eq("Hello WORLD!")
11
+ end
12
+
13
+ it 'evaluates the string under #' do
14
+ upcasing('Hello #{who}!', :who => "World").should eq("Hello World!")
15
+ end
16
+
17
+ it 'raises when not found' do
18
+ lambda{ upcasing('Hello #{who}!') }.should raise_error(NameError)
19
+ end
20
+
21
+ end # describe Dummy
22
+ end # module WLang
@@ -1,2 +1,63 @@
1
- $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
1
+ require 'epath'
2
+ $root_folder ||= Path.backfind('.[Rakefile]')
3
+
4
+ # Require wlang
5
+ $LOAD_PATH.unshift(($root_folder/:lib).to_s)
2
6
  require 'wlang'
7
+
8
+ # RSpec helpers
9
+ require 'rspec'
10
+ module Helpers
11
+ include WLang
12
+ extend(self)
13
+
14
+ def root_folder
15
+ $root_folder
16
+ end
17
+
18
+ def spec_folder
19
+ root_folder/:spec
20
+ end
21
+
22
+ def fixtures_folder
23
+ spec_folder/:fixtures
24
+ end
25
+
26
+ def tpl_path(what)
27
+ what = "#{what}.tpl" if what.is_a?(Symbol)
28
+ fixtures_folder/:templates/what
29
+ end
30
+
31
+ def tpl(what)
32
+ tpl_path(what).read
33
+ end
34
+
35
+ # Load fixture dialects
36
+ spec_folder.glob("fixtures/dialect/*.rb").each do |f|
37
+ require f.expand_path
38
+ end
39
+
40
+ # Install helper methods for templates
41
+ fixtures_folder.glob("templates/*.tpl").each do |f|
42
+ name = f.basename.without_extension
43
+ define_method(:"#{name}_path") do
44
+ fixtures_folder/:templates/f.basename
45
+ end
46
+ define_method(:"#{name}_tpl") do
47
+ send(:"#{name}_path").read
48
+ end
49
+ define_method(:"#{name}_io") do |&b|
50
+ send(:"#{name}_path").open("r") do |io|
51
+ b.call(io)
52
+ end
53
+ end
54
+ end
55
+
56
+ end
57
+ include Helpers
58
+
59
+ # Configure rspec
60
+ RSpec.configure do |c|
61
+ c.include Helpers
62
+ c.filter_run_excluding :hash_ordering => true if RUBY_VERSION < "1.9"
63
+ end
@@ -0,0 +1,101 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+ describe WLang do
3
+
4
+ it "has a version number" do
5
+ WLang.const_defined?(:VERSION).should be_true
6
+ end
7
+
8
+ let(:d){
9
+ WLang::dialect do
10
+ tag('$') do |buf, fn|
11
+ if x = evaluate(fn)
12
+ buf << x.to_s
13
+ end
14
+ end
15
+ end
16
+ }
17
+
18
+ it 'allows building on-the-fly dialects' do
19
+ d.render(hello_tpl, :who => "world").should eq("Hello world!")
20
+ end
21
+
22
+ ### overriding
23
+
24
+ it 'allows overriding super-dialect tags' do
25
+ e = WLang::dialect(d) do
26
+ tag('$') do |buf, fn1|
27
+ buf << render(fn1).capitalize
28
+ end
29
+ end
30
+ e.render(hello_tpl).should eq("Hello Who!")
31
+ end
32
+
33
+ it 'allows overriding super-dialect evaluation rules' do
34
+ e = WLang::dialect(d) do
35
+ def evaluate(expr); super rescue ""; end
36
+ end
37
+ e.render(hello_tpl).should eq("Hello !")
38
+ end
39
+
40
+ it 'does not override the super-dialect evaluation rules' do
41
+ e = WLang::dialect(d) do
42
+ def evaluate(expr); super rescue ""; end
43
+ end
44
+ lambda{ d.render(hello_tpl) }.should raise_error(NameError)
45
+ end
46
+
47
+ ### default scoping
48
+
49
+ it 'allows a hash for scoping by default' do
50
+ d.render(hello_tpl, :who => "World").should eq("Hello World!")
51
+ end
52
+
53
+ it 'allows binding for scoping by default' do
54
+ who = "World"
55
+ d.render(hello_tpl, binding).should eq("Hello World!")
56
+ end
57
+
58
+ ### high-order and multi-dialects
59
+
60
+ it 'allows high-order constructions' do
61
+ scope = {:who => :world, :world => "World"}
62
+ d.render('Hello ${${who}}!', scope).should eq("Hello World!")
63
+ end
64
+
65
+ it 'allows switching the current dialect' do
66
+ e = WLang::dialect do
67
+ tag '!', [Upcasing] do |buf,fn|
68
+ buf << evaluate(fn).to_s;
69
+ end
70
+ end
71
+ scope = {:WHO => "World"}
72
+ e.render('Hello !{${who}}!', scope).should eq("Hello World!")
73
+ end
74
+
75
+ ### autospacing
76
+
77
+ it 'handles magic spacing on a static block' do
78
+ e = WLang::dialect do
79
+ default_options :autospacing => true
80
+ tag '$' do |buf,fn| buf << render(fn) end
81
+ end
82
+ source = "${\n hello world\n}"
83
+ expected = "hello world"
84
+ pending{
85
+ e.render(source).should eq(expected)
86
+ }
87
+ end
88
+
89
+ it 'handles magic spacing on a wlang block' do
90
+ e = WLang::dialect do
91
+ default_options :autospacing => true
92
+ tag '$' do |buf,fn| buf << render(fn) end
93
+ end
94
+ source = "${\n ${name}\n ${score}\n}"
95
+ expected = "name\nscore"
96
+ pending{
97
+ e.render(source).should eq(expected)
98
+ }
99
+ end
100
+
101
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ class Compiler
4
+ describe Autospacing::RightStrip do
5
+
6
+ def optimize(source)
7
+ Autospacing::RightStrip.new.call(source)
8
+ end
9
+
10
+ it 'does not touch single line statics' do
11
+ source = [:static, "Hello World"]
12
+ expected = [:static, "Hello World"]
13
+ optimize(source).should eq(expected)
14
+ end
15
+
16
+ it 'strips at right on :static' do
17
+ source = [:static, "Hello World \n "]
18
+ expected = [:static, "Hello World"]
19
+ optimize(source).should eq(expected)
20
+ end
21
+
22
+ it 'strips the right-most :static on :strconcat' do
23
+ source = [:strconcat, [:static, "Hello \n"], [:static, " World\n"]]
24
+ expected = [:strconcat, [:static, "Hello \n"], [:static, " World"]]
25
+ optimize(source).should eq(expected)
26
+ end
27
+
28
+ end # describe Autospacing::RightStrip
29
+ end # class Compiler
30
+ end # module WLang
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ class Compiler
4
+ describe Autospacing::Unindent do
5
+
6
+ def optimize(source)
7
+ Autospacing::Unindent.new.call(source)
8
+ end
9
+
10
+ it 'unindents :static' do
11
+ source = [:static, " Hello World"]
12
+ expected = [:static, "Hello World"]
13
+ optimize(source).should eq(expected)
14
+ end
15
+
16
+ it 'unindents :static when multiple lines' do
17
+ source = [:static, " Hello\n World"]
18
+ expected = [:static, "Hello\nWorld"]
19
+ optimize(source).should eq(expected)
20
+ end
21
+
22
+ it 'recurses on :strconcat' do
23
+ source = [:strconcat, [:static, " Hello"], [:static, " World"]]
24
+ expected = [:strconcat, [:static, "Hello"], [:static, "World"]]
25
+ optimize(source).should eq(expected)
26
+ end
27
+
28
+ end # describe Autospacing::Unindent
29
+ end # class Compiler
30
+ end # module WLang
@@ -0,0 +1,168 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ class Compiler
4
+ class DialectEnforcer
5
+ public :find_dispatching_method
6
+ end
7
+ describe DialectEnforcer do
8
+
9
+ let(:dialect){
10
+ WLang::dialect{
11
+ tag('$') do |buf,fn| buf << "$" end
12
+ tag('!$') do |buf,fn| buf << "!$" end
13
+ tag('*') do |buf,fn1,fn2| end
14
+ tag('%', [WLang::Dummy]) do |buf, fn| end
15
+ }.factor
16
+ }
17
+
18
+ describe 'find_dispatching_method' do
19
+ let(:e){ DialectEnforcer.new(:dialect => dialect) }
20
+ it 'works on exact matching' do
21
+ e.find_dispatching_method("$").should eq(['', :_tag_36])
22
+ end
23
+ it 'takes the most specific' do
24
+ e.find_dispatching_method("$").should eq(['', :_tag_36])
25
+ e.find_dispatching_method("!$").should eq(['', :_tag_33_36])
26
+ end
27
+ it 'recognizes extras' do
28
+ e.find_dispatching_method("@$").should eq(['@', :_tag_36])
29
+ e.find_dispatching_method("@!$").should eq(['@', :_tag_33_36])
30
+ end
31
+ it 'recognizes missings' do
32
+ e.find_dispatching_method("#").should eq(['#', nil])
33
+ e.find_dispatching_method("@#").should eq(['@#', nil])
34
+ end
35
+ end
36
+
37
+ def optimize(source)
38
+ DialectEnforcer.new(:dialect => dialect).call(source)
39
+ end
40
+
41
+ let(:unknown){[
42
+ [:wlang, '!', [:fn, [:static, "hello"]]],
43
+ [:strconcat, [:static, "!"], [:static, "{"], [:static, "hello"], [:static, "}"]]
44
+ ]}
45
+ let(:hello_fn){[
46
+ [:fn, unknown.first],
47
+ [:fn, unknown.last]
48
+ ]}
49
+ let(:hello_dollar){[
50
+ [:wlang, '$', hello_fn.first],
51
+ [:wlang, '$', hello_fn.last]
52
+ ]}
53
+
54
+ ### recursion rules
55
+
56
+ it 'recurses on template' do
57
+ source = [:template, hello_dollar.first]
58
+ expected = [:template, hello_dollar.last]
59
+ optimize(source).should eq(expected)
60
+ end
61
+
62
+ it 'leaves [:static, ...] unchanged' do
63
+ source = [:static, "Hello world"]
64
+ optimize(source).should eq(source)
65
+ end
66
+
67
+ it 'leaves [:strconcat, ...] unchanged if no tag' do
68
+ source = [:strconcat, [:static, "Hello "], [:static, "world"]]
69
+ optimize(source).should eq(source)
70
+ end
71
+
72
+ it 'recurses on [:strconcat, ...] to optimize further' do
73
+ source = [:strconcat, unknown.first]
74
+ expected = [:strconcat, unknown.last]
75
+ optimize(source).should eq(expected)
76
+ end
77
+
78
+ ### exact symbols
79
+
80
+ it 'optimizes on exact symbols' do
81
+ optimize(hello_dollar.first).should eq(hello_dollar.last)
82
+ end
83
+
84
+ it 'detects extra symbols' do
85
+ source = [:wlang, '@$', hello_fn.first]
86
+ expected = [:strconcat, [:static, "@"], hello_dollar.last]
87
+ optimize(source).should eq(expected)
88
+ end
89
+
90
+ ### unknown tags
91
+
92
+ it 'recognizes unknown tags' do
93
+ optimize(unknown.first).should eq(unknown.last)
94
+ end
95
+
96
+ it 'recognizes unknown tags even if enclosed' do
97
+ source = [:wlang, '$', [:fn, unknown.first]]
98
+ expected = [:wlang, '$', [:fn, unknown.last]]
99
+ optimize(source).should eq(expected)
100
+ end
101
+
102
+ ### high-order wlang
103
+
104
+ it 'applies dynamic dispatching on high-order wlang' do
105
+ source = [:wlang, '$', [:fn, hello_dollar.first]]
106
+ expected = [:wlang, '$', [:fn, hello_dollar.last]]
107
+ optimize(source).should eq(expected)
108
+ end
109
+
110
+ ### arity 2
111
+
112
+ it 'supports tags of arity 2' do
113
+ source = [:wlang, '*', hello_fn.first, hello_fn.first]
114
+ expected = [:wlang, '*', hello_fn.last, hello_fn.last]
115
+ optimize(source).should eq(expected)
116
+ end
117
+
118
+ ### missing blocks
119
+
120
+ it 'detects missing blocks on arity 1' do
121
+ source = [:wlang, '$']
122
+ expected = [:wlang, '$', [:arg, nil]]
123
+ optimize(source).should eq(expected)
124
+ end
125
+
126
+ it 'detects missing blocks on arity 2' do
127
+ source = [:wlang, '*', hello_fn.first]
128
+ expected = [:wlang, '*', hello_fn.last, [:arg, nil]]
129
+ optimize(source).should eq(expected)
130
+ end
131
+
132
+ ### trailing blocks
133
+
134
+ it 'detects trailing blocks' do
135
+ source = [:wlang, '$', hello_fn.first, hello_fn.first]
136
+ expected = \
137
+ [:strconcat,
138
+ [:wlang, '$', hello_fn.last],
139
+ [:static, '{'],
140
+ hello_fn.last.last,
141
+ [:static, '}']
142
+ ]
143
+ optimize(source).should eq(expected)
144
+ end
145
+
146
+ it 'detects trailing blocks on arity 2' do
147
+ source = [:wlang, '*', hello_fn.first, hello_fn.first, hello_fn.first]
148
+ expected = \
149
+ [:strconcat,
150
+ [:wlang, '*', hello_fn.last, hello_fn.last],
151
+ [:static, '{'],
152
+ hello_fn.last.last,
153
+ [:static, '}']
154
+ ]
155
+ optimize(source).should eq(expected)
156
+ end
157
+
158
+ ### dialect switching
159
+
160
+ it 'introduce dialect switching mechanism' do
161
+ source = [:wlang, '%', hello_fn.first]
162
+ expected = [:wlang, '%', [:modulo, WLang::Dummy, hello_fn.last]]
163
+ optimize(source).should eq(expected)
164
+ end
165
+
166
+ end # describe DialectEnforcer
167
+ end # class Compiler
168
+ end # module WLang