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,52 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ describe Dialect, ".compile" do
4
+
5
+ def compile(s, options = nil)
6
+ options.nil? ? Upcasing.compile(s) : Upcasing.compile(s, options)
7
+ end
8
+
9
+ it 'returns a Template' do
10
+ compile(hello_tpl).should be_a(Template)
11
+ end
12
+
13
+ it 'supports a path-like as input' do
14
+ compile(hello_path).should be_a(Template)
15
+ end
16
+
17
+ it 'supports an IO object as input' do
18
+ hello_io do |f|
19
+ compile(f).should be_a(Template)
20
+ end
21
+ end
22
+
23
+ it 'supports a no-op' do
24
+ t = compile(hello_tpl)
25
+ compile(t).should eq(t)
26
+ end
27
+
28
+ it 'supports a proc' do
29
+ proc = compile(hello_tpl).inner_proc
30
+ compile(proc).should be_a(Template)
31
+ end
32
+
33
+ specify 'returned template is callable' do
34
+ compile(hello_tpl).call.should eq("Hello WHO!")
35
+ end
36
+
37
+ specify 'returned template is renderable' do
38
+ compile(hello_tpl).render.should eq("Hello WHO!")
39
+ end
40
+
41
+ it 'returns a thread-safe template object' do
42
+ t = WLang.dialect{ tag('$'){|buf,fn|
43
+ raise if defined?(@somevar)
44
+ @somevar = "World"
45
+ } }.compile('${who}')
46
+ 2.times do
47
+ lambda{ t.call }.should_not raise_error
48
+ end
49
+ end
50
+
51
+ end # describe Dialect
52
+ end # module WLang
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ describe Dialect::Dispatching do
4
+ include Dialect::Dispatching::ClassMethods
5
+
6
+ describe 'tag_dispatching_name' do
7
+ it "works with a single char" do
8
+ tag_dispatching_name("$").should eq(:_tag_36)
9
+ end
10
+ it "works with a multiple chars" do
11
+ tag_dispatching_name("!$").should eq(:_tag_33_36)
12
+ end
13
+ it "works with an array" do
14
+ tag_dispatching_name(['!', '$']).should eq(:_tag_33_36)
15
+ end
16
+ end
17
+
18
+ end # describe Dialect
19
+ end # module WLang
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ class Dialect
4
+ describe Evaluation, "evaluate" do
5
+ include Evaluation
6
+
7
+ let(:struct){ Struct.new(:who) }
8
+
9
+ it 'works with a hash' do
10
+ with_scope({:who => "World"}) do
11
+ evaluate("who").should eq("World")
12
+ evaluate(:who).should eq("World")
13
+ end
14
+ end
15
+
16
+ it 'works with a struct' do
17
+ with_scope(struct.new("World")) do
18
+ evaluate("who").should eq("World")
19
+ evaluate(:who).should eq("World")
20
+ end
21
+ end
22
+
23
+ it 'uses the hash in priority' do
24
+ with_scope({:keys => [1,2,3]}) do
25
+ evaluate("keys").should eq([1,2,3])
26
+ end
27
+ end
28
+
29
+ it 'falls back to send' do
30
+ with_scope({:who => "World"}) do
31
+ evaluate("keys").should eq([:who])
32
+ end
33
+ end
34
+
35
+ it 'raises a NameError when not found' do
36
+ lambda{ evaluate("who") }.should raise_error(NameError)
37
+ end
38
+
39
+ end # describe Evaluation, "evaluate"
40
+ end # class Dialect
41
+ end # module WLang
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ describe Dialect, "render" do
4
+
5
+ U = Upcasing
6
+ let(:expected){ "Hello WHO!" }
7
+
8
+ it 'works as expected' do
9
+ U.render(hello_tpl).should eq(expected)
10
+ end
11
+
12
+ it 'do not eat extra blocks' do
13
+ U.render("Hello ${who}{world}").should eq("Hello WHO{world}")
14
+ end
15
+
16
+ it "accepts an optional scope" do
17
+ U.render(hello_tpl, {}).should eq(expected)
18
+ end
19
+
20
+ it 'accepts a :to_path object' do
21
+ U.render(hello_path).should eq(expected)
22
+ end
23
+
24
+ it 'accepts an IO instance' do
25
+ hello_io{|io| U.render(io)}.should eq(expected)
26
+ end
27
+
28
+ it 'supports specifying the buffer' do
29
+ U.render(hello_tpl, {}, []).should eq(["Hello ", "WHO", "!"])
30
+ end
31
+
32
+ end # describe Dialect
33
+ end # module WLang
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ describe Dialect::Tags do
4
+
5
+ describe 'tag' do
6
+ include Dialect::Tags::ClassMethods
7
+
8
+ def define_tag_method(*args)
9
+ args
10
+ end
11
+
12
+ it "works with a symbol" do
13
+ tag("$", :dollar).should eq(["$", nil, :dollar])
14
+ end
15
+
16
+ it "works with a single proc" do
17
+ proc = lambda{|buf,fn| }
18
+ tag("$", &proc).should eq(["$", nil, proc])
19
+ end
20
+
21
+ it "allows specifying dialects with a symbol" do
22
+ tag("$", [Foo], :dollar).should eq(["$", [Foo], :dollar])
23
+ end
24
+
25
+ it "allows specifying dialects with a proc" do
26
+ proc = lambda{|buf,fn| }
27
+ tag("$", [Foo], &proc).should eq(["$", [Foo], proc])
28
+ end
29
+ end
30
+
31
+ end # describe Dialect
32
+ end # module WLang
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ class Dialect
4
+ describe Evaluation, "with_scope" do
5
+ include Evaluation
6
+
7
+ let(:struct){ Struct.new(:who) }
8
+
9
+ it 'returns the block value' do
10
+ got = with_scope({:who => "World"}) do
11
+ 12
12
+ end
13
+ got.should eq(12)
14
+ end
15
+
16
+ end # describe Evaluation, "with_scope"
17
+ end # class Dialect
18
+ end # module WLang
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ class Scope
4
+ describe BindingScope do
5
+
6
+ it 'implements fetch through eval' do
7
+ who = "World"
8
+ scope = Scope.coerce(binding)
9
+ scope.fetch(:who).should eq("World")
10
+ end
11
+
12
+ it 'delegates fetch to its parent when not found' do
13
+ scope = Scope.coerce(binding, Scope.coerce(:who => "World"))
14
+ scope.fetch(:who).should eq("World")
15
+ end
16
+
17
+ it 'fetches `self` correctly' do
18
+ o = Object.new
19
+ x = o.instance_eval do
20
+ Scope.coerce(binding).fetch(:self)
21
+ end
22
+ x.should eq(o)
23
+ end
24
+
25
+ end # describe BindingScope
26
+ end # class Scope
27
+ end # module WLang
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ describe Scope, ".coerce" do
4
+
5
+ it 'recognizes Binding' do
6
+ Scope.coerce(binding).should be_a(Scope::BindingScope)
7
+ end
8
+
9
+ it 'recognizes Scopes' do
10
+ Scope.coerce(Scope.root).should be_a(Scope::ProxyScope)
11
+ end
12
+
13
+ it 'falls back to ObjectScope on Hash' do
14
+ Scope.coerce({}).should be_a(Scope::ObjectScope)
15
+ end
16
+
17
+ it 'falls back to ObjectScope' do
18
+ Scope.coerce(12).should be_a(Scope::ObjectScope)
19
+ end
20
+
21
+ end # describe Scope
22
+ end # module WLang
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ class Scope
4
+ describe ObjectScope do
5
+
6
+ it 'implements fetch through [] if a Hash' do
7
+ scope = Scope.coerce(:who => "World")
8
+ scope.fetch(:who).should eq("World")
9
+ end
10
+
11
+ it 'supports any obj that responds to :has_key?' do
12
+ subj = Object.new.tap{|x|
13
+ def x.has_key?(k); true; end
14
+ def x.[](k); "World"; end
15
+ }
16
+ scope = Scope.coerce(subj)
17
+ scope.fetch(:who).should eq("World")
18
+ end
19
+
20
+ it 'falls back to send' do
21
+ subj = Struct.new(:who).new("World")
22
+ scope = Scope.coerce(subj)
23
+ scope.fetch(:who).should eq("World")
24
+ end
25
+
26
+ it 'delegates fetch to its parent when not found' do
27
+ scope = Scope.coerce(12, Scope.coerce({:who => "World"}))
28
+ scope.fetch(:who).should eq("World")
29
+ end
30
+
31
+ it 'fetches `self` correctly' do
32
+ scope = Scope.coerce(12)
33
+ scope.fetch(:self).should eq(12)
34
+ end
35
+
36
+ end # describe ObjectScope
37
+ end # class Scope
38
+ end # module WLang
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ class Scope
4
+ describe ProxyScope do
5
+
6
+ it 'delegates fetch to its subject' do
7
+ proxy = Scope.coerce(Scope.coerce(:who => "World"))
8
+ proxy.fetch(:who).should eq("World")
9
+ end
10
+
11
+ it 'delegates fetch to its parent when not found' do
12
+ proxy = Scope.coerce(Scope.root, Scope.coerce(:who => "World"))
13
+ proxy.fetch(:who).should eq("World")
14
+ end
15
+
16
+ it 'fetches `self` correctly' do
17
+ Scope.coerce(Scope.coerce(12)).fetch(:self).should eq(12)
18
+ end
19
+
20
+ end # describe ProxyScope
21
+ end # class Scope
22
+ end # module WLang
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ class Scope
4
+ describe RootScope do
5
+
6
+ let(:scope){ RootScope.new }
7
+
8
+ it 'throws on fetch' do
9
+ lambda{ scope.fetch(:who) }.should throw_symbol(:fail)
10
+ end
11
+
12
+ it 'throws on fetch even on `self`' do
13
+ lambda{ scope.fetch(:self) }.should throw_symbol(:fail)
14
+ end
15
+
16
+ it 'raises on pop' do
17
+ lambda{ scope.pop }.should raise_error
18
+ end
19
+
20
+ end # describe ProxyScope
21
+ end # class Scope
22
+ end # module WLang
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+ describe "ruby assumptions" do
3
+
4
+ def arity0(); end
5
+ def arity1(fn); end
6
+ def arity2(fn1,fn2); end
7
+
8
+ it 'String#to_path does not exist' do
9
+ ''.should_not respond_to(:to_path)
10
+ end
11
+
12
+ it 'Pathname#to_path does exist' do
13
+ require 'pathname'
14
+ Pathname.new('.').should respond_to(:to_path) if RUBY_VERSION >= "1.9"
15
+ end
16
+
17
+ it 'method arity' do
18
+ self.class.instance_method(:arity0).arity.should eq(0)
19
+ self.class.instance_method(:arity1).arity.should eq(1)
20
+ self.class.instance_method(:arity2).arity.should eq(2)
21
+ end
22
+
23
+ it "lambda arity" do
24
+ lambda{|| }.arity.should eq(0)
25
+ lambda{|fn|}.arity.should eq(1)
26
+ lambda{|fn1,fn2|}.arity.should eq(2)
27
+ end
28
+
29
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+ module WLang
3
+ describe Scope do
4
+
5
+ let(:scope){ Scope.coerce({:who => "World"}) }
6
+
7
+ it 'acts like a stack' do
8
+ s = scope
9
+ s.evaluate(:who).should eq("World")
10
+ lambda{ s.pop.evaluate(:who) }.should throw_symbol(:fail)
11
+ s = scope.push(:who => "World2")
12
+ s.evaluate(:who).should eq("World2")
13
+ s = s.pop
14
+ s.evaluate(:who).should eq("World")
15
+ end
16
+
17
+ it 'has a `with` helper' do
18
+ scope.with(:who => "World2") do |s|
19
+ s.evaluate(:who).should eq("World2")
20
+ end
21
+ scope.evaluate(:who).should eq("World")
22
+ end
23
+
24
+ it 'allows pushing scopes' do
25
+ scope.with Scope.coerce(:other => "World2") do |s|
26
+ s.evaluate(:other).should eq("World2")
27
+ s.evaluate(:who).should eq("World")
28
+ end
29
+ end
30
+
31
+ it 'evaluates `self` accurately' do
32
+ scope.evaluate(:self).should eq(:who => "World")
33
+ end
34
+
35
+ it 'evaluates dot expressions correctly' do
36
+ scope.evaluate("who.upcase").should eq("WORLD")
37
+ end
38
+
39
+ it 'strips strings before evaluation' do
40
+ scope.evaluate(" who ").should eq("World")
41
+ scope.evaluate(" who.upcase ").should eq("WORLD")
42
+ end
43
+
44
+ it 'fails when not found' do
45
+ lambda{ scope.evaluate(:nosuchone) }.should throw_symbol(:fail)
46
+ end
47
+
48
+ it 'supports a default value instead of fail' do
49
+ scope.evaluate(:nosuchone, 12).should eq(12)
50
+ end
51
+
52
+ it 'supports nil as default value' do
53
+ scope.evaluate(:nosuchone, nil).should be_nil
54
+ end
55
+
56
+ end # describe Scope
57
+ end # module WLang
@@ -1,8 +1,8 @@
1
1
  # Installs a rake task for debuging the announcement mail.
2
2
  #
3
3
  # This file installs the 'rake debug_mail' that flushes an announcement mail
4
- # for your library on the standard output. It is automatically generated
5
- # by Noe from your .noespec file, and should therefore be configured there,
4
+ # for your library on the standard output. It is automatically generated
5
+ # by Noe from your .noespec file, and should therefore be configured there,
6
6
  # under the variables/rake_tasks/debug_mail entry, as illustrated below:
7
7
  #
8
8
  # variables:
@@ -12,9 +12,9 @@
12
12
  # nb_changelog_sections: 1
13
13
  # ...
14
14
  #
15
- # If you have specific needs requiring manual intervention on this file,
15
+ # If you have specific needs requiring manual intervention on this file,
16
16
  # don't forget to set safe-override to false in your noe specification:
17
- #
17
+ #
18
18
  # template-info:
19
19
  # manifest:
20
20
  # tasks/debug_mail.rake:
@@ -22,8 +22,8 @@
22
22
  #
23
23
  # The mail template used can be found in debug_mail.txt. That file may be
24
24
  # changed to tune the mail you want to send. If you do so, don't forget to
25
- # add a manifest entry in your .noespec file to avoid overriding you
26
- # changes. The mail template uses wlang, with parentheses for block
25
+ # add a manifest entry in your .noespec file to avoid overriding you
26
+ # changes. The mail template uses wlang, with parentheses for block
27
27
  # delimiters.
28
28
  #
29
29
  # template-info:
@@ -31,48 +31,45 @@
31
31
  # tasks/debug_mail.txt:
32
32
  # safe-override: false
33
33
  #
34
- begin
35
- require 'wlang'
34
+ desc "Debug the release announcement mail"
35
+ task :debug_mail do
36
+ begin
37
+ require 'wlang'
38
+ rescue LoadError
39
+ abort "wlang is not available. Try 'gem install wlang'"
40
+ end
36
41
  require 'yaml'
37
-
38
- desc "Debug the release announcement mail"
39
- task :debug_mail do
40
- # Check that a .noespec file exists
41
- noespec_file = File.expand_path('../../wlang.noespec', __FILE__)
42
- unless File.exists?(noespec_file)
43
- raise "Unable to find .noespec project file, sorry."
44
- end
45
-
46
- # Load it as well as variables and options
47
- noespec = YAML::load(File.read(noespec_file))
48
- vars = noespec['variables'] || {}
49
-
50
- # Changes are taken from CHANGELOG
51
- logs = Dir[File.expand_path("../../CHANGELOG.*", __FILE__)]
52
- unless logs.size == 1
53
- abort "Unable to find a changelog file"
54
- end
55
42
 
56
- # Load interesting changesets
57
- changes, end_found = [], 0
58
- File.readlines(logs.first).select{|line|
59
- if line =~ /^#/
60
- break if end_found >= 2
61
- end_found += 1
62
- end
63
- changes << line
64
- }
65
- vars['changes'] = changes.join
66
-
67
- # WLang template
68
- template = File.expand_path('../debug_mail.txt', __FILE__)
69
-
70
- # Let's go!
71
- $stdout << WLang::file_instantiate(template, vars, "wlang/active-text")
43
+ # Check that a .noespec file exists
44
+ noespec_file = File.expand_path('../../wlang.noespec', __FILE__)
45
+ unless File.exists?(noespec_file)
46
+ raise "Unable to find .noespec project file, sorry."
72
47
  end
73
48
 
74
- rescue LoadError
75
- task :debug_mail do
76
- abort "wlang is not available. Try 'gem install wlang'"
49
+ # Load it as well as variables and options
50
+ noespec = YAML::load(File.read(noespec_file))
51
+ vars = noespec['variables'] || {}
52
+
53
+ # Changes are taken from CHANGELOG
54
+ logs = Dir[File.expand_path("../../CHANGELOG.*", __FILE__)]
55
+ unless logs.size == 1
56
+ abort "Unable to find a changelog file"
77
57
  end
58
+
59
+ # Load interesting changesets
60
+ changes, end_found = [], 0
61
+ File.readlines(logs.first).select{|line|
62
+ if line =~ /^# /
63
+ break if end_found >= 1
64
+ end_found += 1
65
+ end
66
+ changes << line
67
+ }
68
+ vars['changes'] = changes.join
69
+
70
+ # WLang template
71
+ template = File.expand_path('../debug_mail.txt', __FILE__)
72
+
73
+ # Let's go!
74
+ $stdout << WLang::file_instantiate(template, vars, "wlang/active-text")
78
75
  end