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.
- data/CHANGELOG.md +3 -121
- data/Gemfile +23 -1
- data/Gemfile.lock +32 -28
- data/LICENCE.md +18 -21
- data/Manifest.txt +4 -5
- data/README.md +100 -174
- data/Rakefile +1 -13
- data/bin/wlang +3 -29
- data/lib/wlang.rb +21 -394
- data/lib/wlang/command.rb +94 -0
- data/lib/wlang/compiler.rb +78 -0
- data/lib/wlang/compiler/autospacing.rb +60 -0
- data/lib/wlang/compiler/dialect_enforcer.rb +91 -0
- data/lib/wlang/compiler/filter.rb +32 -0
- data/lib/wlang/compiler/grammar.citrus +67 -0
- data/lib/wlang/compiler/parser.rb +26 -0
- data/lib/wlang/compiler/proc_call_removal.rb +15 -0
- data/lib/wlang/compiler/static_merger.rb +28 -0
- data/lib/wlang/compiler/strconcat_flattener.rb +25 -0
- data/lib/wlang/compiler/to_ruby_abstraction.rb +22 -0
- data/lib/wlang/compiler/to_ruby_code.rb +55 -0
- data/lib/wlang/dialect.rb +40 -237
- data/lib/wlang/dialect/dispatching.rb +51 -0
- data/lib/wlang/dialect/evaluation.rb +30 -0
- data/lib/wlang/dialect/tags.rb +50 -0
- data/lib/wlang/dummy.rb +32 -0
- data/lib/wlang/html.rb +106 -0
- data/lib/wlang/loader.rb +6 -0
- data/lib/wlang/mustang.rb +90 -0
- data/lib/wlang/scope.rb +57 -0
- data/lib/wlang/scope/binding_scope.rb +18 -0
- data/lib/wlang/scope/object_scope.rb +25 -0
- data/lib/wlang/scope/proxy_scope.rb +18 -0
- data/lib/wlang/scope/root_scope.rb +24 -0
- data/lib/wlang/template.rb +16 -86
- data/lib/wlang/version.rb +9 -8
- data/spec/fixtures/dialect/foobar.rb +31 -0
- data/spec/fixtures/dialect/upcasing.rb +13 -0
- data/spec/fixtures/templates/hello.tpl +1 -0
- data/spec/integration/examples/1-basics.txt +65 -0
- data/spec/integration/examples/2-imperative.txt +51 -0
- data/spec/integration/examples/3-partials.txt +76 -0
- data/spec/integration/examples/4-recursion.txt +16 -0
- data/spec/integration/html/test_ampersand.rb +15 -0
- data/spec/integration/html/test_bang.rb +38 -0
- data/spec/integration/html/test_caret.rb +33 -0
- data/spec/integration/html/test_dollar.rb +16 -0
- data/spec/integration/html/test_greater.rb +23 -0
- data/spec/integration/html/test_modulo.rb +16 -0
- data/spec/integration/html/test_plus.rb +48 -0
- data/spec/integration/html/test_question.rb +33 -0
- data/spec/integration/html/test_sharp.rb +21 -0
- data/spec/integration/html/test_slash.rb +16 -0
- data/spec/integration/html/test_star.rb +37 -0
- data/spec/integration/test_dummy.rb +51 -0
- data/spec/integration/test_examples.rb +29 -0
- data/spec/integration/test_mustang.rb +120 -0
- data/spec/integration/test_readme.rb +56 -0
- data/spec/integration/test_upcasing.rb +22 -0
- data/spec/spec_helper.rb +62 -1
- data/spec/test_wlang.rb +101 -0
- data/spec/unit/compiler/autospacing/test_right_strip.rb +30 -0
- data/spec/unit/compiler/autospacing/test_unindent.rb +30 -0
- data/spec/unit/compiler/test_dialect_enforcer.rb +168 -0
- data/spec/unit/compiler/test_grammar.rb +207 -0
- data/spec/unit/compiler/test_parser.rb +69 -0
- data/spec/unit/compiler/test_proc_call_removal.rb +24 -0
- data/spec/unit/compiler/test_static_merger.rb +29 -0
- data/spec/unit/compiler/test_strconcat_flattener.rb +30 -0
- data/spec/unit/compiler/test_to_ruby_abstraction.rb +59 -0
- data/spec/unit/compiler/test_to_ruby_code.rb +24 -0
- data/spec/unit/dialect/test_compile.rb +52 -0
- data/spec/unit/dialect/test_dispatching.rb +19 -0
- data/spec/unit/dialect/test_evaluate.rb +41 -0
- data/spec/unit/dialect/test_render.rb +33 -0
- data/spec/unit/dialect/test_tags.rb +32 -0
- data/spec/unit/dialect/test_with_scope.rb +18 -0
- data/spec/unit/scope/test_binding_scope.rb +27 -0
- data/spec/unit/scope/test_coerce.rb +22 -0
- data/spec/unit/scope/test_object_scope.rb +38 -0
- data/spec/unit/scope/test_proxy_scope.rb +22 -0
- data/spec/unit/scope/test_root_scope.rb +22 -0
- data/spec/unit/test_assumptions.rb +29 -0
- data/spec/unit/test_scope.rb +57 -0
- data/tasks/debug_mail.rake +42 -45
- data/tasks/gem.rake +22 -17
- data/tasks/spec_test.rake +9 -17
- data/tasks/unit_test.rake +11 -12
- data/tasks/yard.rake +13 -13
- data/wlang.gemspec +36 -32
- data/wlang.noespec +27 -35
- metadata +268 -451
- data/doc/specification/about.rdoc +0 -61
- data/doc/specification/analytics.wtpl +0 -13
- data/doc/specification/dialect.wtpl +0 -14
- data/doc/specification/dialects.wtpl +0 -3
- data/doc/specification/examples.rb +0 -3
- data/doc/specification/glossary.wtpl +0 -14
- data/doc/specification/hosting.rdoc +0 -0
- data/doc/specification/overview.rdoc +0 -116
- data/doc/specification/rulesets.wtpl +0 -87
- data/doc/specification/specification.css +0 -53
- data/doc/specification/specification.html +0 -1690
- data/doc/specification/specification.js +0 -8
- data/doc/specification/specification.wtpl +0 -42
- data/doc/specification/specification.yml +0 -432
- data/doc/specification/symbols.wtpl +0 -16
- data/lib/wlang/dialect_dsl.rb +0 -141
- data/lib/wlang/dialect_loader.rb +0 -74
- data/lib/wlang/dialects/bluecloth_dialect.rb +0 -16
- data/lib/wlang/dialects/coderay_dialect.rb +0 -45
- data/lib/wlang/dialects/hosted_dialect.rb +0 -50
- data/lib/wlang/dialects/plain_text_dialect.rb +0 -69
- data/lib/wlang/dialects/rdoc_dialect.rb +0 -33
- data/lib/wlang/dialects/redcloth_dialect.rb +0 -16
- data/lib/wlang/dialects/ruby_dialect.rb +0 -118
- data/lib/wlang/dialects/sql_dialect.rb +0 -38
- data/lib/wlang/dialects/standard_dialects.rb +0 -181
- data/lib/wlang/dialects/xhtml_dialect.rb +0 -63
- data/lib/wlang/dialects/yaml_dialect.rb +0 -30
- data/lib/wlang/encoder.rb +0 -62
- data/lib/wlang/encoder_set.rb +0 -122
- data/lib/wlang/errors.rb +0 -80
- data/lib/wlang/ext/hash_methodize.rb +0 -13
- data/lib/wlang/ext/string.rb +0 -44
- data/lib/wlang/hash_scope.rb +0 -89
- data/lib/wlang/hosted_language.rb +0 -146
- data/lib/wlang/intelligent_buffer.rb +0 -94
- data/lib/wlang/parser.rb +0 -332
- data/lib/wlang/parser_state.rb +0 -94
- data/lib/wlang/rule.rb +0 -66
- data/lib/wlang/rule_set.rb +0 -106
- data/lib/wlang/rulesets/basic_ruleset.rb +0 -83
- data/lib/wlang/rulesets/buffering_ruleset.rb +0 -115
- data/lib/wlang/rulesets/context_ruleset.rb +0 -111
- data/lib/wlang/rulesets/encoding_ruleset.rb +0 -73
- data/lib/wlang/rulesets/imperative_ruleset.rb +0 -132
- data/lib/wlang/rulesets/ruleset_utils.rb +0 -317
- data/lib/wlang/wlang_command.rb +0 -51
- data/lib/wlang/wlang_command_options.rb +0 -163
- data/spec/basic_object.spec +0 -40
- data/spec/coderay_dialect.spec +0 -8
- data/spec/dialect/apply_post_transform.spec +0 -16
- data/spec/global_extensions.rb +0 -2
- data/spec/hash_scope.spec +0 -76
- data/spec/redcloth_dialect.spec +0 -24
- data/spec/test_all.rb +0 -8
- data/spec/wlang.spec +0 -53
- data/spec/wlang_spec.rb +0 -8
- data/spec/xhtml_dialect.spec +0 -22
- data/tasks/genspec.rake +0 -5
- data/test/blackbox/basic/execution_1.exp +0 -1
- data/test/blackbox/basic/execution_1.tpl +0 -1
- data/test/blackbox/basic/execution_2.exp +0 -1
- data/test/blackbox/basic/execution_2.tpl +0 -1
- data/test/blackbox/basic/execution_3.exp +0 -1
- data/test/blackbox/basic/execution_3.tpl +0 -1
- data/test/blackbox/basic/execution_4.exp +0 -1
- data/test/blackbox/basic/execution_4.tpl +0 -1
- data/test/blackbox/basic/inclusion_1.exp +0 -1
- data/test/blackbox/basic/inclusion_1.tpl +0 -1
- data/test/blackbox/basic/inclusion_2.exp +0 -1
- data/test/blackbox/basic/inclusion_2.tpl +0 -1
- data/test/blackbox/basic/injection_1.exp +0 -1
- data/test/blackbox/basic/injection_1.tpl +0 -1
- data/test/blackbox/basic/injection_2.exp +0 -1
- data/test/blackbox/basic/injection_2.tpl +0 -1
- data/test/blackbox/basic/modulation_1.exp +0 -1
- data/test/blackbox/basic/modulation_1.tpl +0 -1
- data/test/blackbox/basic/modulation_2.exp +0 -1
- data/test/blackbox/basic/modulation_2.tpl +0 -1
- data/test/blackbox/basic/recursive_app_1.exp +0 -1
- data/test/blackbox/basic/recursive_app_1.tpl +0 -1
- data/test/blackbox/basic/recursive_app_2.exp +0 -1
- data/test/blackbox/basic/recursive_app_2.tpl +0 -1
- data/test/blackbox/buffering/data_1.rb +0 -1
- data/test/blackbox/buffering/data_assignment_1.exp +0 -1
- data/test/blackbox/buffering/data_assignment_1.tpl +0 -1
- data/test/blackbox/buffering/data_assignment_2.exp +0 -1
- data/test/blackbox/buffering/data_assignment_2.tpl +0 -1
- data/test/blackbox/buffering/data_assignment_3.exp +0 -1
- data/test/blackbox/buffering/data_assignment_3.tpl +0 -1
- data/test/blackbox/buffering/data_assignment_4.exp +0 -1
- data/test/blackbox/buffering/data_assignment_4.tpl +0 -1
- data/test/blackbox/buffering/input_1.exp +0 -1
- data/test/blackbox/buffering/input_1.tpl +0 -1
- data/test/blackbox/buffering/input_2.exp +0 -1
- data/test/blackbox/buffering/input_2.tpl +0 -1
- data/test/blackbox/buffering/input_3.exp +0 -1
- data/test/blackbox/buffering/input_3.tpl +0 -1
- data/test/blackbox/buffering/input_inclusion.exp +0 -1
- data/test/blackbox/buffering/input_inclusion.tpl +0 -1
- data/test/blackbox/buffering/input_inclusion_1.exp +0 -0
- data/test/blackbox/buffering/input_inclusion_1.tpl +0 -1
- data/test/blackbox/buffering/input_inclusion_2.exp +0 -1
- data/test/blackbox/buffering/input_inclusion_2.tpl +0 -1
- data/test/blackbox/buffering/input_inclusion_3.exp +0 -1
- data/test/blackbox/buffering/input_inclusion_3.tpl +0 -1
- data/test/blackbox/buffering/input_inclusion_4.exp +0 -0
- data/test/blackbox/buffering/input_inclusion_4.tpl +0 -1
- data/test/blackbox/buffering/input_inclusion_5.exp +0 -1
- data/test/blackbox/buffering/input_inclusion_5.tpl +0 -1
- data/test/blackbox/buffering/input_inclusion_6.exp +0 -1
- data/test/blackbox/buffering/input_inclusion_6.tpl +0 -1
- data/test/blackbox/buffering/input_inclusion_7.exp +0 -0
- data/test/blackbox/buffering/input_inclusion_7.tpl +0 -1
- data/test/blackbox/buffering/text_1.txt +0 -1
- data/test/blackbox/buffering/wlang.txt +0 -1
- data/test/blackbox/context/assignment_1.exp +0 -1
- data/test/blackbox/context/assignment_1.tpl +0 -1
- data/test/blackbox/context/assignment_2.exp +0 -1
- data/test/blackbox/context/assignment_2.tpl +0 -1
- data/test/blackbox/context/assignment_3.exp +0 -2
- data/test/blackbox/context/assignment_3.tpl +0 -2
- data/test/blackbox/context/assignment_4.exp +0 -1
- data/test/blackbox/context/assignment_4.tpl +0 -1
- data/test/blackbox/context/block_assignment_1.exp +0 -1
- data/test/blackbox/context/block_assignment_1.tpl +0 -1
- data/test/blackbox/context/block_assignment_2.exp +0 -1
- data/test/blackbox/context/block_assignment_2.tpl +0 -1
- data/test/blackbox/context/modulo_assignment_1.exp +0 -1
- data/test/blackbox/context/modulo_assignment_1.tpl +0 -1
- data/test/blackbox/context/modulo_assignment_2.exp +0 -1
- data/test/blackbox/context/modulo_assignment_2.tpl +0 -1
- data/test/blackbox/data_1.rb +0 -1
- data/test/blackbox/postblock/hello.exp +0 -1
- data/test/blackbox/postblock/hello.pre +0 -1
- data/test/blackbox/postblock/hello.tpl +0 -1
- data/test/blackbox/postblock/hello_input_inclusion.exp +0 -1
- data/test/blackbox/postblock/hello_input_inclusion.tpl +0 -1
- data/test/blackbox/postblock/hello_to_authors.exp +0 -1
- data/test/blackbox/postblock/hello_to_authors.tpl +0 -1
- data/test/blackbox/poststring/hello.exp +0 -1
- data/test/blackbox/poststring/hello.tpl +0 -1
- data/test/blackbox/test_all.rb +0 -70
- data/test/standard_dialects/ruby/data.rb +0 -7
- data/test/standard_dialects/ruby/inclusion.exp +0 -6
- data/test/standard_dialects/ruby/inclusion.tpl +0 -6
- data/test/standard_dialects/test_all.rb +0 -29
- data/test/standard_dialects/yaml/assumptions_test.rb +0 -13
- data/test/standard_dialects/yaml/data.rb +0 -3
- data/test/standard_dialects/yaml/inclusion_1.exp +0 -7
- data/test/standard_dialects/yaml/inclusion_1.tpl +0 -2
- data/test/standard_dialects/yaml/inclusion_2.exp +0 -5
- data/test/standard_dialects/yaml/inclusion_2.tpl +0 -3
- data/test/unit/test_all.rb +0 -9
- data/test/unit/wlang/anagram_bugs_test.rb +0 -111
- data/test/unit/wlang/basic_ruleset_test.rb +0 -52
- data/test/unit/wlang/buffering_ruleset_test.rb +0 -102
- data/test/unit/wlang/buffering_template1.wtpl +0 -1
- data/test/unit/wlang/buffering_template2.wtpl +0 -1
- data/test/unit/wlang/buffering_template3.wtpl +0 -1
- data/test/unit/wlang/buffering_template4.wtpl +0 -1
- data/test/unit/wlang/buffering_template5.wtpl +0 -1
- data/test/unit/wlang/context_ruleset_test.rb +0 -32
- data/test/unit/wlang/data.rb +0 -3
- data/test/unit/wlang/encoder_set_test.rb +0 -42
- data/test/unit/wlang/imperative_ruleset_test.rb +0 -107
- data/test/unit/wlang/intelligent_buffer_test.rb +0 -194
- data/test/unit/wlang/othersymbols_test.rb +0 -16
- data/test/unit/wlang/parser_test.rb +0 -88
- data/test/unit/wlang/plain_text_dialect_test.rb +0 -21
- data/test/unit/wlang/ruby_dialect_test.rb +0 -100
- data/test/unit/wlang/ruby_expected.rb +0 -3
- data/test/unit/wlang/ruby_template.wrb +0 -3
- data/test/unit/wlang/ruleset_utils_test.rb +0 -245
- data/test/unit/wlang/specification_examples_test.rb +0 -54
- data/test/unit/wlang/test_utils.rb +0 -25
- data/test/unit/wlang/wlang_test.rb +0 -80
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'wlang/mustang'
|
|
3
|
+
module WLang
|
|
4
|
+
describe Mustang do
|
|
5
|
+
|
|
6
|
+
describe "The Highlighter example" do
|
|
7
|
+
|
|
8
|
+
class Highlighter < WLang::Dialect
|
|
9
|
+
|
|
10
|
+
def highlight(buf, fn)
|
|
11
|
+
var_name = render(fn)
|
|
12
|
+
var_value = evaluate(var_name)
|
|
13
|
+
buf << var_value.to_s.upcase
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
tag '$', :highlight
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'works as announced' do
|
|
20
|
+
expected = "Hello YOU & THE WORLD!"
|
|
21
|
+
got = Highlighter.render "Hello ${who}!", :who => "you & the world"
|
|
22
|
+
got.should eq(expected)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end # Highlighter example
|
|
26
|
+
|
|
27
|
+
describe "the HighLevel example" do
|
|
28
|
+
|
|
29
|
+
class HighLevel < WLang::Dialect
|
|
30
|
+
|
|
31
|
+
def join(buf, expr, main, between)
|
|
32
|
+
evaluate(expr).each_with_index do |val,i|
|
|
33
|
+
buf << render(between, val) unless i==0
|
|
34
|
+
buf << render(main, val).strip
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def print(buf, fn)
|
|
39
|
+
buf << evaluate(fn).to_s
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
tag '*', :join
|
|
43
|
+
tag '$', :print
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'works as announced' do
|
|
47
|
+
expected = "Hello you and wlang and world !"
|
|
48
|
+
template = 'Hello *{ ${collection} }{ ${self} }{ and } !'
|
|
49
|
+
context = {:collection => 'whos', :whos => [ "you", "wlang", "world" ] }
|
|
50
|
+
got = HighLevel.render template, context
|
|
51
|
+
got.should eq(expected)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module WLang
|
|
3
|
+
describe Upcasing do
|
|
4
|
+
|
|
5
|
+
def upcasing(tpl, scope = {})
|
|
6
|
+
Upcasing.render(tpl, scope)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it 'upcases the string under $' do
|
|
10
|
+
upcasing("Hello ${world}!").should eq("Hello WORLD!")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'evaluates the string under #' do
|
|
14
|
+
upcasing('Hello #{who}!', :who => "World").should eq("Hello World!")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'raises when not found' do
|
|
18
|
+
lambda{ upcasing('Hello #{who}!') }.should raise_error(NameError)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end # describe Dummy
|
|
22
|
+
end # module WLang
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,2 +1,63 @@
|
|
|
1
|
-
|
|
1
|
+
require 'epath'
|
|
2
|
+
$root_folder ||= Path.backfind('.[Rakefile]')
|
|
3
|
+
|
|
4
|
+
# Require wlang
|
|
5
|
+
$LOAD_PATH.unshift(($root_folder/:lib).to_s)
|
|
2
6
|
require 'wlang'
|
|
7
|
+
|
|
8
|
+
# RSpec helpers
|
|
9
|
+
require 'rspec'
|
|
10
|
+
module Helpers
|
|
11
|
+
include WLang
|
|
12
|
+
extend(self)
|
|
13
|
+
|
|
14
|
+
def root_folder
|
|
15
|
+
$root_folder
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def spec_folder
|
|
19
|
+
root_folder/:spec
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def fixtures_folder
|
|
23
|
+
spec_folder/:fixtures
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def tpl_path(what)
|
|
27
|
+
what = "#{what}.tpl" if what.is_a?(Symbol)
|
|
28
|
+
fixtures_folder/:templates/what
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def tpl(what)
|
|
32
|
+
tpl_path(what).read
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Load fixture dialects
|
|
36
|
+
spec_folder.glob("fixtures/dialect/*.rb").each do |f|
|
|
37
|
+
require f.expand_path
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Install helper methods for templates
|
|
41
|
+
fixtures_folder.glob("templates/*.tpl").each do |f|
|
|
42
|
+
name = f.basename.without_extension
|
|
43
|
+
define_method(:"#{name}_path") do
|
|
44
|
+
fixtures_folder/:templates/f.basename
|
|
45
|
+
end
|
|
46
|
+
define_method(:"#{name}_tpl") do
|
|
47
|
+
send(:"#{name}_path").read
|
|
48
|
+
end
|
|
49
|
+
define_method(:"#{name}_io") do |&b|
|
|
50
|
+
send(:"#{name}_path").open("r") do |io|
|
|
51
|
+
b.call(io)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
include Helpers
|
|
58
|
+
|
|
59
|
+
# Configure rspec
|
|
60
|
+
RSpec.configure do |c|
|
|
61
|
+
c.include Helpers
|
|
62
|
+
c.filter_run_excluding :hash_ordering => true if RUBY_VERSION < "1.9"
|
|
63
|
+
end
|
data/spec/test_wlang.rb
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
require File.expand_path('../spec_helper', __FILE__)
|
|
2
|
+
describe WLang do
|
|
3
|
+
|
|
4
|
+
it "has a version number" do
|
|
5
|
+
WLang.const_defined?(:VERSION).should be_true
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
let(:d){
|
|
9
|
+
WLang::dialect do
|
|
10
|
+
tag('$') do |buf, fn|
|
|
11
|
+
if x = evaluate(fn)
|
|
12
|
+
buf << x.to_s
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
it 'allows building on-the-fly dialects' do
|
|
19
|
+
d.render(hello_tpl, :who => "world").should eq("Hello world!")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
### overriding
|
|
23
|
+
|
|
24
|
+
it 'allows overriding super-dialect tags' do
|
|
25
|
+
e = WLang::dialect(d) do
|
|
26
|
+
tag('$') do |buf, fn1|
|
|
27
|
+
buf << render(fn1).capitalize
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
e.render(hello_tpl).should eq("Hello Who!")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'allows overriding super-dialect evaluation rules' do
|
|
34
|
+
e = WLang::dialect(d) do
|
|
35
|
+
def evaluate(expr); super rescue ""; end
|
|
36
|
+
end
|
|
37
|
+
e.render(hello_tpl).should eq("Hello !")
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'does not override the super-dialect evaluation rules' do
|
|
41
|
+
e = WLang::dialect(d) do
|
|
42
|
+
def evaluate(expr); super rescue ""; end
|
|
43
|
+
end
|
|
44
|
+
lambda{ d.render(hello_tpl) }.should raise_error(NameError)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
### default scoping
|
|
48
|
+
|
|
49
|
+
it 'allows a hash for scoping by default' do
|
|
50
|
+
d.render(hello_tpl, :who => "World").should eq("Hello World!")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it 'allows binding for scoping by default' do
|
|
54
|
+
who = "World"
|
|
55
|
+
d.render(hello_tpl, binding).should eq("Hello World!")
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
### high-order and multi-dialects
|
|
59
|
+
|
|
60
|
+
it 'allows high-order constructions' do
|
|
61
|
+
scope = {:who => :world, :world => "World"}
|
|
62
|
+
d.render('Hello ${${who}}!', scope).should eq("Hello World!")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'allows switching the current dialect' do
|
|
66
|
+
e = WLang::dialect do
|
|
67
|
+
tag '!', [Upcasing] do |buf,fn|
|
|
68
|
+
buf << evaluate(fn).to_s;
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
scope = {:WHO => "World"}
|
|
72
|
+
e.render('Hello !{${who}}!', scope).should eq("Hello World!")
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
### autospacing
|
|
76
|
+
|
|
77
|
+
it 'handles magic spacing on a static block' do
|
|
78
|
+
e = WLang::dialect do
|
|
79
|
+
default_options :autospacing => true
|
|
80
|
+
tag '$' do |buf,fn| buf << render(fn) end
|
|
81
|
+
end
|
|
82
|
+
source = "${\n hello world\n}"
|
|
83
|
+
expected = "hello world"
|
|
84
|
+
pending{
|
|
85
|
+
e.render(source).should eq(expected)
|
|
86
|
+
}
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it 'handles magic spacing on a wlang block' do
|
|
90
|
+
e = WLang::dialect do
|
|
91
|
+
default_options :autospacing => true
|
|
92
|
+
tag '$' do |buf,fn| buf << render(fn) end
|
|
93
|
+
end
|
|
94
|
+
source = "${\n ${name}\n ${score}\n}"
|
|
95
|
+
expected = "name\nscore"
|
|
96
|
+
pending{
|
|
97
|
+
e.render(source).should eq(expected)
|
|
98
|
+
}
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module WLang
|
|
3
|
+
class Compiler
|
|
4
|
+
describe Autospacing::RightStrip do
|
|
5
|
+
|
|
6
|
+
def optimize(source)
|
|
7
|
+
Autospacing::RightStrip.new.call(source)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'does not touch single line statics' do
|
|
11
|
+
source = [:static, "Hello World"]
|
|
12
|
+
expected = [:static, "Hello World"]
|
|
13
|
+
optimize(source).should eq(expected)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'strips at right on :static' do
|
|
17
|
+
source = [:static, "Hello World \n "]
|
|
18
|
+
expected = [:static, "Hello World"]
|
|
19
|
+
optimize(source).should eq(expected)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'strips the right-most :static on :strconcat' do
|
|
23
|
+
source = [:strconcat, [:static, "Hello \n"], [:static, " World\n"]]
|
|
24
|
+
expected = [:strconcat, [:static, "Hello \n"], [:static, " World"]]
|
|
25
|
+
optimize(source).should eq(expected)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end # describe Autospacing::RightStrip
|
|
29
|
+
end # class Compiler
|
|
30
|
+
end # module WLang
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module WLang
|
|
3
|
+
class Compiler
|
|
4
|
+
describe Autospacing::Unindent do
|
|
5
|
+
|
|
6
|
+
def optimize(source)
|
|
7
|
+
Autospacing::Unindent.new.call(source)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'unindents :static' do
|
|
11
|
+
source = [:static, " Hello World"]
|
|
12
|
+
expected = [:static, "Hello World"]
|
|
13
|
+
optimize(source).should eq(expected)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'unindents :static when multiple lines' do
|
|
17
|
+
source = [:static, " Hello\n World"]
|
|
18
|
+
expected = [:static, "Hello\nWorld"]
|
|
19
|
+
optimize(source).should eq(expected)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'recurses on :strconcat' do
|
|
23
|
+
source = [:strconcat, [:static, " Hello"], [:static, " World"]]
|
|
24
|
+
expected = [:strconcat, [:static, "Hello"], [:static, "World"]]
|
|
25
|
+
optimize(source).should eq(expected)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end # describe Autospacing::Unindent
|
|
29
|
+
end # class Compiler
|
|
30
|
+
end # module WLang
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module WLang
|
|
3
|
+
class Compiler
|
|
4
|
+
class DialectEnforcer
|
|
5
|
+
public :find_dispatching_method
|
|
6
|
+
end
|
|
7
|
+
describe DialectEnforcer do
|
|
8
|
+
|
|
9
|
+
let(:dialect){
|
|
10
|
+
WLang::dialect{
|
|
11
|
+
tag('$') do |buf,fn| buf << "$" end
|
|
12
|
+
tag('!$') do |buf,fn| buf << "!$" end
|
|
13
|
+
tag('*') do |buf,fn1,fn2| end
|
|
14
|
+
tag('%', [WLang::Dummy]) do |buf, fn| end
|
|
15
|
+
}.factor
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe 'find_dispatching_method' do
|
|
19
|
+
let(:e){ DialectEnforcer.new(:dialect => dialect) }
|
|
20
|
+
it 'works on exact matching' do
|
|
21
|
+
e.find_dispatching_method("$").should eq(['', :_tag_36])
|
|
22
|
+
end
|
|
23
|
+
it 'takes the most specific' do
|
|
24
|
+
e.find_dispatching_method("$").should eq(['', :_tag_36])
|
|
25
|
+
e.find_dispatching_method("!$").should eq(['', :_tag_33_36])
|
|
26
|
+
end
|
|
27
|
+
it 'recognizes extras' do
|
|
28
|
+
e.find_dispatching_method("@$").should eq(['@', :_tag_36])
|
|
29
|
+
e.find_dispatching_method("@!$").should eq(['@', :_tag_33_36])
|
|
30
|
+
end
|
|
31
|
+
it 'recognizes missings' do
|
|
32
|
+
e.find_dispatching_method("#").should eq(['#', nil])
|
|
33
|
+
e.find_dispatching_method("@#").should eq(['@#', nil])
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def optimize(source)
|
|
38
|
+
DialectEnforcer.new(:dialect => dialect).call(source)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
let(:unknown){[
|
|
42
|
+
[:wlang, '!', [:fn, [:static, "hello"]]],
|
|
43
|
+
[:strconcat, [:static, "!"], [:static, "{"], [:static, "hello"], [:static, "}"]]
|
|
44
|
+
]}
|
|
45
|
+
let(:hello_fn){[
|
|
46
|
+
[:fn, unknown.first],
|
|
47
|
+
[:fn, unknown.last]
|
|
48
|
+
]}
|
|
49
|
+
let(:hello_dollar){[
|
|
50
|
+
[:wlang, '$', hello_fn.first],
|
|
51
|
+
[:wlang, '$', hello_fn.last]
|
|
52
|
+
]}
|
|
53
|
+
|
|
54
|
+
### recursion rules
|
|
55
|
+
|
|
56
|
+
it 'recurses on template' do
|
|
57
|
+
source = [:template, hello_dollar.first]
|
|
58
|
+
expected = [:template, hello_dollar.last]
|
|
59
|
+
optimize(source).should eq(expected)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'leaves [:static, ...] unchanged' do
|
|
63
|
+
source = [:static, "Hello world"]
|
|
64
|
+
optimize(source).should eq(source)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it 'leaves [:strconcat, ...] unchanged if no tag' do
|
|
68
|
+
source = [:strconcat, [:static, "Hello "], [:static, "world"]]
|
|
69
|
+
optimize(source).should eq(source)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it 'recurses on [:strconcat, ...] to optimize further' do
|
|
73
|
+
source = [:strconcat, unknown.first]
|
|
74
|
+
expected = [:strconcat, unknown.last]
|
|
75
|
+
optimize(source).should eq(expected)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
### exact symbols
|
|
79
|
+
|
|
80
|
+
it 'optimizes on exact symbols' do
|
|
81
|
+
optimize(hello_dollar.first).should eq(hello_dollar.last)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it 'detects extra symbols' do
|
|
85
|
+
source = [:wlang, '@$', hello_fn.first]
|
|
86
|
+
expected = [:strconcat, [:static, "@"], hello_dollar.last]
|
|
87
|
+
optimize(source).should eq(expected)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
### unknown tags
|
|
91
|
+
|
|
92
|
+
it 'recognizes unknown tags' do
|
|
93
|
+
optimize(unknown.first).should eq(unknown.last)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it 'recognizes unknown tags even if enclosed' do
|
|
97
|
+
source = [:wlang, '$', [:fn, unknown.first]]
|
|
98
|
+
expected = [:wlang, '$', [:fn, unknown.last]]
|
|
99
|
+
optimize(source).should eq(expected)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
### high-order wlang
|
|
103
|
+
|
|
104
|
+
it 'applies dynamic dispatching on high-order wlang' do
|
|
105
|
+
source = [:wlang, '$', [:fn, hello_dollar.first]]
|
|
106
|
+
expected = [:wlang, '$', [:fn, hello_dollar.last]]
|
|
107
|
+
optimize(source).should eq(expected)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
### arity 2
|
|
111
|
+
|
|
112
|
+
it 'supports tags of arity 2' do
|
|
113
|
+
source = [:wlang, '*', hello_fn.first, hello_fn.first]
|
|
114
|
+
expected = [:wlang, '*', hello_fn.last, hello_fn.last]
|
|
115
|
+
optimize(source).should eq(expected)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
### missing blocks
|
|
119
|
+
|
|
120
|
+
it 'detects missing blocks on arity 1' do
|
|
121
|
+
source = [:wlang, '$']
|
|
122
|
+
expected = [:wlang, '$', [:arg, nil]]
|
|
123
|
+
optimize(source).should eq(expected)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it 'detects missing blocks on arity 2' do
|
|
127
|
+
source = [:wlang, '*', hello_fn.first]
|
|
128
|
+
expected = [:wlang, '*', hello_fn.last, [:arg, nil]]
|
|
129
|
+
optimize(source).should eq(expected)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
### trailing blocks
|
|
133
|
+
|
|
134
|
+
it 'detects trailing blocks' do
|
|
135
|
+
source = [:wlang, '$', hello_fn.first, hello_fn.first]
|
|
136
|
+
expected = \
|
|
137
|
+
[:strconcat,
|
|
138
|
+
[:wlang, '$', hello_fn.last],
|
|
139
|
+
[:static, '{'],
|
|
140
|
+
hello_fn.last.last,
|
|
141
|
+
[:static, '}']
|
|
142
|
+
]
|
|
143
|
+
optimize(source).should eq(expected)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it 'detects trailing blocks on arity 2' do
|
|
147
|
+
source = [:wlang, '*', hello_fn.first, hello_fn.first, hello_fn.first]
|
|
148
|
+
expected = \
|
|
149
|
+
[:strconcat,
|
|
150
|
+
[:wlang, '*', hello_fn.last, hello_fn.last],
|
|
151
|
+
[:static, '{'],
|
|
152
|
+
hello_fn.last.last,
|
|
153
|
+
[:static, '}']
|
|
154
|
+
]
|
|
155
|
+
optimize(source).should eq(expected)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
### dialect switching
|
|
159
|
+
|
|
160
|
+
it 'introduce dialect switching mechanism' do
|
|
161
|
+
source = [:wlang, '%', hello_fn.first]
|
|
162
|
+
expected = [:wlang, '%', [:modulo, WLang::Dummy, hello_fn.last]]
|
|
163
|
+
optimize(source).should eq(expected)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
end # describe DialectEnforcer
|
|
167
|
+
end # class Compiler
|
|
168
|
+
end # module WLang
|