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