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 +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
|