jbuilder 2.2.16 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
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