rabl-rails 0.4.3 → 0.5.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.
@@ -4,10 +4,21 @@ module RablRails
4
4
  ActiveSupport.on_load(:action_view) do
5
5
  ActionView::Template.register_template_handler :rabl, RablRails::Handlers::Rabl
6
6
  end
7
- end
8
7
 
9
- config.after_initialize do
10
- ActionController::Base.responder = RablRails::Responder if RablRails.configuration.use_custom_responder
8
+ if Rails::VERSION::MAJOR >= 5
9
+ module ::ActionController
10
+ module ApiRendering
11
+ include ActionView::Rendering
12
+ end
13
+ end
14
+
15
+ ActiveSupport.on_load :action_controller do
16
+ if self == ActionController::API
17
+ include ActionController::Helpers
18
+ include ActionController::ImplicitRender
19
+ end
20
+ end
21
+ end
11
22
  end
12
23
  end
13
24
  end
@@ -20,7 +20,6 @@ module RablRails
20
20
  visitor.instance_variable_get(template.data)
21
21
  end
22
22
  end
23
- collection_or_resource ||= locals[:resource] if locals
24
23
 
25
24
  render_with_cache(template.cache_key, collection_or_resource) do
26
25
  output_hash = if collection?(collection_or_resource)
@@ -82,4 +81,4 @@ module RablRails
82
81
  end
83
82
  end
84
83
  end
85
- end
84
+ end
@@ -3,8 +3,9 @@ module RablRails
3
3
  attr_accessor :nodes, :data, :root_name, :cache_key
4
4
 
5
5
  def initialize
6
- @nodes = []
7
- @cache_key = false
6
+ @nodes = []
7
+ @data = nil
8
+ @cache_key = false
8
9
  end
9
10
 
10
11
  def initialize_dup(other)
@@ -20,4 +21,4 @@ module RablRails
20
21
  @nodes.concat template.nodes
21
22
  end
22
23
  end
23
- end
24
+ end
@@ -1,3 +1,3 @@
1
1
  module RablRails
2
- VERSION = '0.4.3'
2
+ VERSION = '0.5.0'
3
3
  end
@@ -18,10 +18,6 @@ module Visitors
18
18
  @_result = {}
19
19
  end
20
20
 
21
- def visit_Array n
22
- n.each { |i| visit i }
23
- end
24
-
25
21
  def visit_Attribute n
26
22
  if !n.condition || instance_exec(_resource, &(n.condition))
27
23
  n.each { |k, v| @_result[k] = _resource.send(v) }
@@ -29,7 +25,7 @@ module Visitors
29
25
  end
30
26
 
31
27
  def visit_Child n
32
- object = object_from_data(_resource, n.data, n.instance_variable_data?)
28
+ object = object_from_data(_resource, n)
33
29
 
34
30
  @_result[n.name] = if object
35
31
  collection?(object) ? object.map { |o| sub_visit(o, n.nodes) } : sub_visit(object, n.nodes)
@@ -38,12 +34,17 @@ module Visitors
38
34
  end
39
35
  end
40
36
 
37
+ def visit_Glue n
38
+ object = object_from_data(_resource, n)
39
+ @_result.merge!(sub_visit(object, n.nodes)) if object
40
+ end
41
+
41
42
  def visit_Code n
42
43
  if !n.condition || instance_exec(_resource, &(n.condition))
43
44
  result = instance_exec _resource, &(n.block)
44
45
 
45
46
  if n.merge?
46
- raise RablRails::Renderer::PartialError, '`merge` block should return a hash' unless result.is_a?(Hash)
47
+ raise RablRails::PartialError, '`merge` block should return a hash' unless result.is_a?(Hash)
47
48
  @_result.merge!(result)
48
49
  else
49
50
  @_result[n.name] = result
@@ -55,9 +56,11 @@ module Visitors
55
56
  @_result.merge!(sub_visit(_resource, n.nodes)) if instance_exec _resource, &(n.condition)
56
57
  end
57
58
 
58
- def visit_Glue n
59
- object = object_from_data(_resource, n.data, n.instance_variable_data?)
60
- @_result.merge! sub_visit(object, n.template.nodes)
59
+ def visit_Extend n
60
+ @_locals = n.locals
61
+ @_result.merge!(sub_visit(_resource, n.nodes))
62
+ ensure
63
+ @_locals = {}
61
64
  end
62
65
 
63
66
  def result
@@ -65,13 +68,13 @@ module Visitors
65
68
  when 0
66
69
  @_result
67
70
  when 1
68
- @_result.each { |k, v| @_result[k] = '' if v == nil }
71
+ @_result.each { |k, v| @_result[k] = ''.freeze if v == nil }
69
72
  when 2, 3
70
- @_result.each { |k, v| @_result[k] = nil if v == '' }
73
+ @_result.each { |k, v| @_result[k] = nil if v == ''.freeze }
71
74
  when 4, 5
72
75
  @_result.delete_if { |_, v| v == nil }
73
76
  when 6
74
- @_result.delete_if { |_, v| v == nil || v == '' }
77
+ @_result.delete_if { |_, v| v == nil || v == ''.freeze }
75
78
  end
76
79
  end
77
80
 
@@ -95,7 +98,7 @@ module Visitors
95
98
  # rendering time).
96
99
  #
97
100
  def partial(template_path, options = {})
98
- raise RablRails::Renderer::PartialError.new("No object was given to partial #{template_path}") unless options[:object]
101
+ raise RablRails::PartialError.new("No object was given to partial #{template_path}") unless options[:object]
99
102
  object = options[:object]
100
103
  @_locals = options[:locals].freeze
101
104
 
@@ -115,7 +118,7 @@ module Visitors
115
118
 
116
119
  def copy_instance_variables_from_context
117
120
  @_context.instance_variable_get(:@_assigns).each_pair { |k, v|
118
- instance_variable_set("@#{k}", v) unless k.to_s.start_with?('_')
121
+ instance_variable_set("@#{k}", v) unless k.to_s.start_with?('_'.freeze)
119
122
  }
120
123
  end
121
124
 
@@ -128,10 +131,11 @@ module Visitors
128
131
  @_result, @_resource = old_result, old_resource
129
132
  end
130
133
 
131
- def object_from_data(resource, symbol, is_variable)
132
- return resource if symbol == nil
134
+ def object_from_data(resource, node)
135
+ return resource if node.data == nil
133
136
 
134
- if is_variable
137
+ symbol = node.data
138
+ if node.instance_variable_data?
135
139
  instance_variable_get(symbol)
136
140
  else
137
141
  resource.respond_to?(symbol) ? resource.send(symbol) : @_context.send(symbol)
@@ -1,7 +1,11 @@
1
1
  module Visitors
2
2
  class Visitor
3
3
  def visit(node)
4
- dispatch node
4
+ dispatch(node)
5
+ end
6
+
7
+ def visit_Array a
8
+ a.each { |n| dispatch(n) }
5
9
  end
6
10
 
7
11
  private
@@ -14,4 +18,4 @@ module Visitors
14
18
  send DISPATCH[node.class], node
15
19
  end
16
20
  end
17
- end
21
+ end
data/rabl-rails.gemspec CHANGED
@@ -8,17 +8,20 @@ Gem::Specification.new do |s|
8
8
  s.authors = ["Christopher Cocchi-Perrier"]
9
9
  s.email = ["cocchi.c@gmail.com"]
10
10
  s.homepage = "https://github.com/ccocchi/rabl-rails"
11
- s.summary = "Fast Rails 3+ templating system with JSON, XML and PList support"
12
- s.description = "Fast Rails 3+ templating system with JSON, XML and PList support"
11
+ s.summary = "Fast Rails 4+ templating system with JSON, XML and PList support"
12
+ s.description = "Fast Rails 4+ templating system with JSON, XML and PList support"
13
13
  s.license = 'MIT'
14
14
 
15
+ s.required_ruby_version = '>= 2.2.0'
16
+
15
17
  s.files = `git ls-files`.split("\n")
16
18
  s.test_files = `git ls-files -- test/*`.split("\n")
17
19
  s.require_paths = ["lib"]
18
20
 
19
- s.add_dependency 'activesupport', '>= 3.1'
20
- s.add_dependency 'railties', '>= 3.1'
21
- s.add_dependency 'thread_safe', '~> 0.3.1'
21
+ s.add_dependency 'activesupport', '>= 4.2'
22
+ s.add_dependency 'railties', '>= 4.2'
23
+ s.add_dependency 'concurrent-ruby', '~> 1.0.0'
22
24
 
23
- s.add_development_dependency 'actionpack', '>= 3.1'
25
+ s.add_development_dependency 'actionpack', '>= 4.2'
26
+ s.add_development_dependency 'actionview', '>= 4.2'
24
27
  end
data/test/helper.rb CHANGED
@@ -9,7 +9,6 @@ require 'rabl-rails'
9
9
  require 'plist'
10
10
  require 'action_dispatch/http/mime_type'
11
11
  require 'action_view'
12
- require 'active_support/core_ext/string/starts_ends_with'
13
12
 
14
13
  if RUBY_ENGINE == 'jruby'
15
14
  require 'nokogiri'
@@ -17,12 +16,6 @@ elsif RUBY_ENGINE == 'ruby'
17
16
  require 'libxml'
18
17
  end
19
18
 
20
- MINITEST_TEST_CLASS = if defined?(Minitest::Test)
21
- Minitest::Test
22
- else
23
- Minitest::Unit::TestCase
24
- end
25
-
26
19
  ActionView::Template.register_template_handler :rabl, RablRails::Handlers::Rabl
27
20
 
28
21
  module Configurable
@@ -35,7 +28,7 @@ module Configurable
35
28
  RablRails.configuration.send(accessor, old_value)
36
29
  end
37
30
  end
38
- MINITEST_TEST_CLASS.send(:include, Configurable)
31
+ Minitest::Test.send(:include, Configurable)
39
32
 
40
33
  module Rails
41
34
  def self.cache
@@ -1,9 +1,9 @@
1
1
  require 'helper'
2
2
 
3
- class TestHashRenderer < MINITEST_TEST_CLASS
3
+ class TestHashRenderer < Minitest::Test
4
4
  describe 'hash renderer' do
5
- def render(locals = nil)
6
- RablRails::Renderers::Hash.render(@template, @context, locals)
5
+ def render
6
+ RablRails::Renderers::Hash.render(@template, @context, {})
7
7
  end
8
8
 
9
9
  def with_cache
@@ -71,12 +71,6 @@ class TestHashRenderer < MINITEST_TEST_CLASS
71
71
  assert_equal({ name: 'Marty' }, render)
72
72
  end
73
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
74
  it 'uses template root_name option' do
81
75
  @template.root_name = :user
82
76
  assert_equal({ user: { name: 'Marty' } }, render)
@@ -87,4 +81,4 @@ class TestHashRenderer < MINITEST_TEST_CLASS
87
81
  assert_equal([{ name: 'Marty' }], render)
88
82
  end
89
83
  end
90
- end
84
+ end
@@ -1,6 +1,6 @@
1
1
  require 'helper'
2
2
 
3
- class TestJSONRenderer < MINITEST_TEST_CLASS
3
+ class TestJSONRenderer < Minitest::Test
4
4
  describe 'JSON renderer' do
5
5
  def render
6
6
  RablRails::Renderers::JSON.render(@template, @context)
@@ -1,6 +1,6 @@
1
1
  require 'helper'
2
2
 
3
- class TestPListRenderer < MINITEST_TEST_CLASS
3
+ class TestPListRenderer < Minitest::Test
4
4
  INDENT_REGEXP = /\n(\s)*/
5
5
  HEADER_REGEXP = /<\?[^>]+><![^>]+>/
6
6
 
@@ -1,6 +1,6 @@
1
1
  require 'helper'
2
2
 
3
- class TestXMLRenderer < MINITEST_TEST_CLASS
3
+ class TestXMLRenderer < Minitest::Test
4
4
  INDENT_REGEXP = /\n(\s)*/
5
5
  HEADER_REGEXP = /<[^>]+>/
6
6
 
@@ -2,9 +2,15 @@ require 'helper'
2
2
  require 'pathname'
3
3
  require 'tmpdir'
4
4
 
5
- class TestCompiler < MINITEST_TEST_CLASS
5
+ class TestCompiler < Minitest::Test
6
6
  @@tmp_path = Pathname.new(Dir.mktmpdir)
7
7
 
8
+ File.open(@@tmp_path + 'user.rabl', 'w') do |f|
9
+ f.puts %q{
10
+ attributes :id
11
+ }
12
+ end
13
+
8
14
  describe 'compiler' do
9
15
  def extract_attributes(nodes)
10
16
  nodes.map(&:hash)
@@ -159,11 +165,7 @@ class TestCompiler < MINITEST_TEST_CLASS
159
165
  end
160
166
 
161
167
  it "compiles child with inline partial notation" do
162
- File.open(@@tmp_path + 'user.rabl', 'w') do |f|
163
- f.puts %q{
164
- attributes :id
165
- }
166
- end
168
+
167
169
 
168
170
  t = @compiler.compile_source(%{child(:user, :partial => 'user') })
169
171
  child_node = t.nodes.first
@@ -205,12 +207,17 @@ class TestCompiler < MINITEST_TEST_CLASS
205
207
  assert_equal(:foo, code_node.name)
206
208
  end
207
209
 
210
+ it "compiles glue with a partial" do
211
+ t = @compiler.compile_source(%{
212
+ glue(:@user, partial: 'user')
213
+ })
214
+
215
+ glue_node = t.nodes.first
216
+ assert_equal(1, glue_node.nodes.size)
217
+ assert_equal([{ :id => :id }], extract_attributes(glue_node.nodes))
218
+ end
219
+
208
220
  it "extends other template" do
209
- File.open(@@tmp_path + 'user.rabl', 'w') do |f|
210
- f.puts %q{
211
- attributes :id
212
- }
213
- end
214
221
  t = @compiler.compile_source(%{ extends 'user' })
215
222
  assert_equal([{ :id => :id }], extract_attributes(t.nodes))
216
223
  end
@@ -229,17 +236,21 @@ class TestCompiler < MINITEST_TEST_CLASS
229
236
  end
230
237
 
231
238
  it "extends template that has been compiled previously by ActionView" do
232
- File.open(@@tmp_path + 'user.rabl', 'w') do |f|
233
- f.puts %q{
234
- attributes :id
235
- }
236
- end
237
239
  t = @view.lookup_context.find_template('user')
238
240
  t.send(:compile!, @view)
239
241
  t = @compiler.compile_source(%{ extends 'user' })
240
242
  assert_equal([{ :id => :id }], extract_attributes(t.nodes))
241
243
  end
242
244
 
245
+ it "compiles extends with locals" do
246
+ t = @compiler.compile_source(%{ extends 'user', locals: { display_credit_card: false } })
247
+ node = t.nodes.first
248
+
249
+ assert_instance_of RablRails::Nodes::Extend, node
250
+ assert_equal([{ :id => :id }], extract_attributes(node.nodes))
251
+ assert_equal({ display_credit_card: false }, node.locals)
252
+ end
253
+
243
254
  it "compiles node" do
244
255
  t = @compiler.compile_source(%{ node(:foo) { bar } })
245
256
 
@@ -262,13 +273,19 @@ class TestCompiler < MINITEST_TEST_CLASS
262
273
  assert_nil node.name
263
274
  end
264
275
 
265
- it "compiles merge like a node but with a reserved keyword as name" do
276
+ it "compiles merge like a node" do
266
277
  t = @compiler.compile_source(%{ merge do |m| m.foo end })
267
278
  node = t.nodes.first
268
279
  assert_instance_of RablRails::Nodes::Code, node
269
280
  assert_nil node.name
270
281
  end
271
282
 
283
+ it "compiles merge with options" do
284
+ t = @compiler.compile_source(%{ merge(->(m) { true }) do |m| m.foo end })
285
+ node = t.nodes.first
286
+ refute_nil node.condition
287
+ end
288
+
272
289
  it "compiles condition" do
273
290
  t = @compiler.compile_source(%{ condition(->(u) {}) do attributes :secret end })
274
291
 
@@ -1,6 +1,6 @@
1
1
  require 'helper'
2
2
 
3
- class TestConfiguration < MINITEST_TEST_CLASS
3
+ class TestConfiguration < Minitest::Test
4
4
  describe 'Configuration' do
5
5
  it 'has a zero score by default' do
6
6
  config = RablRails::Configuration.new
@@ -28,4 +28,4 @@ class TestConfiguration < MINITEST_TEST_CLASS
28
28
  assert_equal 3, config.result_flags
29
29
  end
30
30
  end
31
- end
31
+ end
@@ -1,6 +1,6 @@
1
1
  require 'helper'
2
2
 
3
- class TestHashVisitor < MINITEST_TEST_CLASS
3
+ class TestHashVisitor < Minitest::Test
4
4
  describe 'hash visitor' do
5
5
  def visitor_result
6
6
  visitor = Visitors::ToHash.new(@context)
@@ -45,12 +45,12 @@ class TestHashVisitor < MINITEST_TEST_CLASS
45
45
  before do
46
46
  @template = RablRails::CompiledTemplate.new
47
47
  @template.add_node(RablRails::Nodes::Attribute.new(city: :city))
48
- @nodes << RablRails::Nodes::Child.new(:address, @template)
49
48
  @address = Address.new('Paris')
50
49
  end
51
50
 
52
51
  it 'renders with resource association as data source' do
53
52
  @template.data = :address
53
+ @nodes << RablRails::Nodes::Child.new(:address, @template)
54
54
  def @resource.address; end
55
55
  @resource.stub :address, @address do
56
56
  assert_equal({ address: { city: 'Paris' } }, visitor_result)
@@ -59,12 +59,14 @@ class TestHashVisitor < MINITEST_TEST_CLASS
59
59
 
60
60
  it 'renders with arbitrary data source' do
61
61
  @template.data = :@address
62
+ @nodes = [RablRails::Nodes::Child.new(:address, @template)]
62
63
  @context.assigns['address'] = @address
63
64
  assert_equal({ address: { city: 'Paris' } }, visitor_result)
64
65
  end
65
66
 
66
67
  it 'renders with local method as data source' do
67
68
  @template.data = :address
69
+ @nodes << RablRails::Nodes::Child.new(:address, @template)
68
70
  def @context.address; end
69
71
  @context.stub :address, @address do
70
72
  assert_equal({ address: { city: 'Paris' } }, visitor_result)
@@ -73,6 +75,7 @@ class TestHashVisitor < MINITEST_TEST_CLASS
73
75
 
74
76
  it 'renders with a collection as data source' do
75
77
  @template.data = :address
78
+ @nodes << RablRails::Nodes::Child.new(:address, @template)
76
79
  def @context.address; end
77
80
  @context.stub :address, [@address, @address] do
78
81
  assert_equal({ address: [
@@ -84,6 +87,7 @@ class TestHashVisitor < MINITEST_TEST_CLASS
84
87
 
85
88
  it 'renders if the source is nil' do
86
89
  @template.data = :address
90
+ @nodes << RablRails::Nodes::Child.new(:address, @template)
87
91
  def @resource.address; end
88
92
  @resource.stub :address, nil do
89
93
  assert_equal({ address: nil }, visitor_result)
@@ -157,7 +161,7 @@ class TestHashVisitor < MINITEST_TEST_CLASS
157
161
  it 'raises an exception when trying to merge a non hash object' do
158
162
  proc = ->(c) { c.name }
159
163
  @nodes << RablRails::Nodes::Code.new(nil, proc)
160
- assert_raises(RablRails::Renderer::PartialError) { visitor_result }
164
+ assert_raises(RablRails::PartialError) { visitor_result }
161
165
  end
162
166
 
163
167
  it 'renders partial defined in node' do
@@ -192,6 +196,17 @@ class TestHashVisitor < MINITEST_TEST_CLASS
192
196
  library.verify
193
197
  end
194
198
 
199
+ it 'renders extend with locals' do
200
+ n = RablRails::Nodes::Attribute.new(id: :id)
201
+ n.condition = lambda { |_| locals[:display_id] }
202
+
203
+ @nodes << RablRails::Nodes::Extend.new(n, display_id: true)
204
+ assert_equal({ id: 1 }, visitor_result)
205
+
206
+ @nodes.first.locals[:display_id] = false
207
+ assert_equal({}, visitor_result)
208
+ end
209
+
195
210
  it 'renders partial with empty target' do
196
211
  proc = ->(u) { partial('users/base', object: []) }
197
212
  @nodes << RablRails::Nodes::Code.new(:users, proc)
@@ -201,7 +216,7 @@ class TestHashVisitor < MINITEST_TEST_CLASS
201
216
  it 'raises an exception when calling a partial without a target' do
202
217
  proc = ->(u) { partial('users/base') }
203
218
  @nodes << RablRails::Nodes::Code.new(:user, proc)
204
- assert_raises(RablRails::Renderer::PartialError) { visitor_result }
219
+ assert_raises(RablRails::PartialError) { visitor_result }
205
220
  end
206
221
 
207
222
  describe 'when hash options are set' do