rabl 0.10.1 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZDMwMmY3ZDU1N2QwN2Y3OGNjZmRlOTljMGRiZGE1NDU3ZjQwYmViNQ==
4
+ ZTQ1YmY1YjA4YWM5YmIwNmI1Y2M3NDYzYjg0OWRmOGE3NTRiMjJiMg==
5
5
  data.tar.gz: !binary |-
6
- NzliNzM2YThjMmUxNzg3OTdhYzc5M2FiMmVhNmEwOTljYjBjYWI5Mw==
6
+ N2QxNDFjMjUwOTk2NTRhYmVmMWNiMjE3ZWQ5MmU4OWEyZTI5YzNlMQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- OTQ5YWQ4ZjYwNmRiMzc4YmRlYzIyYWZhZTA4Nzk3NzAyMWQxMDNlMzU5ZDdl
10
- M2JiOTBhYTQxNDUwZjIwZjhhYmQ0ZWMyMDFiYTkyODhkMmU0MWNhMDNjY2Y5
11
- MGQ3NTAzZDM0YmM0NzUwNmU1YjZjZTRhOTdhNjZmYzI5NjE4ZDA=
9
+ ZmE2N2I2MGZhNWM1ZWM3YTFkMDNmNzMyODhlNGM2NTFiMTRhYWE5MjJlOTlj
10
+ YjljMzc5YWEzMmJjZjdjNDRkZTAyYjE2NDA1MTMxODg3NzE3NWU2ODZlNTNk
11
+ MjczY2Y1YjgxNGI0YTBhNzE5NTY3MWQzOGIzZGFlNGQ5OTgxNjc=
12
12
  data.tar.gz: !binary |-
13
- MmRiZjE3ZGYyZjU3M2FlZWViYjkzYjgzZjU4MTU3YjA4Y2JkZjFmNjE0NjA1
14
- MDcyMTc2M2E2MjgyMGE2ZTI3NWZkN2IyN2MyZWE5MGJiMWM3ZWI4OGQyZDI1
15
- NmZmMjRmMGE5YWQ3MjE5ODI0N2JkY2IwNDEzZGMwMjUzMWRlOGM=
13
+ MzBjMDE4YjY4ZjBiNmEzODY5NDZlMzI2OTI0ZjY4Mjk0M2YyMjVkYzY3YWZl
14
+ MWQ1MWMxNjM3NDlmMTc1ZmVmOGRiODkxOTc3YTU4YTM1NWJlNjc5YWVkMjBi
15
+ ZjNlNDZmNGZmODFiZWI5ZmJlNDAzYmQ3NjgyM2NiZGI2NmEwYzg=
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.11.0 (August 16th)
4
+
5
+ * Restore ruby 1.8 compatibility (@s01ipsist, @patrickdavey)
6
+ * Fix Rabl::Tracker to match paths with numbers (@szimek)
7
+ * Fix caching of a recursive template (@bonobos)
8
+ * Fix cache for non-rails apps (@t-k)
9
+ * Escape output all at once to properly escape content (@bholzer)
10
+ * Add hashie mash to known object list (@nguyenmighty)
11
+ * Remove root object when set to false value (@mrThe)
12
+
3
13
  ## 0.10.1 (May 28th)
4
14
 
5
15
  * Fix nasty formatting bug that broke XML (@bhicks)
data/Gemfile CHANGED
@@ -20,6 +20,7 @@ group :test do
20
20
  gem 'activerecord', :require => 'active_record'
21
21
  gem 'sqlite3'
22
22
  gem 'sinatra', '>= 1.2.0'
23
+ gem 'hashie'
23
24
  end
24
25
 
25
26
  group :development, :test do
data/README.md CHANGED
@@ -171,7 +171,6 @@ Additionally, anything within child, glue and partial will also be cached separa
171
171
  To cache just a single template, see the section titled 'Caching' below.
172
172
 
173
173
  If `escape_all_output` is set to `true` and ActiveSupport is available, attribute output will be escaped using [ERB::Util.html_escape](http://corelib.rubyonrails.org/classes/ERB/Util.html).
174
- Custom nodes will not be escaped, use `ERB::Util.h(value)`.
175
174
 
176
175
  If `view_paths` is set to a path, this view path will be checked for every rabl template within your application.
177
176
  Add to this path especially when including Rabl in an engine and using view paths within a another Rails app.
@@ -16,6 +16,9 @@ Dir[File.dirname(__FILE__) + "/models/*.rb"].each do |file|
16
16
  end
17
17
 
18
18
  # Register RABL
19
+ Rabl.configure do |config|
20
+ config.perform_caching = true
21
+ end
19
22
  Rabl.register!
20
23
 
21
24
  class SinatraTest < Sinatra::Application
data/lib/rabl/digestor.rb CHANGED
@@ -2,11 +2,11 @@ module Rabl
2
2
  class Digestor < ActionView::Digestor
3
3
  # Override the original digest function to ignore partial which
4
4
  # rabl doesn't use the Rails conventional _ symbol.
5
- if Rails.version.to_s >= '4.1'
5
+ if Gem::Version.new(Rails.version) >= Gem::Version.new('4.1')
6
6
  def self.digest(options = {})
7
7
  cache_key = [options[:name]] + Array.wrap(options[:dependencies])
8
8
  @@cache[cache_key.join('.')] ||= begin
9
- Digestor.new({ name: options[:name], finder: options[:finder] }.merge!(options)).digest
9
+ Digestor.new({ :name => options[:name], :finder => options[:finder] }.merge!(options)).digest
10
10
  end
11
11
  end
12
12
  else
@@ -20,9 +20,9 @@ module Rabl
20
20
 
21
21
  private
22
22
  def dependency_digest
23
- template_digests = dependencies.collect do |template_name|
24
- if Rails.version.to_s >= '4.1'
25
- Digestor.digest(name: template_name, finder: finder)
23
+ template_digests = (dependencies - [template.virtual_path]).collect do |template_name|
24
+ if Gem::Version.new(Rails.version) >= Gem::Version.new('4.1')
25
+ Digestor.digest(:name => template_name, :finder => finder)
26
26
  else
27
27
  Digestor.digest(template_name, format, finder)
28
28
  end
data/lib/rabl/engine.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  module Rabl
2
2
  class Engine
3
3
  include Rabl::Partials
4
+ include Rabl::Helpers::Escaper
4
5
 
5
6
  # List of supported rendering formats
6
7
  FORMATS = [:json, :xml, :plist, :bson, :msgpack]
@@ -35,12 +36,12 @@ module Rabl
35
36
  options[:root_name] = determine_object_root(data, root_name, options[:root])
36
37
 
37
38
  if is_object?(data) || !data # object @user
38
- builder.build(data, options)
39
+ result = builder.build(data, options)
39
40
  elsif is_collection?(data) # collection @users
40
41
  result = data.map { |object| builder.build(object, options) }
41
42
  result = result.map(&:presence).compact if Rabl.configuration.exclude_empty_values_in_collections
42
- result
43
43
  end
44
+ Rabl.configuration.escape_all_output ? escape_output(result) : result
44
45
  end
45
46
 
46
47
  # Returns a json representation of the data object
@@ -109,6 +110,10 @@ module Rabl
109
110
  current_data = (@_locals[:object].nil? || template_data == false) ? template_data : @_locals[:object]
110
111
  @_data_object = data_object(current_data)
111
112
  @_data_name = data_name(template_data.is_a?(Hash) && !current_data.is_a?(Hash) ? template_data : current_data)
113
+ if @_data_name == false
114
+ @_object_root_name = false
115
+ @_collection_name = false
116
+ end
112
117
  end
113
118
 
114
119
  # Returns the current object that is the topic of this template
@@ -277,10 +282,10 @@ module Rabl
277
282
  _cache = @_cache if defined?(@_cache)
278
283
  cache_key, cache_options = *_cache || nil
279
284
  if template_cache_configured? && cache_key
280
- if Rails.version =~ /^[4]/
281
- result_cache_key = cache_key_with_digest(cache_key)
282
- else # fallback for Rails 3
283
- result_cache_key = cache_key_simple(cache_key)
285
+ result_cache_key = if digestor_available?
286
+ cache_key_with_digest(cache_key)
287
+ else # fallback for Rails 3, and Non-Rails app
288
+ cache_key_simple(cache_key)
284
289
  end
285
290
  fetch_result_from_cache(result_cache_key, cache_options, &block)
286
291
  else # skip caching
@@ -288,11 +293,15 @@ module Rabl
288
293
  end
289
294
  end
290
295
 
296
+ def digestor_available?
297
+ defined?(Rails) && Rails.version =~ /^[4]/
298
+ end
299
+
291
300
  def cache_key_with_digest(cache_key)
292
301
  template = @_options[:template] || @virtual_path
293
302
 
294
- if Rails.version.to_s >= '4.1'
295
- digested = Digestor.digest(name: template, finder: lookup_context)
303
+ if Gem::Version.new(Rails.version) >= Gem::Version.new('4.1')
304
+ digested = Digestor.digest(:name => template, :finder => lookup_context)
296
305
  else
297
306
  digested = Digestor.digest(template, :rabl, lookup_context)
298
307
  end
data/lib/rabl/helpers.rb CHANGED
@@ -3,7 +3,7 @@ require 'active_support/inflector' # for the sake of pluralizing
3
3
  module Rabl
4
4
  module Helpers
5
5
  # Set of class names known to be objects, not collections
6
- KNOWN_OBJECT_CLASSES = ['Struct']
6
+ KNOWN_OBJECT_CLASSES = ['Struct', 'Hashie::Mash']
7
7
 
8
8
  # data_object(data) => <AR Object>
9
9
  # data_object(@user => :person) => @user
@@ -15,7 +15,7 @@ module Rabl
15
15
 
16
16
  # data_object_attribute(data) => @_object.send(data)
17
17
  def data_object_attribute(data)
18
- escape_output @_object.__send__(data)
18
+ @_object.__send__(data)
19
19
  end
20
20
 
21
21
  # data_name(data) => "user"
@@ -119,10 +119,28 @@ module Rabl
119
119
  end
120
120
  end
121
121
 
122
- # Escape output if configured and supported
123
- def escape_output(data)
124
- (data && defined?(ERB::Util.h) && Rabl.configuration.escape_all_output) ? ERB::Util.h(data) : data
125
- end
122
+ module Escaper
123
+ def escape_output(response)
124
+ case response
125
+ when Hash
126
+ response.each{|k,v| response[k] = escape_value(v) }
127
+ when Array
128
+ response.map!{|v| escape_value(v) }
129
+ else
130
+ response
131
+ end
132
+ end
126
133
 
134
+ def escape_value(value)
135
+ case value
136
+ when String
137
+ ERB::Util.h(value)
138
+ when Array, Hash
139
+ escape_output(value)
140
+ else
141
+ value
142
+ end
143
+ end
144
+ end
127
145
  end
128
146
  end
data/lib/rabl/tracker.rb CHANGED
@@ -6,7 +6,7 @@ module Rabl
6
6
  EXTENDS_DEPENDENCY = /
7
7
  extends\s* # extends, followed by optional whitespace
8
8
  \(? # start an optional parenthesis for the extends call
9
- \s*["']([a-z_\/\.]+) # the template name itself
9
+ \s*["']([0-9a-z_\/\.]+) # the template name itself
10
10
  /x
11
11
 
12
12
  # Matches:
@@ -14,7 +14,7 @@ module Rabl
14
14
  PARTIAL_DEPENDENCY = /
15
15
  partial\s* # partial, followed by optional whitespace
16
16
  \(? # start an optional parenthesis for the partial call
17
- \s*["']([a-z_\/\.]+) # the template name itself
17
+ \s*["']([0-9a-z_\/\.]+) # the template name itself
18
18
  /x
19
19
 
20
20
  def self.call(name, template)
data/lib/rabl/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rabl
2
- VERSION = "0.10.1"
2
+ VERSION = "0.11.0"
3
3
  end
data/test/engine_test.rb CHANGED
@@ -37,7 +37,7 @@ context "Rabl::Engine" do
37
37
 
38
38
  context "with a specified format" do
39
39
  setup do
40
- template = RablTemplate.new("code", format: 'xml') { "" }
40
+ template = RablTemplate.new("code", :format => 'xml') { "" }
41
41
  template.render(Object.new)
42
42
  engine = template.instance_eval('@engine')
43
43
  engine.instance_eval('@_options')[:format]
@@ -132,6 +132,26 @@ context "Rabl::Engine" do
132
132
  template.render(scope)
133
133
  end.equals "{\"person\":{}}"
134
134
 
135
+ asserts "that it can set false root node" do
136
+ template = rabl %q{
137
+ object @user => false
138
+ }
139
+ scope = Object.new
140
+ scope.instance_variable_set :@user, User.new
141
+ template.render(scope)
142
+ end.equals "{}"
143
+
144
+ asserts "that it can set false root node and correctly render object without root node" do
145
+ template = rabl %q{
146
+ object @user => false
147
+ attribute :name
148
+ }
149
+ user = User.new(:name => "John Doe")
150
+ scope = Object.new
151
+ scope.instance_variable_set :@user, user
152
+ template.render(scope)
153
+ end.equals "{\"name\":\"John Doe\"}"
154
+
135
155
  asserts "that it can use non-ORM objects" do
136
156
  template = rabl %q{
137
157
  object @other
data/test/helpers_test.rb CHANGED
@@ -85,6 +85,11 @@ context "Rabl::Helpers" do
85
85
  @helper_class.is_object?(obj.new('foo'))
86
86
  end.equals(true)
87
87
 
88
+ asserts "returns true for a Hashie::Mash" do
89
+ obj = Hashie::Mash.new({:name => 'hello'})
90
+ @helper_class.is_object?(obj)
91
+ end.equals(true)
92
+
88
93
  asserts "returns false for an array" do
89
94
  @helper_class.is_object?([@user])
90
95
  end.equals(false)
@@ -116,5 +121,10 @@ context "Rabl::Helpers" do
116
121
  asserts "returns true for an array" do
117
122
  @helper_class.is_collection?([@user])
118
123
  end.equals(true)
124
+
125
+ asserts "returns true for an array" do
126
+ obj = Hashie::Mash.new({:name => 'hello'})
127
+ @helper_class.is_collection?(obj)
128
+ end.equals(false)
119
129
  end # is_collection method
120
130
  end
data/test/teststrap.rb CHANGED
@@ -18,6 +18,7 @@ silence_warnings do
18
18
  require 'riot/rr'
19
19
  require 'tilt'
20
20
  require 'rabl'
21
+ require 'hashie'
21
22
  require File.expand_path('../models/user', __FILE__)
22
23
  end
23
24
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rabl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.1
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Esquenazi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-29 00:00:00.000000000 Z
11
+ date: 2014-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport