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 +4 -4
- data/.travis.yml +12 -0
- data/Appraisals +23 -12
- data/CHANGELOG.md +9 -0
- data/Gemfile +1 -0
- data/gemfiles/rails_3_0.gemfile +2 -0
- data/gemfiles/rails_3_1.gemfile +2 -0
- data/gemfiles/rails_3_2.gemfile +2 -0
- data/gemfiles/rails_4_0.gemfile +2 -0
- data/gemfiles/rails_4_1.gemfile +2 -0
- data/gemfiles/rails_4_2.gemfile +2 -0
- data/gemfiles/rails_edge.gemfile +11 -0
- data/jbuilder.gemspec +1 -1
- data/lib/generators/rails/scaffold_controller_generator.rb +1 -1
- data/lib/generators/rails/templates/api_controller.rb +63 -0
- data/lib/jbuilder.rb +15 -5
- data/lib/jbuilder/jbuilder_template.rb +70 -35
- data/lib/jbuilder/railtie.rb +2 -0
- data/test/jbuilder_template_test.rb +192 -152
- data/test/jbuilder_test.rb +1 -3
- data/test/scaffold_api_controller_generator_test.rb +46 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 19f9ffc0fdffc27e1b5d6a807700fe17a1f69fc5
|
4
|
+
data.tar.gz: 276ff03b94f8abf7b1b73d7518821132024edd87
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b7683720c91b74da8edea9469e11ed401007fe5e8351c290e6e0c68bd4ef9f4332db841744ae4500990423f1c88ffec2b24093a36576cb500ce4164f895b1c28
|
7
|
+
data.tar.gz: 8ea62fd1c6b86e5156bcb63b88384c4441866d0c49f2430968514936a9f890ee32efdc151e2b1779c0f20bbb3c6eb56439acd3487b9140e9a1e4756d0714cff6
|
data/.travis.yml
CHANGED
@@ -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",
|
4
|
-
gem "actionpack",
|
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",
|
10
|
-
gem "actionpack",
|
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",
|
16
|
-
gem "actionpack",
|
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",
|
21
|
-
gem "actionpack",
|
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",
|
26
|
-
gem "actionpack",
|
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",
|
31
|
-
gem "actionpack",
|
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
|
data/CHANGELOG.md
CHANGED
@@ -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
data/gemfiles/rails_3_0.gemfile
CHANGED
data/gemfiles/rails_3_1.gemfile
CHANGED
data/gemfiles/rails_3_2.gemfile
CHANGED
data/gemfiles/rails_4_0.gemfile
CHANGED
data/gemfiles/rails_4_1.gemfile
CHANGED
data/gemfiles/rails_4_2.gemfile
CHANGED
data/jbuilder.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'jbuilder'
|
3
|
-
s.version = '2.
|
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
|
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 -%>
|
data/lib/jbuilder.rb
CHANGED
@@ -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
|
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
|
-
|
63
|
-
|
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
|
305
|
-
|
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
|
14
|
+
super *args
|
15
15
|
end
|
16
16
|
|
17
|
-
def partial!(
|
18
|
-
|
19
|
-
|
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
|
-
|
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
|
-
|
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
|
130
|
-
|
131
|
-
|
132
|
-
|
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
|
|
data/lib/jbuilder/railtie.rb
CHANGED
@@ -1,16 +1,17 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
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
|
-
|
12
|
-
json.first_name
|
13
|
-
json.last_name
|
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 = [
|
24
|
-
BLOG_POST_COLLECTION = 10
|
25
|
-
COLLECTION_COLLECTION = 5
|
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
|
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
|
-
|
52
|
-
|
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(
|
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
|
70
|
-
assert_equal
|
71
|
-
assert_equal
|
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
|
75
|
-
|
76
|
-
json.content
|
94
|
+
test "rendering" do
|
95
|
+
result = jbuild(<<-JBUILDER)
|
96
|
+
json.content "hello"
|
77
97
|
JBUILDER
|
78
98
|
|
79
|
-
assert_equal
|
99
|
+
assert_equal "hello", result["content"]
|
80
100
|
end
|
81
101
|
|
82
|
-
test
|
83
|
-
|
84
|
-
json.key_format! :
|
85
|
-
json.camel_style
|
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 [
|
108
|
+
assert_equal ["camelStyle"], result.keys
|
89
109
|
end
|
90
110
|
|
91
|
-
test
|
92
|
-
|
111
|
+
test "key_format! propagates to child elements" do
|
112
|
+
result = jbuild(<<-JBUILDER)
|
93
113
|
json.key_format! :upcase
|
94
|
-
json.level1
|
114
|
+
json.level1 "one"
|
95
115
|
json.level2 do
|
96
|
-
json.value
|
116
|
+
json.value "two"
|
97
117
|
end
|
98
118
|
JBUILDER
|
99
119
|
|
100
|
-
|
101
|
-
assert_equal
|
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
|
106
|
-
|
107
|
-
json.partial!
|
124
|
+
test "partial! renders partial" do
|
125
|
+
result = jbuild(<<-JBUILDER)
|
126
|
+
json.partial! "partial"
|
108
127
|
JBUILDER
|
109
128
|
|
110
|
-
assert_equal
|
129
|
+
assert_equal "hello", result["content"]
|
111
130
|
end
|
112
131
|
|
113
|
-
test
|
114
|
-
|
115
|
-
json.partial!
|
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
|
137
|
+
assert_equal "howdy", result["content"]
|
119
138
|
end
|
120
139
|
|
121
|
-
test
|
122
|
-
|
123
|
-
json.partial!
|
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
|
145
|
+
assert_equal "goodbye", result["content"]
|
127
146
|
end
|
128
147
|
|
129
|
-
test
|
130
|
-
|
131
|
-
json.partial!
|
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
|
153
|
+
assert_collection_rendered result
|
135
154
|
end
|
136
155
|
|
137
|
-
test
|
138
|
-
|
139
|
-
json.partial!
|
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
|
161
|
+
assert_collection_rendered result
|
143
162
|
end
|
144
163
|
|
145
|
-
test
|
146
|
-
|
147
|
-
json.partial!
|
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,
|
169
|
+
assert_equal 5, result.length
|
151
170
|
end
|
152
171
|
|
153
|
-
test
|
154
|
-
|
155
|
-
json.partial!
|
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
|
177
|
+
assert_equal [], result
|
159
178
|
end
|
160
179
|
|
161
|
-
test
|
162
|
-
|
163
|
-
json.partial! :
|
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
|
185
|
+
assert_collection_rendered result
|
167
186
|
end
|
168
187
|
|
169
|
-
test
|
170
|
-
|
171
|
-
json.partial! :
|
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
|
193
|
+
assert_equal [], result
|
175
194
|
end
|
176
195
|
|
177
|
-
test
|
178
|
-
|
179
|
-
json.array! BLOG_POST_COLLECTION, :
|
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
|
201
|
+
assert_collection_rendered result
|
183
202
|
end
|
184
203
|
|
185
|
-
test
|
186
|
-
|
187
|
-
json.array! nil, :
|
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
|
209
|
+
assert_equal [], result
|
191
210
|
end
|
192
211
|
|
193
|
-
test
|
194
|
-
|
195
|
-
json.posts BLOG_POST_COLLECTION, :
|
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
|
217
|
+
assert_collection_rendered result, "posts"
|
199
218
|
end
|
200
219
|
|
201
|
-
test
|
202
|
-
|
203
|
-
json.posts nil, :
|
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
|
225
|
+
assert_equal [], result["posts"]
|
207
226
|
end
|
208
227
|
|
209
|
-
test
|
228
|
+
test "cache an empty block" do
|
210
229
|
undef_context_methods :fragment_name_with_digest, :cache_fragment_name
|
211
230
|
|
212
|
-
|
213
|
-
json.cache!
|
231
|
+
jbuild <<-JBUILDER
|
232
|
+
json.cache! "nothing" do
|
214
233
|
end
|
215
234
|
JBUILDER
|
216
235
|
|
217
|
-
|
236
|
+
result = nil
|
218
237
|
|
219
238
|
assert_nothing_raised do
|
220
|
-
|
221
|
-
json.foo
|
222
|
-
json.cache!
|
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
|
246
|
+
assert_equal "bar", result["foo"]
|
228
247
|
end
|
229
248
|
|
230
|
-
test
|
249
|
+
test "fragment caching a JSON object" do
|
231
250
|
undef_context_methods :fragment_name_with_digest, :cache_fragment_name
|
232
251
|
|
233
|
-
|
234
|
-
json.cache!
|
235
|
-
json.name
|
252
|
+
jbuild <<-JBUILDER
|
253
|
+
json.cache! "cachekey" do
|
254
|
+
json.name "Cache"
|
236
255
|
end
|
237
256
|
JBUILDER
|
238
257
|
|
239
|
-
|
240
|
-
json.cache!
|
241
|
-
json.name
|
258
|
+
result = jbuild(<<-JBUILDER)
|
259
|
+
json.cache! "cachekey" do
|
260
|
+
json.name "Miss"
|
242
261
|
end
|
243
262
|
JBUILDER
|
244
263
|
|
245
|
-
|
246
|
-
assert_equal 'Cache', parsed['name']
|
264
|
+
assert_equal "Cache", result["name"]
|
247
265
|
end
|
248
266
|
|
249
|
-
test
|
267
|
+
test "conditionally fragment caching a JSON object" do
|
250
268
|
undef_context_methods :fragment_name_with_digest, :cache_fragment_name
|
251
269
|
|
252
|
-
|
253
|
-
json.cache_if! true,
|
254
|
-
json.test1
|
270
|
+
jbuild <<-JBUILDER
|
271
|
+
json.cache_if! true, "cachekey" do
|
272
|
+
json.test1 "Cache"
|
255
273
|
end
|
256
|
-
json.cache_if! false,
|
257
|
-
json.test2
|
274
|
+
json.cache_if! false, "cachekey" do
|
275
|
+
json.test2 "Cache"
|
258
276
|
end
|
259
277
|
JBUILDER
|
260
278
|
|
261
|
-
|
262
|
-
json.cache_if! true,
|
263
|
-
json.test1
|
279
|
+
result = jbuild(<<-JBUILDER)
|
280
|
+
json.cache_if! true, "cachekey" do
|
281
|
+
json.test1 "Miss"
|
264
282
|
end
|
265
|
-
json.cache_if! false,
|
266
|
-
json.test2
|
283
|
+
json.cache_if! false, "cachekey" do
|
284
|
+
json.test2 "Miss"
|
267
285
|
end
|
268
286
|
JBUILDER
|
269
287
|
|
270
|
-
|
271
|
-
assert_equal
|
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
|
292
|
+
test "fragment caching deserializes an array" do
|
276
293
|
undef_context_methods :fragment_name_with_digest, :cache_fragment_name
|
277
294
|
|
278
|
-
|
279
|
-
json.cache!
|
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
|
-
|
285
|
-
json.cache!
|
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
|
-
|
291
|
-
assert_equal %w[a b c], parsed
|
307
|
+
assert_equal %w[a b c], result
|
292
308
|
end
|
293
309
|
|
294
|
-
test
|
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
|
-
|
300
|
-
json.cache!
|
301
|
-
json.name
|
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
|
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
|
-
|
313
|
-
json.cache!
|
314
|
-
json.name
|
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
|
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(
|
338
|
+
@context.expects(:cache_fragment_name).with("cachekey", skip_digest: true)
|
323
339
|
ActiveSupport::Cache.expects :expand_cache_key
|
324
340
|
|
325
|
-
|
326
|
-
json.cache!
|
327
|
-
json.name
|
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
|
348
|
+
test "does not perform caching when controller.perform_caching is false" do
|
333
349
|
controller.perform_caching = false
|
334
|
-
|
335
|
-
|
336
|
-
|
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],
|
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
|
data/test/jbuilder_test.rb
CHANGED
@@ -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.
|
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-
|
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
|