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,207 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ describe Grammar do
4
+
5
+ let(:grammar){ WLang::Grammar }
6
+
7
+ context "parsing" do
8
+
9
+ subject{
10
+ if defined?(trailing)
11
+ grammar.parse(text, :root => rule, :consume => false)
12
+ else
13
+ grammar.parse(text, :root => rule)
14
+ end
15
+ }
16
+ after { subject.should eq(text) }
17
+
18
+ describe 'the fn_start rule' do
19
+ let(:rule){ :fn_start }
20
+ let(:text){ "{" }
21
+ it{ should_not be_nil }
22
+ end
23
+
24
+ describe 'the fn_stop rule' do
25
+ let(:rule){ :fn_stop }
26
+ let(:text){ "}" }
27
+ it{ should_not be_nil }
28
+ end
29
+
30
+ describe 'the symbols rule' do
31
+ let(:rule){ :symbols }
32
+ WLang::SYMBOLS.each do |sym|
33
+ describe 'on #{sym}' do
34
+ let(:text){ sym }
35
+ it{ should_not be_nil }
36
+ end
37
+ end
38
+ describe 'on "<<+"' do
39
+ let(:text){ "<<+" }
40
+ it{ should_not be_nil }
41
+ end
42
+ describe 'on joined symbols' do
43
+ let(:text){ WLang::SYMBOLS.join }
44
+ it{ should_not be_nil }
45
+ end
46
+ end
47
+
48
+ describe 'the stop char rule' do
49
+ let(:rule){ :stop_char }
50
+ describe 'on {' do
51
+ let(:text){ '{' }
52
+ it{ should_not be_nil }
53
+ end
54
+ describe 'on }' do
55
+ let(:text){ '}' }
56
+ it{ should_not be_nil }
57
+ end
58
+ describe 'on ${' do
59
+ let(:text){ '${' }
60
+ it{ should_not be_nil }
61
+ end
62
+ describe 'on <<+{' do
63
+ let(:text){ '<<+{' }
64
+ it{ should_not be_nil }
65
+ end
66
+ end
67
+
68
+ describe 'the block rule' do
69
+ let(:rule){ :block }
70
+ let(:text){ '{ hello }' }
71
+ it{ should_not be_nil }
72
+ end
73
+
74
+ describe 'the wlang rule' do
75
+ let(:rule){ :wlang }
76
+ describe 'on a single wlang block' do
77
+ let(:text){ '${who}' }
78
+ it{ should_not be_nil }
79
+ end
80
+ describe 'on a wlang with two blocks' do
81
+ let(:text){ '${who}{,}' }
82
+ it{ should_not be_nil }
83
+ end
84
+ end
85
+
86
+ describe 'the static rule' do
87
+ let(:rule){ :static }
88
+ describe 'on pure static text' do
89
+ let(:text){ 'Hello world' }
90
+ it{ should_not be_nil }
91
+ end
92
+ describe 'with trailing chars' do
93
+ let(:text){ 'Hello ' }
94
+ let(:trailing){ "${who}" }
95
+ it{ should_not be_nil }
96
+ end
97
+ end
98
+
99
+ describe 'the non_static rule on a block' do
100
+ describe 'on a block' do
101
+ let(:rule){ :non_static }
102
+ let(:text){ '{ hello }' }
103
+ it{ should_not be_nil }
104
+ end
105
+ describe 'on a wlang' do
106
+ let(:rule){ :non_static }
107
+ let(:text){ '${who}' }
108
+ it{ should_not be_nil }
109
+ end
110
+ end
111
+
112
+ describe 'the strconcat rule' do
113
+ let(:rule){ :strconcat }
114
+ let(:text){ 'Hello ${who}' }
115
+ it{ should_not be_nil }
116
+ end
117
+
118
+ describe "the template rule" do
119
+ let(:rule){ :template }
120
+ describe 'on an empty template' do
121
+ let(:text){ "" }
122
+ it{ should_not be_nil }
123
+ end
124
+ describe 'on a static template' do
125
+ let(:text){ "Hello world" }
126
+ it{ should_not be_nil }
127
+ end
128
+ describe 'on a block' do
129
+ let(:text){ "{ world }" }
130
+ it{ should_not be_nil }
131
+ end
132
+ describe 'on a wlang' do
133
+ let(:text){ "${who}" }
134
+ it{ should_not be_nil }
135
+ end
136
+ describe 'on a high-order wlang' do
137
+ let(:text){ "${${who}}" }
138
+ it{ should_not be_nil }
139
+ end
140
+ describe 'on a mix' do
141
+ let(:text){ "Hello ${who}!" }
142
+ it{ should_not be_nil }
143
+ end
144
+ end
145
+
146
+ end
147
+
148
+ context "value" do
149
+
150
+ subject{ grammar.parse(text, :root => rule).value }
151
+
152
+ describe 'the static rule' do
153
+ let(:rule){ :static }
154
+ let(:text){ "Hello world!" }
155
+ it{ should eq([:static, text]) }
156
+ end
157
+
158
+ describe 'the block rule' do
159
+ let(:rule){ :block }
160
+ let(:text){ "{ world }" }
161
+ it{ should eq([:static, text]) }
162
+ end
163
+
164
+ describe 'the wlang rule' do
165
+ let(:rule){ :wlang }
166
+ let(:text){ "${who}" }
167
+ it{ should eq([:wlang, '$', [:fn, [:static, "who"]] ]) }
168
+ end
169
+
170
+ describe 'the strconcat rule' do
171
+ let(:rule){ :strconcat }
172
+ describe "when a single match" do
173
+ let(:text){ "Hello world" }
174
+ it{ should eq([:static, text]) }
175
+ end
176
+ describe "with multiple matches" do
177
+ let(:text){ "Hello ${who}!" }
178
+ specify{
179
+ expected = \
180
+ [:strconcat,
181
+ [:static, "Hello "],
182
+ [:wlang, '$', [:fn, [:static, "who"]]],
183
+ [:static, "!"]]
184
+ subject.should eq(expected)
185
+ }
186
+ end
187
+ end
188
+
189
+ describe 'the template rule' do
190
+ let(:rule){ :template }
191
+ let(:text){ "Hello ${who}!" }
192
+ specify{
193
+ expected = \
194
+ [:template,
195
+ [:fn,
196
+ [:strconcat,
197
+ [:static, "Hello "],
198
+ [:wlang, '$', [:fn, [:static, "who"]]],
199
+ [:static, "!"]]]]
200
+ subject.should eq(expected)
201
+ }
202
+ end
203
+
204
+ end
205
+
206
+ end
207
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ describe Parser do
4
+
5
+ def parse(input)
6
+ WLang::Parser.new.call(input)
7
+ end
8
+
9
+ let(:expected) {
10
+ [:template,
11
+ [:fn,
12
+ [:strconcat,
13
+ [:static, "Hello "],
14
+ [:wlang, "$",
15
+ [:fn,
16
+ [:static, "who"]]],
17
+ [:static, "!"]]]]
18
+ }
19
+
20
+ it 'should parse "Hello ${world}!" as expected' do
21
+ parse(hello_tpl).should eq(expected)
22
+ end
23
+
24
+ it 'should support high-order wlang' do
25
+ expected = \
26
+ [:template,
27
+ [:fn,
28
+ [:wlang, "$",
29
+ [:fn,
30
+ [:wlang, "$",
31
+ [:fn,
32
+ [:static, "who"]]]]]]]
33
+ parse("${${who}}").should eq(expected)
34
+ end
35
+
36
+ it 'should support mutli-block functions' do
37
+ expected = \
38
+ [:template,
39
+ [:fn,
40
+ [:wlang, "$",
41
+ [:fn, [:static, "first" ]],
42
+ [:fn, [:static, "second"]]]]]
43
+ parse("${first}{second}").should eq(expected)
44
+ end
45
+
46
+ it 'is idempotent' do
47
+ parse(parse(hello_tpl)).should eq(expected)
48
+ end
49
+
50
+ it 'supports a path-like object' do
51
+ parse(hello_path).should eq(expected)
52
+ end
53
+
54
+ it 'supports an IO object' do
55
+ hello_io{|io| parse(io)}.should eq(expected)
56
+ end
57
+
58
+ it 'recognizes objects that respond to :to_path' do
59
+ s = Struct.new(:to_path).new(hello_path)
60
+ parse(s).should eq(expected)
61
+ end
62
+
63
+ it 'recognizes objects that respond to :to_str' do
64
+ s = Struct.new(:to_str).new(hello_tpl)
65
+ parse(s).should eq(expected)
66
+ end
67
+
68
+ end
69
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ class Compiler
4
+ describe ProcCallRemoval do
5
+
6
+ def optimize(source)
7
+ ProcCallRemoval.new.call(source)
8
+ end
9
+
10
+ it 'optimizes :fn' do
11
+ source = [:fn, [:static, "Hello world"]]
12
+ expected = [:arg, "Hello world"]
13
+ optimize(source).should eq(expected)
14
+ end
15
+
16
+ it 'recurses on :wlang' do
17
+ source = [:wlang, '$', [:fn, [:static, "Hello world"]]]
18
+ expected = [:wlang, '$', [:arg, "Hello world"]]
19
+ optimize(source).should eq(expected)
20
+ end
21
+
22
+ end # describe ToRubyCode
23
+ end # class Compiler
24
+ end # module WLang
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ class Compiler
4
+ describe StaticMerger do
5
+
6
+ def optimize(source)
7
+ StaticMerger.new.call(source)
8
+ end
9
+
10
+ let(:trailing){[
11
+ [:strconcat, [:static, "{"], [:static, "Hello world"], [:static, "}"]],
12
+ [:strconcat, [:static, "{Hello world}"]]
13
+ ]}
14
+
15
+ it 'optimize result of trailing blocks' do
16
+ optimize(trailing.first).should eq(trailing.last)
17
+ end
18
+
19
+ [:template, :modulo, :wlang, :fn].each do |kind|
20
+
21
+ it "recurses on :#{kind}" do
22
+ optimize([kind, trailing.first]).should eq([kind, trailing.last])
23
+ end
24
+
25
+ end
26
+
27
+ end # describe StaticMerger
28
+ end # class Compiler
29
+ end # module WLang
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ class Compiler
4
+ describe StrconcatFlattener do
5
+
6
+ def optimize(source)
7
+ StrconcatFlattener.new.call(source)
8
+ end
9
+
10
+ it 'cleans singleton' do
11
+ source = [:strconcat, [:static, "Hello World!"]]
12
+ expected = [:static, "Hello World!"]
13
+ optimize(source).should eq(expected)
14
+ end
15
+
16
+ it 'does nothing on single :strconcat' do
17
+ source = [:strconcat, [:static, "Hello "], [:static, "World"]]
18
+ expected = [:strconcat, [:static, "Hello "], [:static, "World"]]
19
+ optimize(source).should eq(expected)
20
+ end
21
+
22
+ it 'flattens :strconcat' do
23
+ source = [:strconcat, [:strconcat, [:static, "Hello "], [:static, "World"]], [:static, "!"]]
24
+ expected = [:strconcat, [:static, "Hello "], [:static, "World"], [:static, "!"]]
25
+ optimize(source).should eq(expected)
26
+ end
27
+
28
+ end # describe StrconcatFlattener
29
+ end # class Compiler
30
+ end # module WLang
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ class Compiler
4
+ describe ToRubyAbstraction do
5
+
6
+ def optimize(source)
7
+ ToRubyAbstraction.new.call(source)
8
+ end
9
+
10
+ let(:hello){[
11
+ [:static, "Hello world"],
12
+ [:static, "Hello world"]
13
+ ]}
14
+ let(:strconcat){[
15
+ [:strconcat, [:static, "Hello "], [:static, "world"]],
16
+ [:multi, [:static, "Hello "], [:static, "world"]]
17
+ ]}
18
+
19
+ it 'let [:static, ...] unchanged' do
20
+ optimize(hello.first).should eq(hello.last)
21
+ end
22
+
23
+ it 'transforms :strconcat to :multi' do
24
+ optimize(strconcat.first).should eq(strconcat.last)
25
+ end
26
+
27
+ it 'recurses on :strconcat' do
28
+ source = [:strconcat, strconcat.first]
29
+ expected = [:multi, strconcat.last]
30
+ optimize(source).should eq(expected)
31
+ end
32
+
33
+ it 'transforms :fn to :proc' do
34
+ source = [:fn, hello.first]
35
+ expected = [:proc, hello.last]
36
+ optimize(source).should eq(expected)
37
+ end
38
+
39
+ it 'recurses on :fn' do
40
+ source = [:fn, strconcat.first]
41
+ expected = [:proc, strconcat.last]
42
+ optimize(source).should eq(expected)
43
+ end
44
+
45
+ it "recurses on :template" do
46
+ source = [:template, strconcat.first]
47
+ expected = [:template, strconcat.last]
48
+ optimize(source).should eq(expected)
49
+ end
50
+
51
+ it 'transforms :wlang to :dispatch' do
52
+ source = [:wlang, '$', [:fn, strconcat.first]]
53
+ expected = [:dispatch, :_tag_36, [:proc, strconcat.last]]
54
+ optimize(source).should eq(expected)
55
+ end
56
+
57
+ end # describe ToRubyAbstraction
58
+ end # class Compiler
59
+ end # module WLang
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ class Compiler
4
+ describe ToRubyCode do
5
+
6
+ def generate(source)
7
+ ToRubyCode.new.call(source)
8
+ end
9
+
10
+ it 'compiles [:proc, ...]' do
11
+ source = [:proc, [:static, "Hello world"]]
12
+ expected = %q{Proc.new{|d1,b1| b1 << ("Hello world") }}
13
+ generate(source).should eq(expected)
14
+ end
15
+
16
+ it 'compiles [:dispatch, ...]' do
17
+ source = [:dispatch, :_tag_36, [:proc, [:static, "Hello world"]]]
18
+ expected = %q{d0._tag_36(b0, Proc.new{|d1,b1| b1 << ("Hello world") })}
19
+ generate(source).should eq(expected)
20
+ end
21
+
22
+ end # describe ToRubyCode
23
+ end # class Compiler
24
+ end # module WLang