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