jbuilder 2.2.16 → 2.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 79566456f0f777b15fdab405ea286da70467e78c
4
- data.tar.gz: 73ac0f91316aea81448cca1e2d414d4b1c20fde4
3
+ metadata.gz: 19f9ffc0fdffc27e1b5d6a807700fe17a1f69fc5
4
+ data.tar.gz: 276ff03b94f8abf7b1b73d7518821132024edd87
5
5
  SHA512:
6
- metadata.gz: cef291a3f61cd86b1f36bbf171dcea06bc4388cb23cde5a309cf4c9217d6dad9b3641b6d3cc2994fcee3b6b21018763a53d0d3358d938570b1e5b274f356dafd
7
- data.tar.gz: 4b4e043b1b7a029bebecf8f90bc9f9fb46c5ed6be43e0cdefca0711ef292302651b126ae6c033f02c15c715c7f65a0f86c3bb1248375083cf0e09dd117bb639f
6
+ metadata.gz: b7683720c91b74da8edea9469e11ed401007fe5e8351c290e6e0c68bd4ef9f4332db841744ae4500990423f1c88ffec2b24093a36576cb500ce4164f895b1c28
7
+ data.tar.gz: 8ea62fd1c6b86e5156bcb63b88384c4441866d0c49f2430968514936a9f890ee32efdc151e2b1779c0f20bbb3c6eb56439acd3487b9140e9a1e4756d0714cff6
@@ -16,6 +16,7 @@ gemfile:
16
16
  - gemfiles/rails_4_0.gemfile
17
17
  - gemfiles/rails_4_1.gemfile
18
18
  - gemfiles/rails_4_2.gemfile
19
+ - gemfiles/rails_edge.gemfile
19
20
 
20
21
  matrix:
21
22
  allow_failures:
@@ -23,6 +24,17 @@ matrix:
23
24
  - rvm: rbx
24
25
  - rvm: ruby-head
25
26
  fast_finish: true
27
+ exclude:
28
+ - rvm: 1.9
29
+ gemfile: gemfiles/rails_edge.gemfile
30
+ - rvm: 2.0
31
+ gemfile: gemfiles/rails_edge.gemfile
32
+ - rvm: 2.1
33
+ gemfile: gemfiles/rails_edge.gemfile
34
+ - rvm: jruby-19mode
35
+ gemfile: gemfiles/rails_edge.gemfile
36
+ - rvm: rbx
37
+ gemfile: gemfiles/rails_edge.gemfile
26
38
 
27
39
  notifications:
28
40
  email: false
data/Appraisals CHANGED
@@ -1,32 +1,43 @@
1
1
  appraise "rails-3-0" do
2
2
  gem "test-unit"
3
- gem "railties", "~> 3.0.0"
4
- gem "actionpack", "~> 3.0.0"
3
+ gem "railties", "~> 3.0.0"
4
+ gem "actionpack", "~> 3.0.0"
5
+ gem "activemodel", "~> 3.0.0"
5
6
  end
6
7
 
7
8
  appraise "rails-3-1" do
8
9
  gem "test-unit"
9
- gem "railties", "~> 3.1.0"
10
- gem "actionpack", "~> 3.1.0"
10
+ gem "railties", "~> 3.1.0"
11
+ gem "actionpack", "~> 3.1.0"
12
+ gem "activemodel", "~> 3.1.0"
11
13
  end
12
14
 
13
15
  appraise "rails-3-2" do
14
16
  gem "test-unit"
15
- gem "railties", "~> 3.2.0"
16
- gem "actionpack", "~> 3.2.0"
17
+ gem "railties", "~> 3.2.0"
18
+ gem "actionpack", "~> 3.2.0"
19
+ gem "activemodel", "~> 3.2.0"
17
20
  end
18
21
 
19
22
  appraise "rails-4-0" do
20
- gem "railties", "~> 4.0.0"
21
- gem "actionpack", "~> 4.0.0"
23
+ gem "railties", "~> 4.0.0"
24
+ gem "actionpack", "~> 4.0.0"
25
+ gem "activemodel", "~> 4.0.0"
22
26
  end
23
27
 
24
28
  appraise "rails-4-1" do
25
- gem "railties", "~> 4.1.0"
26
- gem "actionpack", "~> 4.1.0"
29
+ gem "railties", "~> 4.1.0"
30
+ gem "actionpack", "~> 4.1.0"
31
+ gem "activemodel", "~> 4.1.0"
27
32
  end
28
33
 
29
34
  appraise "rails-4-2" do
30
- gem "railties", "~> 4.2.0"
31
- gem "actionpack", "~> 4.2.0"
35
+ gem "railties", "~> 4.2.0"
36
+ gem "actionpack", "~> 4.2.0"
37
+ gem "activemodel", "~> 4.2.0"
38
+ end
39
+
40
+ appraise "rails-edge" do
41
+ gem "rails", github: "rails/rails"
42
+ gem "arel", github: "rails/arel"
32
43
  end
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ 2.3.0
4
+ -----
5
+
6
+ * [Add new in-place partial invocation support](https://github.com/rails/jbuilder/commit/1feda7ee605c136e59fb4de970f4674de518e6de)
7
+ * [Add implicit partial rendering for AM::Models](https://github.com/rails/jbuilder/commit/4d5bf7d0ea92765adb7be36834e84f9855a061df)
8
+ * [Generate API controller if Rails API option is enabled](https://github.com/rails/jbuilder/commit/db68f6bd327cf42b47ef22d455fb5721a8c2cf5f)
9
+ * [JBuilder's templates have less priority than app templates](https://github.com/rails/jbuilder/commit/7c1a5f25603ec1f4e51fba3dbba9db23726a5d69)
10
+ * [Add AC::Helpers module to jbuilder for api only apps](https://github.com/rails/jbuilder/commit/7cf1d1eb7d125caf38309b5427952030011c1aa0)
11
+
3
12
  2.2.16
4
13
  ------
5
14
 
data/Gemfile CHANGED
@@ -5,3 +5,4 @@ gemspec
5
5
  gem "rake"
6
6
  gem "mocha", require: false
7
7
  gem "appraisal"
8
+ gem "pry"
@@ -5,8 +5,10 @@ source "https://rubygems.org"
5
5
  gem "rake"
6
6
  gem "mocha", :require => false
7
7
  gem "appraisal"
8
+ gem "pry"
8
9
  gem "test-unit"
9
10
  gem "railties", "~> 3.0.0"
10
11
  gem "actionpack", "~> 3.0.0"
12
+ gem "activemodel", "~> 3.0.0"
11
13
 
12
14
  gemspec :path => "../"
@@ -5,8 +5,10 @@ source "https://rubygems.org"
5
5
  gem "rake"
6
6
  gem "mocha", :require => false
7
7
  gem "appraisal"
8
+ gem "pry"
8
9
  gem "test-unit"
9
10
  gem "railties", "~> 3.1.0"
10
11
  gem "actionpack", "~> 3.1.0"
12
+ gem "activemodel", "~> 3.1.0"
11
13
 
12
14
  gemspec :path => "../"
@@ -5,8 +5,10 @@ source "https://rubygems.org"
5
5
  gem "rake"
6
6
  gem "mocha", :require => false
7
7
  gem "appraisal"
8
+ gem "pry"
8
9
  gem "test-unit"
9
10
  gem "railties", "~> 3.2.0"
10
11
  gem "actionpack", "~> 3.2.0"
12
+ gem "activemodel", "~> 3.2.0"
11
13
 
12
14
  gemspec :path => "../"
@@ -5,7 +5,9 @@ source "https://rubygems.org"
5
5
  gem "rake"
6
6
  gem "mocha", :require => false
7
7
  gem "appraisal"
8
+ gem "pry"
8
9
  gem "railties", "~> 4.0.0"
9
10
  gem "actionpack", "~> 4.0.0"
11
+ gem "activemodel", "~> 4.0.0"
10
12
 
11
13
  gemspec :path => "../"
@@ -5,7 +5,9 @@ source "https://rubygems.org"
5
5
  gem "rake"
6
6
  gem "mocha", :require => false
7
7
  gem "appraisal"
8
+ gem "pry"
8
9
  gem "railties", "~> 4.1.0"
9
10
  gem "actionpack", "~> 4.1.0"
11
+ gem "activemodel", "~> 4.1.0"
10
12
 
11
13
  gemspec :path => "../"
@@ -5,7 +5,9 @@ source "https://rubygems.org"
5
5
  gem "rake"
6
6
  gem "mocha", :require => false
7
7
  gem "appraisal"
8
+ gem "pry"
8
9
  gem "railties", "~> 4.2.0"
9
10
  gem "actionpack", "~> 4.2.0"
11
+ gem "activemodel", "~> 4.2.0"
10
12
 
11
13
  gemspec :path => "../"
@@ -0,0 +1,11 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake"
6
+ gem "mocha", :require => false
7
+ gem "appraisal"
8
+ gem "rails", :github => "rails/rails"
9
+ gem "arel", :github => "rails/arel"
10
+
11
+ gemspec :path => "../"
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'jbuilder'
3
- s.version = '2.2.16'
3
+ s.version = '2.3.0'
4
4
  s.authors = ['David Heinemeier Hansson', 'Pavel Pravosud']
5
5
  s.email = ['david@37signals.com', 'pavel@pravosud.com']
6
6
  s.summary = 'Create JSON structures via a Builder-style DSL'
@@ -4,7 +4,7 @@ require 'rails/generators/rails/scaffold_controller/scaffold_controller_generato
4
4
  module Rails
5
5
  module Generators
6
6
  class ScaffoldControllerGenerator
7
- source_paths.unshift File.expand_path('../templates', __FILE__)
7
+ source_paths << File.expand_path('../templates', __FILE__)
8
8
 
9
9
  hook_for :jbuilder, default: true
10
10
  end
@@ -0,0 +1,63 @@
1
+ <% if namespaced? -%>
2
+ require_dependency "<%= namespaced_file_path %>/application_controller"
3
+
4
+ <% end -%>
5
+ <% module_namespacing do -%>
6
+ class <%= controller_class_name %>Controller < ApplicationController
7
+ before_action :set_<%= singular_table_name %>, only: [:show, :update, :destroy]
8
+
9
+ # GET <%= route_url %>
10
+ # GET <%= route_url %>.json
11
+ def index
12
+ @<%= plural_table_name %> = <%= orm_class.all(class_name) %>
13
+ end
14
+
15
+ # GET <%= route_url %>/1
16
+ # GET <%= route_url %>/1.json
17
+ def show
18
+ end
19
+
20
+ # POST <%= route_url %>
21
+ # POST <%= route_url %>.json
22
+ def create
23
+ @<%= singular_table_name %> = <%= orm_class.build(class_name, "#{singular_table_name}_params") %>
24
+
25
+ if @<%= orm_instance.save %>
26
+ render :show, status: :created, location: <%= "@#{singular_table_name}" %>
27
+ else
28
+ render json: <%= "@#{orm_instance.errors}" %>, status: :unprocessable_entity
29
+ end
30
+ end
31
+
32
+ # PATCH/PUT <%= route_url %>/1
33
+ # PATCH/PUT <%= route_url %>/1.json
34
+ def update
35
+ if @<%= orm_instance.update("#{singular_table_name}_params") %>
36
+ render :show, status: :ok, location: <%= "@#{singular_table_name}" %>
37
+ else
38
+ render json: <%= "@#{orm_instance.errors}" %>, status: :unprocessable_entity
39
+ end
40
+ end
41
+
42
+ # DELETE <%= route_url %>/1
43
+ # DELETE <%= route_url %>/1.json
44
+ def destroy
45
+ @<%= orm_instance.destroy %>
46
+ end
47
+
48
+ private
49
+ # Use callbacks to share common setup or constraints between actions.
50
+ def set_<%= singular_table_name %>
51
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
52
+ end
53
+
54
+ # Never trust parameters from the scary internet, only allow the white list through.
55
+ def <%= "#{singular_table_name}_params" %>
56
+ <%- if attributes_names.empty? -%>
57
+ params[<%= ":#{singular_table_name}" %>]
58
+ <%- else -%>
59
+ params.require(<%= ":#{singular_table_name}" %>).permit(<%= attributes_names.map { |name| ":#{name}" }.join(', ') %>)
60
+ <%- end -%>
61
+ end
62
+ end
63
+ <% end -%>
@@ -23,6 +23,7 @@ class Jbuilder
23
23
  end
24
24
 
25
25
  BLANK = Blank.new
26
+ NON_ENUMERABLES = [ ::Struct, ::OpenStruct ].to_set
26
27
 
27
28
  def set!(key, value = BLANK, *args)
28
29
  result = if ::Kernel.block_given?
@@ -46,7 +47,7 @@ class Jbuilder
46
47
  # { "age": 32 }
47
48
  value
48
49
  end
49
- elsif _mapable_arguments?(value, *args)
50
+ elsif _is_collection?(value)
50
51
  # json.comments @post.comments, :content, :created_at
51
52
  # { "comments": [ { "content": "hello", "created_at": "..." }, { "content": "world", "created_at": "..." } ] }
52
53
  _scope{ array! value, *args }
@@ -59,8 +60,13 @@ class Jbuilder
59
60
  _set_value key, result
60
61
  end
61
62
 
62
- alias_method :method_missing, :set!
63
- private :method_missing
63
+ def method_missing(*args)
64
+ if ::Kernel.block_given?
65
+ set! *args, &::Proc.new
66
+ else
67
+ set! *args
68
+ end
69
+ end
64
70
 
65
71
  # Specifies formatting to be applied to the key. Passing in a name of a function
66
72
  # will cause that function to be called on the key. So :upcase will upper case
@@ -301,13 +307,17 @@ class Jbuilder
301
307
  @attributes, @key_formatter = parent_attributes, parent_formatter
302
308
  end
303
309
 
304
- def _mapable_arguments?(value, *args)
305
- value.respond_to?(:map)
310
+ def _is_collection?(object)
311
+ _object_respond_to?(object, :map, :count) && NON_ENUMERABLES.none?{ |klass| klass === object }
306
312
  end
307
313
 
308
314
  def _blank?(value=@attributes)
309
315
  BLANK == value
310
316
  end
317
+
318
+ def _object_respond_to?(object, *methods)
319
+ methods.all?{ |m| object.respond_to?(m) }
320
+ end
311
321
  end
312
322
 
313
323
  require 'jbuilder/railtie' if defined?(Rails)
@@ -11,37 +11,14 @@ class JbuilderTemplate < Jbuilder
11
11
 
12
12
  def initialize(context, *args)
13
13
  @context = context
14
- super(*args)
14
+ super *args
15
15
  end
16
16
 
17
- def partial!(name_or_options, locals = {})
18
- case name_or_options
19
- when ::Hash
20
- # partial! partial: 'name', foo: 'bar'
21
- options = name_or_options
17
+ def partial!(*args)
18
+ if args.one? && _is_active_model?(args.first)
19
+ _render_active_model_partial args.first
22
20
  else
23
- # partial! 'name', locals: {foo: 'bar'}
24
- if locals.one? && (locals.keys.first == :locals)
25
- options = locals.merge(partial: name_or_options)
26
- else
27
- options = { partial: name_or_options, locals: locals }
28
- end
29
- # partial! 'name', foo: 'bar'
30
- as = locals.delete(:as)
31
- options[:as] = as if as.present?
32
- options[:collection] = locals[:collection] if locals.key?(:collection)
33
- end
34
-
35
- _render_partial_with_options options
36
- end
37
-
38
- def array!(collection = [], *attributes)
39
- options = attributes.extract_options!
40
-
41
- if options.key?(:partial)
42
- partial! options[:partial], options.merge(collection: collection)
43
- else
44
- super
21
+ _render_explicit_partial *args
45
22
  end
46
23
  end
47
24
 
@@ -78,7 +55,27 @@ class JbuilderTemplate < Jbuilder
78
55
  condition ? cache!(*args, &::Proc.new) : yield
79
56
  end
80
57
 
81
- protected
58
+ def array!(collection = [], *args)
59
+ options = args.first
60
+
61
+ if args.one? && _partial_options?(options)
62
+ partial! options.merge(collection: collection)
63
+ else
64
+ super
65
+ end
66
+ end
67
+
68
+ def set!(name, object = BLANK, *args)
69
+ options = args.first
70
+
71
+ if args.one? && _partial_options?(options)
72
+ _set_inline_partial name, object, options
73
+ else
74
+ super
75
+ end
76
+ end
77
+
78
+ private
82
79
 
83
80
  def _render_partial_with_options(options)
84
81
  options.reverse_merge! locals: {}
@@ -111,8 +108,6 @@ class JbuilderTemplate < Jbuilder
111
108
  ::ActiveSupport::Cache.expand_cache_key(key, :jbuilder)
112
109
  end
113
110
 
114
- private
115
-
116
111
  def _fragment_name_with_digest(key, options)
117
112
  if @context.respond_to?(:cache_fragment_name)
118
113
  # Current compatibility, fragment_name_with_digest is private again and cache_fragment_name
@@ -126,10 +121,50 @@ class JbuilderTemplate < Jbuilder
126
121
  end
127
122
  end
128
123
 
129
- def _mapable_arguments?(value, *args)
130
- return true if super
131
- options = args.last
132
- ::Hash === options && options.key?(:as)
124
+ def _partial_options?(options)
125
+ ::Hash === options && options.key?(:as) && options.key?(:partial)
126
+ end
127
+
128
+ def _is_active_model?(object)
129
+ object.class.respond_to?(:model_name) && object.respond_to?(:to_partial_path)
130
+ end
131
+
132
+ def _set_inline_partial(name, object, options)
133
+ value = if object.nil?
134
+ []
135
+ elsif _is_collection?(object)
136
+ _scope{ _render_partial_with_options options.merge(collection: object) }
137
+ else
138
+ locals = ::Hash[options[:as], object]
139
+ _scope{ _render_partial options.merge(locals: locals) }
140
+ end
141
+
142
+ set! name, value
143
+ end
144
+
145
+ def _render_explicit_partial(name_or_options, locals = {})
146
+ case name_or_options
147
+ when ::Hash
148
+ # partial! partial: 'name', foo: 'bar'
149
+ options = name_or_options
150
+ else
151
+ # partial! 'name', locals: {foo: 'bar'}
152
+ if locals.one? && (locals.keys.first == :locals)
153
+ options = locals.merge(partial: name_or_options)
154
+ else
155
+ options = { partial: name_or_options, locals: locals }
156
+ end
157
+ # partial! 'name', foo: 'bar'
158
+ as = locals.delete(:as)
159
+ options[:as] = as if as.present?
160
+ options[:collection] = locals[:collection] if locals.key?(:collection)
161
+ end
162
+
163
+ _render_partial_with_options options
164
+ end
165
+
166
+ def _render_active_model_partial(object)
167
+ @context.render object, json: self
133
168
  end
134
169
  end
135
170
 
@@ -12,6 +12,8 @@ class Jbuilder
12
12
  if app.config.respond_to?(:api_only) && app.config.api_only
13
13
  ActiveSupport.on_load :action_controller do
14
14
  include ActionView::Rendering
15
+ include ActionController::Helpers
16
+ include ActionController::ImplicitRender
15
17
  end
16
18
  end
17
19
  end
@@ -1,16 +1,17 @@
1
- require 'test_helper'
2
- require 'mocha/setup'
3
- require 'action_view'
4
- require 'action_view/testing/resolvers'
5
- require 'active_support/cache'
6
- require 'jbuilder/jbuilder_template'
1
+ require "test_helper"
2
+ require "mocha/setup"
3
+ require "active_model"
4
+ require "action_view"
5
+ require "action_view/testing/resolvers"
6
+ require "active_support/cache"
7
+ require "jbuilder/jbuilder_template"
7
8
 
8
9
  BLOG_POST_PARTIAL = <<-JBUILDER
9
10
  json.extract! blog_post, :id, :body
10
11
  json.author do
11
- name = blog_post.author_name.split(nil, 2)
12
- json.first_name name[0]
13
- json.last_name name[1]
12
+ first_name, last_name = blog_post.author_name.split(nil, 2)
13
+ json.first_name first_name
14
+ json.last_name last_name
14
15
  end
15
16
  JBUILDER
16
17
 
@@ -18,14 +19,37 @@ COLLECTION_PARTIAL = <<-JBUILDER
18
19
  json.extract! collection, :id, :name
19
20
  JBUILDER
20
21
 
22
+ RACER_PARTIAL = <<-JBUILDER
23
+ json.extract! racer, :id, :name
24
+ JBUILDER
25
+
26
+ class Racer
27
+ extend ActiveModel::Naming
28
+ include ActiveModel::Conversion
29
+
30
+ def initialize(id, name)
31
+ @id, @name = id, name
32
+ end
33
+
34
+ attr_reader :id, :name
35
+ end
36
+
37
+
21
38
  BlogPost = Struct.new(:id, :body, :author_name)
22
39
  Collection = Struct.new(:id, :name)
23
- blog_authors = [ 'David Heinemeier Hansson', 'Pavel Pravosud' ].cycle
24
- BLOG_POST_COLLECTION = 10.times.map{ |i| BlogPost.new(i+1, "post body #{i+1}", blog_authors.next) }
25
- COLLECTION_COLLECTION = 5.times.map{ |i| Collection.new(i+1, "collection #{i+1}") }
40
+ blog_authors = [ "David Heinemeier Hansson", "Pavel Pravosud" ].cycle
41
+ BLOG_POST_COLLECTION = Array.new(10){ |i| BlogPost.new(i+1, "post body #{i+1}", blog_authors.next) }
42
+ COLLECTION_COLLECTION = Array.new(5){ |i| Collection.new(i+1, "collection #{i+1}") }
26
43
 
27
44
  ActionView::Template.register_template_handler :jbuilder, JbuilderHandler
28
45
 
46
+ PARTIALS = {
47
+ "_partial.json.jbuilder" => "foo ||= 'hello'; json.content foo",
48
+ "_blog_post.json.jbuilder" => BLOG_POST_PARTIAL,
49
+ "racers/_racer.json.jbuilder" => RACER_PARTIAL,
50
+ "_collection.json.jbuilder" => COLLECTION_PARTIAL
51
+ }
52
+
29
53
  module Rails
30
54
  def self.cache
31
55
  @cache ||= ActiveSupport::Cache::MemoryStore.new
@@ -38,18 +62,15 @@ class JbuilderTemplateTest < ActionView::TestCase
38
62
  Rails.cache.clear
39
63
  end
40
64
 
41
- def partials
42
- {
43
- '_partial.json.jbuilder' => 'foo ||= "hello"; json.content foo',
44
- '_blog_post.json.jbuilder' => BLOG_POST_PARTIAL,
45
- '_collection.json.jbuilder' => COLLECTION_PARTIAL
46
- }
47
- end
48
-
49
- def render_jbuilder(source)
65
+ def jbuild(source)
50
66
  @rendered = []
51
- lookup_context.view_paths = [ActionView::FixtureResolver.new(partials.merge('test.json.jbuilder' => source))]
52
- ActionView::Template.new(source, 'test', JbuilderHandler, :virtual_path => 'test').render(self, {}).strip
67
+ partials = PARTIALS.clone
68
+ partials["test.json.jbuilder"] = source
69
+ resolver = ActionView::FixtureResolver.new(partials)
70
+ lookup_context.view_paths = [resolver]
71
+ template = ActionView::Template.new(source, "test", JbuilderHandler, virtual_path: "test")
72
+ json = template.render(self, {}).strip
73
+ MultiJson.load(json)
53
74
  end
54
75
 
55
76
  def undef_context_methods(*names)
@@ -60,284 +81,303 @@ class JbuilderTemplateTest < ActionView::TestCase
60
81
  end
61
82
  end
62
83
 
63
- def assert_collection_rendered(json, context = nil)
64
- result = MultiJson.load(json)
84
+ def assert_collection_rendered(result, context = nil)
65
85
  result = result.fetch(context) if context
66
86
 
67
87
  assert_equal 10, result.length
68
88
  assert_equal Array, result.class
69
- assert_equal 'post body 5', result[4]['body']
70
- assert_equal 'Heinemeier Hansson', result[2]['author']['last_name']
71
- assert_equal 'Pavel', result[5]['author']['first_name']
89
+ assert_equal "post body 5", result[4]["body"]
90
+ assert_equal "Heinemeier Hansson", result[2]["author"]["last_name"]
91
+ assert_equal "Pavel", result[5]["author"]["first_name"]
72
92
  end
73
93
 
74
- test 'rendering' do
75
- json = render_jbuilder <<-JBUILDER
76
- json.content 'hello'
94
+ test "rendering" do
95
+ result = jbuild(<<-JBUILDER)
96
+ json.content "hello"
77
97
  JBUILDER
78
98
 
79
- assert_equal 'hello', MultiJson.load(json)['content']
99
+ assert_equal "hello", result["content"]
80
100
  end
81
101
 
82
- test 'key_format! with parameter' do
83
- json = render_jbuilder <<-JBUILDER
84
- json.key_format! :camelize => [:lower]
85
- json.camel_style 'for JS'
102
+ test "key_format! with parameter" do
103
+ result = jbuild(<<-JBUILDER)
104
+ json.key_format! camelize: [:lower]
105
+ json.camel_style "for JS"
86
106
  JBUILDER
87
107
 
88
- assert_equal ['camelStyle'], MultiJson.load(json).keys
108
+ assert_equal ["camelStyle"], result.keys
89
109
  end
90
110
 
91
- test 'key_format! propagates to child elements' do
92
- json = render_jbuilder <<-JBUILDER
111
+ test "key_format! propagates to child elements" do
112
+ result = jbuild(<<-JBUILDER)
93
113
  json.key_format! :upcase
94
- json.level1 'one'
114
+ json.level1 "one"
95
115
  json.level2 do
96
- json.value 'two'
116
+ json.value "two"
97
117
  end
98
118
  JBUILDER
99
119
 
100
- result = MultiJson.load(json)
101
- assert_equal 'one', result['LEVEL1']
102
- assert_equal 'two', result['LEVEL2']['VALUE']
120
+ assert_equal "one", result["LEVEL1"]
121
+ assert_equal "two", result["LEVEL2"]["VALUE"]
103
122
  end
104
123
 
105
- test 'partial! renders partial' do
106
- json = render_jbuilder <<-JBUILDER
107
- json.partial! 'partial'
124
+ test "partial! renders partial" do
125
+ result = jbuild(<<-JBUILDER)
126
+ json.partial! "partial"
108
127
  JBUILDER
109
128
 
110
- assert_equal 'hello', MultiJson.load(json)['content']
129
+ assert_equal "hello", result["content"]
111
130
  end
112
131
 
113
- test 'partial! + locals via :locals option' do
114
- json = render_jbuilder <<-JBUILDER
115
- json.partial! 'partial', locals: { foo: 'howdy' }
132
+ test "partial! + locals via :locals option" do
133
+ result = jbuild(<<-JBUILDER)
134
+ json.partial! "partial", locals: { foo: "howdy" }
116
135
  JBUILDER
117
136
 
118
- assert_equal 'howdy', MultiJson.load(json)['content']
137
+ assert_equal "howdy", result["content"]
119
138
  end
120
139
 
121
- test 'partial! + locals without :locals key' do
122
- json = render_jbuilder <<-JBUILDER
123
- json.partial! 'partial', foo: 'goodbye'
140
+ test "partial! + locals without :locals key" do
141
+ result = jbuild(<<-JBUILDER)
142
+ json.partial! "partial", foo: "goodbye"
124
143
  JBUILDER
125
144
 
126
- assert_equal 'goodbye', MultiJson.load(json)['content']
145
+ assert_equal "goodbye", result["content"]
127
146
  end
128
147
 
129
- test 'partial! renders collections' do
130
- json = render_jbuilder <<-JBUILDER
131
- json.partial! 'blog_post', :collection => BLOG_POST_COLLECTION, :as => :blog_post
148
+ test "partial! renders collections" do
149
+ result = jbuild(<<-JBUILDER)
150
+ json.partial! "blog_post", collection: BLOG_POST_COLLECTION, as: :blog_post
132
151
  JBUILDER
133
152
 
134
- assert_collection_rendered json
153
+ assert_collection_rendered result
135
154
  end
136
155
 
137
- test 'partial! renders collections when as argument is a string' do
138
- json = render_jbuilder <<-JBUILDER
139
- json.partial! 'blog_post', collection: BLOG_POST_COLLECTION, as: "blog_post"
156
+ test "partial! renders collections when as argument is a string" do
157
+ result = jbuild(<<-JBUILDER)
158
+ json.partial! "blog_post", collection: BLOG_POST_COLLECTION, as: "blog_post"
140
159
  JBUILDER
141
160
 
142
- assert_collection_rendered json
161
+ assert_collection_rendered result
143
162
  end
144
163
 
145
- test 'partial! renders collections as collections' do
146
- json = render_jbuilder <<-JBUILDER
147
- json.partial! 'collection', collection: COLLECTION_COLLECTION, as: :collection
164
+ test "partial! renders collections as collections" do
165
+ result = jbuild(<<-JBUILDER)
166
+ json.partial! "collection", collection: COLLECTION_COLLECTION, as: :collection
148
167
  JBUILDER
149
168
 
150
- assert_equal 5, MultiJson.load(json).length
169
+ assert_equal 5, result.length
151
170
  end
152
171
 
153
- test 'partial! renders as empty array for nil-collection' do
154
- json = render_jbuilder <<-JBUILDER
155
- json.partial! 'blog_post', :collection => nil, :as => :blog_post
172
+ test "partial! renders as empty array for nil-collection" do
173
+ result = jbuild(<<-JBUILDER)
174
+ json.partial! "blog_post", collection: nil, as: :blog_post
156
175
  JBUILDER
157
176
 
158
- assert_equal '[]', json
177
+ assert_equal [], result
159
178
  end
160
179
 
161
- test 'partial! renders collection (alt. syntax)' do
162
- json = render_jbuilder <<-JBUILDER
163
- json.partial! :partial => 'blog_post', :collection => BLOG_POST_COLLECTION, :as => :blog_post
180
+ test "partial! renders collection (alt. syntax)" do
181
+ result = jbuild(<<-JBUILDER)
182
+ json.partial! partial: "blog_post", collection: BLOG_POST_COLLECTION, as: :blog_post
164
183
  JBUILDER
165
184
 
166
- assert_collection_rendered json
185
+ assert_collection_rendered result
167
186
  end
168
187
 
169
- test 'partial! renders as empty array for nil-collection (alt. syntax)' do
170
- json = render_jbuilder <<-JBUILDER
171
- json.partial! :partial => 'blog_post', :collection => nil, :as => :blog_post
188
+ test "partial! renders as empty array for nil-collection (alt. syntax)" do
189
+ result = jbuild(<<-JBUILDER)
190
+ json.partial! partial: "blog_post", collection: nil, as: :blog_post
172
191
  JBUILDER
173
192
 
174
- assert_equal '[]', json
193
+ assert_equal [], result
175
194
  end
176
195
 
177
- test 'render array of partials' do
178
- json = render_jbuilder <<-JBUILDER
179
- json.array! BLOG_POST_COLLECTION, :partial => 'blog_post', :as => :blog_post
196
+ test "render array of partials" do
197
+ result = jbuild(<<-JBUILDER)
198
+ json.array! BLOG_POST_COLLECTION, partial: "blog_post", as: :blog_post
180
199
  JBUILDER
181
200
 
182
- assert_collection_rendered json
201
+ assert_collection_rendered result
183
202
  end
184
203
 
185
- test 'render array of partials as empty array with nil-collection' do
186
- json = render_jbuilder <<-JBUILDER
187
- json.array! nil, :partial => 'blog_post', :as => :blog_post
204
+ test "render array of partials as empty array with nil-collection" do
205
+ result = jbuild(<<-JBUILDER)
206
+ json.array! nil, partial: "blog_post", as: :blog_post
188
207
  JBUILDER
189
208
 
190
- assert_equal '[]', json
209
+ assert_equal [], result
191
210
  end
192
211
 
193
- test 'render array if partials as a value' do
194
- json = render_jbuilder <<-JBUILDER
195
- json.posts BLOG_POST_COLLECTION, :partial => 'blog_post', :as => :blog_post
212
+ test "render array of partials as a value" do
213
+ result = jbuild(<<-JBUILDER)
214
+ json.posts BLOG_POST_COLLECTION, partial: "blog_post", as: :blog_post
196
215
  JBUILDER
197
216
 
198
- assert_collection_rendered json, 'posts'
217
+ assert_collection_rendered result, "posts"
199
218
  end
200
219
 
201
- test 'render as empty array if partials as a nil value' do
202
- json = render_jbuilder <<-JBUILDER
203
- json.posts nil, :partial => 'blog_post', :as => :blog_post
220
+ test "render as empty array if partials as a nil value" do
221
+ result = jbuild <<-JBUILDER
222
+ json.posts nil, partial: "blog_post", as: :blog_post
204
223
  JBUILDER
205
224
 
206
- assert_equal '{"posts":[]}', json
225
+ assert_equal [], result["posts"]
207
226
  end
208
227
 
209
- test 'cache an empty block' do
228
+ test "cache an empty block" do
210
229
  undef_context_methods :fragment_name_with_digest, :cache_fragment_name
211
230
 
212
- render_jbuilder <<-JBUILDER
213
- json.cache! 'nothing' do
231
+ jbuild <<-JBUILDER
232
+ json.cache! "nothing" do
214
233
  end
215
234
  JBUILDER
216
235
 
217
- json = nil
236
+ result = nil
218
237
 
219
238
  assert_nothing_raised do
220
- json = render_jbuilder <<-JBUILDER
221
- json.foo 'bar'
222
- json.cache! 'nothing' do
239
+ result = jbuild(<<-JBUILDER)
240
+ json.foo "bar"
241
+ json.cache! "nothing" do
223
242
  end
224
243
  JBUILDER
225
244
  end
226
245
 
227
- assert_equal 'bar', MultiJson.load(json)['foo']
246
+ assert_equal "bar", result["foo"]
228
247
  end
229
248
 
230
- test 'fragment caching a JSON object' do
249
+ test "fragment caching a JSON object" do
231
250
  undef_context_methods :fragment_name_with_digest, :cache_fragment_name
232
251
 
233
- render_jbuilder <<-JBUILDER
234
- json.cache! 'cachekey' do
235
- json.name 'Cache'
252
+ jbuild <<-JBUILDER
253
+ json.cache! "cachekey" do
254
+ json.name "Cache"
236
255
  end
237
256
  JBUILDER
238
257
 
239
- json = render_jbuilder <<-JBUILDER
240
- json.cache! 'cachekey' do
241
- json.name 'Miss'
258
+ result = jbuild(<<-JBUILDER)
259
+ json.cache! "cachekey" do
260
+ json.name "Miss"
242
261
  end
243
262
  JBUILDER
244
263
 
245
- parsed = MultiJson.load(json)
246
- assert_equal 'Cache', parsed['name']
264
+ assert_equal "Cache", result["name"]
247
265
  end
248
266
 
249
- test 'conditionally fragment caching a JSON object' do
267
+ test "conditionally fragment caching a JSON object" do
250
268
  undef_context_methods :fragment_name_with_digest, :cache_fragment_name
251
269
 
252
- render_jbuilder <<-JBUILDER
253
- json.cache_if! true, 'cachekey' do
254
- json.test1 'Cache'
270
+ jbuild <<-JBUILDER
271
+ json.cache_if! true, "cachekey" do
272
+ json.test1 "Cache"
255
273
  end
256
- json.cache_if! false, 'cachekey' do
257
- json.test2 'Cache'
274
+ json.cache_if! false, "cachekey" do
275
+ json.test2 "Cache"
258
276
  end
259
277
  JBUILDER
260
278
 
261
- json = render_jbuilder <<-JBUILDER
262
- json.cache_if! true, 'cachekey' do
263
- json.test1 'Miss'
279
+ result = jbuild(<<-JBUILDER)
280
+ json.cache_if! true, "cachekey" do
281
+ json.test1 "Miss"
264
282
  end
265
- json.cache_if! false, 'cachekey' do
266
- json.test2 'Miss'
283
+ json.cache_if! false, "cachekey" do
284
+ json.test2 "Miss"
267
285
  end
268
286
  JBUILDER
269
287
 
270
- parsed = MultiJson.load(json)
271
- assert_equal 'Cache', parsed['test1']
272
- assert_equal 'Miss', parsed['test2']
288
+ assert_equal "Cache", result["test1"]
289
+ assert_equal "Miss", result["test2"]
273
290
  end
274
291
 
275
- test 'fragment caching deserializes an array' do
292
+ test "fragment caching deserializes an array" do
276
293
  undef_context_methods :fragment_name_with_digest, :cache_fragment_name
277
294
 
278
- render_jbuilder <<-JBUILDER
279
- json.cache! 'cachekey' do
295
+ jbuild <<-JBUILDER
296
+ json.cache! "cachekey" do
280
297
  json.array! %w[a b c]
281
298
  end
282
299
  JBUILDER
283
300
 
284
- json = render_jbuilder <<-JBUILDER
285
- json.cache! 'cachekey' do
301
+ result = jbuild(<<-JBUILDER)
302
+ json.cache! "cachekey" do
286
303
  json.array! %w[1 2 3]
287
304
  end
288
305
  JBUILDER
289
306
 
290
- parsed = MultiJson.load(json)
291
- assert_equal %w[a b c], parsed
307
+ assert_equal %w[a b c], result
292
308
  end
293
309
 
294
- test 'fragment caching works with previous version of cache digests' do
310
+ test "fragment caching works with previous version of cache digests" do
295
311
  undef_context_methods :cache_fragment_name
296
312
 
297
313
  @context.expects :fragment_name_with_digest
298
314
 
299
- render_jbuilder <<-JBUILDER
300
- json.cache! 'cachekey' do
301
- json.name 'Cache'
315
+ jbuild <<-JBUILDER
316
+ json.cache! "cachekey" do
317
+ json.name "Cache"
302
318
  end
303
319
  JBUILDER
304
320
  end
305
321
 
306
- test 'fragment caching works with current cache digests' do
322
+ test "fragment caching works with current cache digests" do
307
323
  undef_context_methods :fragment_name_with_digest
308
324
 
309
325
  @context.expects :cache_fragment_name
310
326
  ActiveSupport::Cache.expects :expand_cache_key
311
327
 
312
- render_jbuilder <<-JBUILDER
313
- json.cache! 'cachekey' do
314
- json.name 'Cache'
328
+ jbuild <<-JBUILDER
329
+ json.cache! "cachekey" do
330
+ json.name "Cache"
315
331
  end
316
332
  JBUILDER
317
333
  end
318
334
 
319
- test 'current cache digest option accepts options' do
335
+ test "current cache digest option accepts options" do
320
336
  undef_context_methods :fragment_name_with_digest
321
337
 
322
- @context.expects(:cache_fragment_name).with('cachekey', skip_digest: true)
338
+ @context.expects(:cache_fragment_name).with("cachekey", skip_digest: true)
323
339
  ActiveSupport::Cache.expects :expand_cache_key
324
340
 
325
- render_jbuilder <<-JBUILDER
326
- json.cache! 'cachekey', skip_digest: true do
327
- json.name 'Cache'
341
+ jbuild <<-JBUILDER
342
+ json.cache! "cachekey", skip_digest: true do
343
+ json.name "Cache"
328
344
  end
329
345
  JBUILDER
330
346
  end
331
347
 
332
- test 'does not perform caching when controller.perform_caching is false' do
348
+ test "does not perform caching when controller.perform_caching is false" do
333
349
  controller.perform_caching = false
334
- render_jbuilder <<-JBUILDER
335
- json.cache! 'cachekey' do
336
- json.name 'Cache'
350
+
351
+ jbuild <<-JBUILDER
352
+ json.cache! "cachekey" do
353
+ json.name "Cache"
337
354
  end
338
355
  JBUILDER
339
356
 
340
- assert_equal Rails.cache.inspect[/entries=(\d+)/, 1], '0'
357
+ assert_equal Rails.cache.inspect[/entries=(\d+)/, 1], "0"
358
+ end
359
+
360
+ test "invokes templates via params via set!" do
361
+ @post = BLOG_POST_COLLECTION.first
362
+
363
+ result = jbuild(<<-JBUILDER)
364
+ json.post @post, partial: "blog_post", as: :blog_post
365
+ JBUILDER
366
+
367
+ assert_equal 1, result["post"]["id"]
368
+ assert_equal "post body 1", result["post"]["body"]
369
+ assert_equal "David", result["post"]["author"]["first_name"]
341
370
  end
342
371
 
372
+ test "invokes templates implicitly for ActiveModel objects" do
373
+ @racer = Racer.new(123, "Chris Harris")
374
+
375
+ result = jbuild(<<-JBUILDER)
376
+ json.partial! @racer
377
+ JBUILDER
378
+
379
+ assert_equal %w[id name], result.keys
380
+ assert_equal 123, result["id"]
381
+ assert_equal "Chris Harris", result["name"]
382
+ end
343
383
  end
@@ -13,9 +13,7 @@ class NonEnumerable
13
13
  @collection = collection
14
14
  end
15
15
 
16
- def map(&block)
17
- @collection.map(&block)
18
- end
16
+ delegate :map, :count, to: :@collection
19
17
  end
20
18
 
21
19
  class VeryBasicWrapper < BasicObject
@@ -0,0 +1,46 @@
1
+ require 'test_helper'
2
+ require 'rails/generators/test_case'
3
+ require 'generators/rails/scaffold_controller_generator'
4
+
5
+ if Rails::VERSION::MAJOR > 4
6
+
7
+ class ScaffoldApiControllerGeneratorTest < Rails::Generators::TestCase
8
+ tests Rails::Generators::ScaffoldControllerGenerator
9
+ arguments %w(Post title body:text --api)
10
+ destination File.expand_path('../tmp', __FILE__)
11
+ setup :prepare_destination
12
+
13
+ test 'controller content' do
14
+ run_generator
15
+
16
+ assert_file 'app/controllers/posts_controller.rb' do |content|
17
+ assert_instance_method :index, content do |m|
18
+ assert_match /@posts = Post\.all/, m
19
+ end
20
+
21
+ assert_instance_method :show, content do |m|
22
+ assert m.blank?
23
+ end
24
+
25
+ assert_instance_method :create, content do |m|
26
+ assert_match /@post = Post\.new\(post_params\)/, m
27
+ assert_match /@post\.save/, m
28
+ assert_match /render :show, status: :created, location: @post/, m
29
+ assert_match /render json: @post\.errors, status: :unprocessable_entity/, m
30
+ end
31
+
32
+ assert_instance_method :update, content do |m|
33
+ assert_match /render :show, status: :ok, location: @post/, m
34
+ assert_match /render json: @post.errors, status: :unprocessable_entity/, m
35
+ end
36
+
37
+ assert_instance_method :destroy, content do |m|
38
+ assert_match /@post\.destroy/, m
39
+ end
40
+
41
+ assert_match(/def post_params/, content)
42
+ assert_match(/params\.require\(:post\)\.permit\(:title, :body\)/, content)
43
+ end
44
+ end
45
+ end
46
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jbuilder
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.16
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-05-18 00:00:00.000000000 Z
12
+ date: 2015-06-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -67,9 +67,11 @@ files:
67
67
  - gemfiles/rails_4_0.gemfile
68
68
  - gemfiles/rails_4_1.gemfile
69
69
  - gemfiles/rails_4_2.gemfile
70
+ - gemfiles/rails_edge.gemfile
70
71
  - jbuilder.gemspec
71
72
  - lib/generators/rails/jbuilder_generator.rb
72
73
  - lib/generators/rails/scaffold_controller_generator.rb
74
+ - lib/generators/rails/templates/api_controller.rb
73
75
  - lib/generators/rails/templates/controller.rb
74
76
  - lib/generators/rails/templates/index.json.jbuilder
75
77
  - lib/generators/rails/templates/show.json.jbuilder
@@ -85,6 +87,7 @@ files:
85
87
  - test/jbuilder_generator_test.rb
86
88
  - test/jbuilder_template_test.rb
87
89
  - test/jbuilder_test.rb
90
+ - test/scaffold_api_controller_generator_test.rb
88
91
  - test/scaffold_controller_generator_test.rb
89
92
  - test/test_helper.rb
90
93
  homepage: https://github.com/rails/jbuilder
@@ -116,5 +119,6 @@ test_files:
116
119
  - test/jbuilder_generator_test.rb
117
120
  - test/jbuilder_template_test.rb
118
121
  - test/jbuilder_test.rb
122
+ - test/scaffold_api_controller_generator_test.rb
119
123
  - test/scaffold_controller_generator_test.rb
120
124
  - test/test_helper.rb