rabl-rails 0.3.4 → 0.4.0
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/.travis.yml +2 -2
- data/CHANGELOG.md +10 -0
- data/Gemfile +5 -9
- data/README.md +5 -3
- data/Rakefile +2 -2
- data/lib/rabl-rails.rb +21 -74
- data/lib/rabl-rails/compiler.rb +28 -38
- data/lib/rabl-rails/configuration.rb +48 -0
- data/lib/rabl-rails/handler.rb +3 -1
- data/lib/rabl-rails/helpers.rb +7 -0
- data/lib/rabl-rails/library.rb +43 -16
- data/lib/rabl-rails/nodes.rb +6 -0
- data/lib/rabl-rails/nodes/attribute.rb +17 -0
- data/lib/rabl-rails/nodes/child.rb +12 -0
- data/lib/rabl-rails/nodes/code.rb +19 -0
- data/lib/rabl-rails/nodes/condition.rb +14 -0
- data/lib/rabl-rails/nodes/glue.rb +25 -0
- data/lib/rabl-rails/nodes/node.rb +9 -0
- data/lib/rabl-rails/railtie.rb +0 -2
- data/lib/rabl-rails/renderer.rb +15 -13
- data/lib/rabl-rails/renderers/hash.rb +85 -0
- data/lib/rabl-rails/renderers/json.rb +9 -5
- data/lib/rabl-rails/renderers/plist.rb +6 -4
- data/lib/rabl-rails/renderers/xml.rb +6 -3
- data/lib/rabl-rails/responder.rb +1 -1
- data/lib/rabl-rails/template.rb +11 -5
- data/lib/rabl-rails/version.rb +1 -1
- data/lib/rabl-rails/visitors.rb +2 -0
- data/lib/rabl-rails/visitors/to_hash.rb +131 -0
- data/lib/rabl-rails/visitors/visitor.rb +17 -0
- data/rabl-rails.gemspec +3 -5
- data/test/helper.rb +75 -0
- data/test/renderers/test_hash_renderer.rb +90 -0
- data/test/renderers/test_json_renderer.rb +46 -0
- data/test/renderers/test_plist_renderer.rb +42 -0
- data/test/renderers/test_xml_renderer.rb +37 -0
- data/test/test_compiler.rb +283 -0
- data/test/test_configuration.rb +31 -0
- data/test/test_hash_visitor.rb +224 -0
- data/test/test_library.rb +85 -0
- data/test/{render_test.rb → test_render.rb} +18 -24
- metadata +99 -108
- data/lib/rabl-rails/condition.rb +0 -10
- data/lib/rabl-rails/renderers/base.rb +0 -171
- data/test/base_renderer_test.rb +0 -67
- data/test/cache_templates_test.rb +0 -35
- data/test/compiler_test.rb +0 -233
- data/test/deep_nesting_test.rb +0 -56
- data/test/keyword_test.rb +0 -47
- data/test/non_restful_response_test.rb +0 -35
- data/test/renderers/json_renderer_test.rb +0 -189
- data/test/renderers/plist_renderer_test.rb +0 -135
- data/test/renderers/xml_renderer_test.rb +0 -137
- data/test/test_helper.rb +0 -68
@@ -0,0 +1,17 @@
|
|
1
|
+
module Visitors
|
2
|
+
class Visitor
|
3
|
+
def visit(node)
|
4
|
+
dispatch node
|
5
|
+
end
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
DISPATCH = Hash.new do |hash, node_class|
|
10
|
+
hash[node_class] = "visit_#{node_class.name.split('::').last}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def dispatch(node)
|
14
|
+
send DISPATCH[node.class], node
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/rabl-rails.gemspec
CHANGED
@@ -15,9 +15,7 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.test_files = `git ls-files -- test/*`.split("\n")
|
16
16
|
s.require_paths = ["lib"]
|
17
17
|
|
18
|
-
s.add_dependency
|
19
|
-
s.add_dependency
|
20
|
-
|
21
|
-
s.add_development_dependency "actionpack", ">= 3.1"
|
22
|
-
s.add_development_dependency "rspec-mocks"
|
18
|
+
s.add_dependency 'activesupport', '>= 3.1'
|
19
|
+
s.add_dependency 'railties', '>= 3.1'
|
20
|
+
s.add_dependency 'thread_safe', '~> 0.3.1'
|
23
21
|
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
ENV['RAILS_ENV'] = 'test'
|
2
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
3
|
+
|
4
|
+
# require 'rspec/mocks'
|
5
|
+
require 'minitest/mock'
|
6
|
+
require 'minitest/autorun'
|
7
|
+
|
8
|
+
require 'rabl-rails'
|
9
|
+
require 'plist'
|
10
|
+
|
11
|
+
if RUBY_ENGINE == 'jruby'
|
12
|
+
require 'nokogiri'
|
13
|
+
elsif RUBY_ENGINE == 'ruby'
|
14
|
+
require 'libxml'
|
15
|
+
end
|
16
|
+
|
17
|
+
MINITEST_TEST_CLASS = if defined?(Minitest::Test)
|
18
|
+
Minitest::Test
|
19
|
+
else
|
20
|
+
Minitest::Unit::TestCase
|
21
|
+
end
|
22
|
+
|
23
|
+
module Configurable
|
24
|
+
def with_configuration(key, value)
|
25
|
+
accessor = "#{key}="
|
26
|
+
old_value = RablRails.configuration.send(key)
|
27
|
+
RablRails.configuration.send(accessor, value)
|
28
|
+
yield
|
29
|
+
ensure
|
30
|
+
RablRails.configuration.send(accessor, old_value)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
MINITEST_TEST_CLASS.send(:include, Configurable)
|
34
|
+
|
35
|
+
module Rails
|
36
|
+
def self.cache
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module ActionController
|
41
|
+
module Base
|
42
|
+
def self.perform_caching
|
43
|
+
false
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class Context
|
49
|
+
attr_writer :virtual_path
|
50
|
+
|
51
|
+
def initialize
|
52
|
+
@_assigns = {}
|
53
|
+
@virtual_path = nil
|
54
|
+
end
|
55
|
+
|
56
|
+
def assigns
|
57
|
+
@_assigns
|
58
|
+
end
|
59
|
+
|
60
|
+
def params
|
61
|
+
{}
|
62
|
+
end
|
63
|
+
|
64
|
+
def context_method
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class User
|
69
|
+
attr_accessor :id, :name
|
70
|
+
|
71
|
+
def initialize(id = nil, name = nil)
|
72
|
+
@id = id
|
73
|
+
@name = name
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestHashRenderer < MINITEST_TEST_CLASS
|
4
|
+
describe 'hash renderer' do
|
5
|
+
def render(locals = nil)
|
6
|
+
RablRails::Renderers::Hash.render(@template, @context, locals)
|
7
|
+
end
|
8
|
+
|
9
|
+
def with_cache
|
10
|
+
ActionController::Base.stub :perform_caching, true do
|
11
|
+
Rails.stub :cache, @cache do
|
12
|
+
yield
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
before do
|
18
|
+
@cache = MiniTest::Mock.new
|
19
|
+
@resource = User.new(1, 'Marty')
|
20
|
+
@context = Context.new
|
21
|
+
@context.assigns['user'] = @resource
|
22
|
+
@template = RablRails::CompiledTemplate.new
|
23
|
+
@template.data = :@user
|
24
|
+
@template.add_node RablRails::Nodes::Attribute.new(name: :name)
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'cache' do
|
28
|
+
it 'uses resource cache_key by default' do
|
29
|
+
def @resource.cache_key; 'marty_cache' end
|
30
|
+
@template.cache_key = nil
|
31
|
+
@cache.expect :fetch, { user: 'Marty' }, ['marty_cache']
|
32
|
+
with_cache {
|
33
|
+
assert_equal({ user: 'Marty' }, render)
|
34
|
+
}
|
35
|
+
@cache.verify
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'uses template cache_key if present' do
|
39
|
+
@template.cache_key = ->(u) { u.name }
|
40
|
+
@cache.expect :fetch, { user: 'Marty' }, ['Marty']
|
41
|
+
with_cache {
|
42
|
+
assert_equal({ user: 'Marty' }, render)
|
43
|
+
}
|
44
|
+
@cache.verify
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'uses a to_hash visitor' do
|
49
|
+
visitor = MiniTest::Mock.new
|
50
|
+
visitor.expect :instance_variable_get, @resource, [:@user]
|
51
|
+
visitor.expect :reset_for, nil, [@resource]
|
52
|
+
visitor.expect :visit, nil, [Array]
|
53
|
+
visitor.expect :result, { some: 'result' }
|
54
|
+
|
55
|
+
Visitors::ToHash.stub :new, visitor do
|
56
|
+
assert_equal({ some: 'result' }, render)
|
57
|
+
end
|
58
|
+
|
59
|
+
visitor.verify
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'retrieves data from context if exist' do
|
63
|
+
@template.data = :context_method
|
64
|
+
resource = User.new(2, 'Biff')
|
65
|
+
@context.stub :context_method, resource do
|
66
|
+
assert_equal({ name: 'Biff' }, render)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'uses assigns from context if context has no data method' do
|
71
|
+
assert_equal({ name: 'Marty' }, render)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "uses resource passed in locals if template don't have data" do
|
75
|
+
@template.data = nil
|
76
|
+
resource = User.new(2, 'Biff')
|
77
|
+
assert_equal({ name: 'Biff' }, render(resource: resource))
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'uses template root_name option' do
|
81
|
+
@template.root_name = :user
|
82
|
+
assert_equal({ user: { name: 'Marty' } }, render)
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'renders collection' do
|
86
|
+
@context.assigns['user'] = [@resource]
|
87
|
+
assert_equal([{ name: 'Marty' }], render)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestJSONRenderer < MINITEST_TEST_CLASS
|
4
|
+
describe 'JSON renderer' do
|
5
|
+
def render
|
6
|
+
RablRails::Renderers::JSON.render(@template, @context)
|
7
|
+
end
|
8
|
+
|
9
|
+
before do
|
10
|
+
@resource = User.new(1, 'Marty')
|
11
|
+
@context = Context.new
|
12
|
+
@context.assigns['user'] = @resource
|
13
|
+
@template = RablRails::CompiledTemplate.new
|
14
|
+
@template.data = :@user
|
15
|
+
@template.add_node RablRails::Nodes::Attribute.new(name: :name)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'extends hash renderer' do
|
19
|
+
RablRails::Renderers::JSON.ancestors.include?(RablRails::Renderers::Hash)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'renders JSON' do
|
23
|
+
assert_equal %q({"name":"Marty"}), render
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'uses template root_name option' do
|
27
|
+
@template.root_name = :user
|
28
|
+
assert_equal %q({"user":{"name":"Marty"}}), render
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'ignores template root_name option if include_json_root is disabled' do
|
32
|
+
@template.root_name = :user
|
33
|
+
with_configuration :include_json_root, false do
|
34
|
+
assert_equal %q({"name":"Marty"}), render
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'renders jsonp callback' do
|
39
|
+
@context.stub :params, { callback: 'some_callback' } do
|
40
|
+
with_configuration :enable_jsonp_callbacks, true do
|
41
|
+
assert_equal %q[some_callback({"name":"Marty"})], render
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestPListRenderer < MINITEST_TEST_CLASS
|
4
|
+
INDENT_REGEXP = /\n(\s)*/
|
5
|
+
HEADER_REGEXP = /<\?[^>]+><![^>]+>/
|
6
|
+
|
7
|
+
describe 'PList renderer' do
|
8
|
+
def render
|
9
|
+
output = RablRails::Renderers::PLIST.render(@template, @context).to_s.gsub!(INDENT_REGEXP, '')
|
10
|
+
output.sub!(HEADER_REGEXP, '').gsub!(%r(</?plist[^>]*>), '').sub!(%r(<dict/?>), '').sub(%r(</dict>), '')
|
11
|
+
end
|
12
|
+
|
13
|
+
before do
|
14
|
+
@resource = User.new(1, 'Marty')
|
15
|
+
@context = Context.new
|
16
|
+
@context.assigns['user'] = @resource
|
17
|
+
@template = RablRails::CompiledTemplate.new
|
18
|
+
@template.data = :@user
|
19
|
+
@template.add_node RablRails::Nodes::Attribute.new(name: :name)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'extends hash renderer' do
|
23
|
+
RablRails::Renderers::PLIST.ancestors.include?(RablRails::Renderers::Hash)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'renders PList' do
|
27
|
+
assert_equal %q(<key>name</key><string>Marty</string>), render
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'uses template root_name option if include_plist_root is set' do
|
31
|
+
@template.root_name = :user
|
32
|
+
with_configuration :include_plist_root, true do
|
33
|
+
assert_equal %q(<key>user</key><dict><key>name</key><string>Marty</string></dict>), render
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'ignores template root_name by default' do
|
38
|
+
@template.root_name = :user
|
39
|
+
assert_equal %q(<key>name</key><string>Marty</string>), render
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestXMLRenderer < MINITEST_TEST_CLASS
|
4
|
+
INDENT_REGEXP = /\n(\s)*/
|
5
|
+
HEADER_REGEXP = /<[^>]+>/
|
6
|
+
|
7
|
+
describe 'XML renderer' do
|
8
|
+
def render
|
9
|
+
RablRails::Renderers::XML.render(@template, @context).to_s.gsub!(INDENT_REGEXP, '').sub!(HEADER_REGEXP, '')
|
10
|
+
end
|
11
|
+
|
12
|
+
before do
|
13
|
+
@resource = User.new(1, 'Marty')
|
14
|
+
@context = Context.new
|
15
|
+
@context.assigns['user'] = @resource
|
16
|
+
@template = RablRails::CompiledTemplate.new
|
17
|
+
@template.data = :@user
|
18
|
+
@template.add_node RablRails::Nodes::Attribute.new(name: :name)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'extends hash renderer' do
|
22
|
+
RablRails::Renderers::XML.ancestors.include?(RablRails::Renderers::Hash)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'uses global XML options' do
|
26
|
+
@template.nodes = [RablRails::Nodes::Attribute.new(first_name: :name)]
|
27
|
+
with_configuration :xml_options, { dasherize: false, skip_types: false } do
|
28
|
+
assert_equal %q(<hash><first_name>Marty</first_name></hash>), render
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'uses template root_name option' do
|
33
|
+
@template.root_name = :user
|
34
|
+
assert_equal %q(<user><name>Marty</name></user>), render
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,283 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestCompiler < MINITEST_TEST_CLASS
|
4
|
+
describe 'compiler' do
|
5
|
+
def extract_attributes(nodes)
|
6
|
+
nodes.map(&:hash)
|
7
|
+
end
|
8
|
+
|
9
|
+
before do
|
10
|
+
@view = Context.new
|
11
|
+
@compiler = RablRails::Compiler.new(@view)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns a compiled template instance" do
|
15
|
+
assert_instance_of RablRails::CompiledTemplate, @compiler.compile_source("")
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#object' do
|
19
|
+
it "sets data for the template" do
|
20
|
+
t = @compiler.compile_source(%{ object :@user })
|
21
|
+
assert_equal :@user, t.data
|
22
|
+
assert_equal([], t.nodes)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "can define root name" do
|
26
|
+
t = @compiler.compile_source(%{ object :@user => :author })
|
27
|
+
assert_equal :@user, t.data
|
28
|
+
assert_equal :author, t.root_name
|
29
|
+
assert_equal([], t.nodes)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#root' do
|
34
|
+
it "defines root via keyword" do
|
35
|
+
t = @compiler.compile_source(%{ root :author })
|
36
|
+
assert_equal :author, t.root_name
|
37
|
+
end
|
38
|
+
|
39
|
+
it "overrides object root" do
|
40
|
+
t = @compiler.compile_source(%{ object :@user ; root :author })
|
41
|
+
assert_equal :author, t.root_name
|
42
|
+
end
|
43
|
+
|
44
|
+
it "can set root to false via options" do
|
45
|
+
t = @compiler.compile_source(%( object :@user, root: false))
|
46
|
+
assert_equal false, t.root_name
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#collection' do
|
51
|
+
it "sets the data for the template" do
|
52
|
+
t = @compiler.compile_source(%{ collection :@user })
|
53
|
+
assert_equal :@user, t.data
|
54
|
+
assert_equal([], t.nodes)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "can define root name" do
|
58
|
+
t = @compiler.compile_source(%{ collection :@user => :users })
|
59
|
+
assert_equal :@user, t.data
|
60
|
+
assert_equal :users, t.root_name
|
61
|
+
assert_equal([], t.nodes)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "can define root name via options" do
|
65
|
+
t = @compiler.compile_source(%{ collection :@user, :root => :users })
|
66
|
+
assert_equal :@user, t.data
|
67
|
+
assert_equal :users, t.root_name
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should not have a cache key if cache is not enable" do
|
72
|
+
t = @compiler.compile_source('')
|
73
|
+
assert_equal false, t.cache_key
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#cache' do
|
77
|
+
it "can take no argument" do
|
78
|
+
t = @compiler.compile_source(%{ cache })
|
79
|
+
assert_nil t.cache_key
|
80
|
+
end
|
81
|
+
|
82
|
+
it "sets the given block as cache key" do
|
83
|
+
t = @compiler.compile_source(%( cache { 'foo' }))
|
84
|
+
assert_instance_of Proc, t.cache_key
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Compilation
|
89
|
+
|
90
|
+
it "compiles single attributes" do
|
91
|
+
t = @compiler.compile_source(%{ attributes :id, :name })
|
92
|
+
assert_equal([{ :id => :id, :name => :name }], extract_attributes(t.nodes))
|
93
|
+
end
|
94
|
+
|
95
|
+
it "compiles attributes with the same name once" do
|
96
|
+
skip('Failing')
|
97
|
+
t = @compiler.compile_source(%{ attribute :id ; attribute :id })
|
98
|
+
assert_equal([{ :id => :id }], extract_attributes(t.nodes))
|
99
|
+
end
|
100
|
+
|
101
|
+
it "aliases attributes through :as option" do
|
102
|
+
t = @compiler.compile_source(%{ attribute :foo, :as => :bar })
|
103
|
+
assert_equal([{ :bar => :foo }], extract_attributes(t.nodes))
|
104
|
+
end
|
105
|
+
|
106
|
+
it "aliases attributes through a hash" do
|
107
|
+
t = @compiler.compile_source(%{ attribute :foo => :bar })
|
108
|
+
assert_equal([{ :bar => :foo }], extract_attributes(t.nodes))
|
109
|
+
end
|
110
|
+
|
111
|
+
it "aliases multiple attributes" do
|
112
|
+
t = @compiler.compile_source(%{ attributes :foo => :bar, :id => :uid })
|
113
|
+
assert_equal([{ :bar => :foo, :uid => :id }], extract_attributes(t.nodes))
|
114
|
+
end
|
115
|
+
|
116
|
+
it "compiles child with record association" do
|
117
|
+
t = @compiler.compile_source(%{ child :address do attributes :foo end})
|
118
|
+
|
119
|
+
assert_equal(1, t.nodes.size)
|
120
|
+
child_node = t.nodes.first
|
121
|
+
|
122
|
+
assert_equal(:address, child_node.name)
|
123
|
+
assert_equal(:address, child_node.data)
|
124
|
+
assert_equal([{ foo: :foo }], extract_attributes(child_node.nodes))
|
125
|
+
end
|
126
|
+
|
127
|
+
it "compiles child with association aliased" do
|
128
|
+
t = @compiler.compile_source(%{ child :address => :bar do attributes :foo end})
|
129
|
+
child_node = t.nodes.first
|
130
|
+
|
131
|
+
assert_equal(:bar, child_node.name)
|
132
|
+
assert_equal(:address, child_node.data)
|
133
|
+
end
|
134
|
+
|
135
|
+
it "compiles child with root name defined as option" do
|
136
|
+
t = @compiler.compile_source(%{ child(:user, :root => :author) do attributes :foo end })
|
137
|
+
child_node = t.nodes.first
|
138
|
+
|
139
|
+
assert_equal(:author, child_node.name)
|
140
|
+
assert_equal(:user, child_node.data)
|
141
|
+
end
|
142
|
+
|
143
|
+
it "compiles child with arbitrary source" do
|
144
|
+
t = @compiler.compile_source(%{ child :@user => :author do attribute :name end })
|
145
|
+
child_node = t.nodes.first
|
146
|
+
|
147
|
+
assert_equal(:author, child_node.name)
|
148
|
+
assert_equal(:@user, child_node.data)
|
149
|
+
end
|
150
|
+
|
151
|
+
it "compiles child with inline partial notation" do
|
152
|
+
mock_template = RablRails::CompiledTemplate.new
|
153
|
+
mock_template.add_node(RablRails::Nodes::Attribute.new(id: :id))
|
154
|
+
|
155
|
+
t = RablRails::Library.instance.stub :compile_template_from_path, mock_template do
|
156
|
+
@compiler.compile_source(%{child(:user, :partial => 'users/base') })
|
157
|
+
end
|
158
|
+
|
159
|
+
child_node = t.nodes.first
|
160
|
+
|
161
|
+
assert_equal(:user, child_node.name)
|
162
|
+
assert_equal(:user, child_node.data)
|
163
|
+
assert_equal([{ id: :id }], extract_attributes(child_node.nodes))
|
164
|
+
end
|
165
|
+
|
166
|
+
it "compiles glue as a child but without a name" do
|
167
|
+
t = @compiler.compile_source(%{ glue(:@user) do attribute :name end })
|
168
|
+
|
169
|
+
assert_equal(1, t.nodes.size)
|
170
|
+
glue_node = t.nodes.first
|
171
|
+
|
172
|
+
assert_equal(:@user, glue_node.data)
|
173
|
+
assert_equal([{ name: :name }], extract_attributes(glue_node.nodes))
|
174
|
+
end
|
175
|
+
|
176
|
+
it "allows multiple glue within same template" do
|
177
|
+
t = @compiler.compile_source(%{
|
178
|
+
glue :@user do attribute :name end
|
179
|
+
glue :@user do attribute :foo end
|
180
|
+
})
|
181
|
+
|
182
|
+
assert_equal(2, t.nodes.size)
|
183
|
+
end
|
184
|
+
|
185
|
+
it "compiles glue with RablRails DSL in its body" do
|
186
|
+
t = @compiler.compile_source(%{
|
187
|
+
glue :@user do node(:foo) { |u| u.name } end
|
188
|
+
})
|
189
|
+
|
190
|
+
glue_node = t.nodes.first
|
191
|
+
assert_equal(1, glue_node.nodes.size)
|
192
|
+
|
193
|
+
code_node = glue_node.nodes.first
|
194
|
+
assert_instance_of(RablRails::Nodes::Code, code_node)
|
195
|
+
assert_equal(:foo, code_node.name)
|
196
|
+
end
|
197
|
+
|
198
|
+
it "extends other template" do
|
199
|
+
template = RablRails::CompiledTemplate.new
|
200
|
+
template.add_node RablRails::Nodes::Attribute.new(id: :id)
|
201
|
+
|
202
|
+
library = MiniTest::Mock.new
|
203
|
+
library.expect :compile_template_from_path, template, ['users/base', @view]
|
204
|
+
|
205
|
+
t = RablRails::Library.stub :instance, library do
|
206
|
+
@compiler.compile_source(%{ extends 'users/base' })
|
207
|
+
end
|
208
|
+
assert_equal([{ :id => :id }], extract_attributes(t.nodes))
|
209
|
+
library.verify
|
210
|
+
end
|
211
|
+
|
212
|
+
it "compiles extend without overwriting nodes previously defined" do
|
213
|
+
template = RablRails::CompiledTemplate.new
|
214
|
+
template.add_node(RablRails::Nodes::Condition.new(->{ true }, ->{ 'foo' }))
|
215
|
+
|
216
|
+
t = RablRails::Library.instance.stub :compile_template_from_path, template do
|
217
|
+
@compiler.compile_source(%{
|
218
|
+
condition(-> { false }) { 'bar' }
|
219
|
+
extends('users/xtnd')
|
220
|
+
})
|
221
|
+
end
|
222
|
+
assert_equal(2, t.nodes.size)
|
223
|
+
end
|
224
|
+
|
225
|
+
it "compiles node" do
|
226
|
+
t = @compiler.compile_source(%{ node(:foo) { bar } })
|
227
|
+
|
228
|
+
assert_equal(1, t.nodes.size)
|
229
|
+
code_node = t.nodes.first
|
230
|
+
|
231
|
+
assert_equal(:foo, code_node.name)
|
232
|
+
assert_instance_of Proc, code_node.block
|
233
|
+
end
|
234
|
+
|
235
|
+
it "compiles node with condition option" do
|
236
|
+
t = @compiler.compile_source(%{ node(:foo, :if => lambda { |m| m.foo.present? }) do |m| m.foo end })
|
237
|
+
code_node = t.nodes.first
|
238
|
+
assert_instance_of Proc, code_node.condition
|
239
|
+
end
|
240
|
+
|
241
|
+
it "compiles node with no argument" do
|
242
|
+
t = @compiler.compile_source(%{ node do |m| m.foo end })
|
243
|
+
node = t.nodes.first
|
244
|
+
assert_nil node.name
|
245
|
+
end
|
246
|
+
|
247
|
+
it "compiles merge like a node but with a reserved keyword as name" do
|
248
|
+
t = @compiler.compile_source(%{ merge do |m| m.foo end })
|
249
|
+
node = t.nodes.first
|
250
|
+
assert_instance_of RablRails::Nodes::Code, node
|
251
|
+
assert_nil node.name
|
252
|
+
end
|
253
|
+
|
254
|
+
it "compiles condition" do
|
255
|
+
t = @compiler.compile_source(%{ condition(->(u) {}) do attributes :secret end })
|
256
|
+
|
257
|
+
assert_equal(1, t.nodes.size)
|
258
|
+
node = t.nodes.first
|
259
|
+
|
260
|
+
assert_instance_of RablRails::Nodes::Condition, node
|
261
|
+
assert_equal([{ secret: :secret }], extract_attributes(node.nodes))
|
262
|
+
end
|
263
|
+
|
264
|
+
it "compiles with no object" do
|
265
|
+
t = @compiler.compile_source(%{
|
266
|
+
object false
|
267
|
+
child(:@user => :user) do
|
268
|
+
attribute :id
|
269
|
+
end
|
270
|
+
})
|
271
|
+
|
272
|
+
assert_equal false, t.data
|
273
|
+
end
|
274
|
+
|
275
|
+
describe '#extract_data_and_name' do
|
276
|
+
it "extracts name from argument" do
|
277
|
+
assert_equal [:@users, 'users'], @compiler.send(:extract_data_and_name, :@users)
|
278
|
+
assert_equal [:users, :users], @compiler.send(:extract_data_and_name, :users)
|
279
|
+
assert_equal [:@users, :authors], @compiler.send(:extract_data_and_name, :@users => :authors)
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|