wlang 0.10.2 → 2.0.0.beta

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 (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