jbuilder 2.10.0 → 2.14.1
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/.devcontainer/devcontainer.json +25 -0
- data/.github/workflows/ruby.yml +56 -0
- data/.gitignore +2 -0
- data/Appraisals +14 -13
- data/CONTRIBUTING.md +5 -13
- data/Gemfile +2 -0
- data/README.md +113 -26
- data/Rakefile +3 -1
- data/bin/release +14 -0
- data/bin/test +6 -0
- data/gemfiles/{rails_5_1.gemfile → rails_7_0.gemfile} +2 -1
- data/gemfiles/{rails_5_2.gemfile → rails_7_1.gemfile} +1 -1
- data/gemfiles/{rails_6_0.gemfile → rails_7_2.gemfile} +1 -1
- data/gemfiles/{rails_5_0.gemfile → rails_8_0.gemfile} +1 -1
- data/gemfiles/rails_head.gemfile +1 -1
- data/jbuilder.gemspec +22 -3
- data/lib/generators/rails/jbuilder_generator.rb +10 -0
- data/lib/generators/rails/scaffold_controller_generator.rb +2 -0
- data/lib/generators/rails/templates/api_controller.rb +8 -2
- data/lib/generators/rails/templates/controller.rb +19 -17
- data/lib/generators/rails/templates/index.json.jbuilder +1 -1
- data/lib/generators/rails/templates/partial.json.jbuilder +14 -0
- data/lib/generators/rails/templates/show.json.jbuilder +1 -1
- data/lib/jbuilder/blank.rb +2 -0
- data/lib/jbuilder/collection_renderer.rb +58 -0
- data/lib/jbuilder/errors.rb +3 -1
- data/lib/jbuilder/jbuilder.rb +3 -7
- data/lib/jbuilder/jbuilder_dependency_tracker.rb +75 -0
- data/lib/jbuilder/jbuilder_template.rb +82 -48
- data/lib/jbuilder/key_formatter.rb +19 -21
- data/lib/jbuilder/railtie.rb +17 -19
- data/lib/jbuilder/version.rb +5 -0
- data/lib/jbuilder.rb +96 -51
- data/test/jbuilder_dependency_tracker_test.rb +2 -3
- data/test/jbuilder_generator_test.rb +22 -0
- data/test/jbuilder_template_test.rb +133 -8
- data/test/jbuilder_test.rb +211 -9
- data/test/scaffold_api_controller_generator_test.rb +63 -47
- data/test/scaffold_controller_generator_test.rb +47 -11
- data/test/test_helper.rb +24 -11
- metadata +37 -18
- data/.travis.yml +0 -47
- data/CHANGELOG.md +0 -283
- data/lib/jbuilder/dependency_tracker.rb +0 -61
data/test/jbuilder_test.rb
CHANGED
|
@@ -196,6 +196,18 @@ class JbuilderTest < ActiveSupport::TestCase
|
|
|
196
196
|
assert_equal 'Pavel', result['author']['name']
|
|
197
197
|
end
|
|
198
198
|
|
|
199
|
+
test 'support merge! method with Jbuilder instance' do
|
|
200
|
+
obj = jbuild do |json|
|
|
201
|
+
json.foo 'bar'
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
result = jbuild do |json|
|
|
205
|
+
json.merge! obj
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
assert_equal 'bar', result['foo']
|
|
209
|
+
end
|
|
210
|
+
|
|
199
211
|
test 'blocks are additive via extract syntax' do
|
|
200
212
|
person = Person.new('Pavel', 27)
|
|
201
213
|
|
|
@@ -300,7 +312,7 @@ class JbuilderTest < ActiveSupport::TestCase
|
|
|
300
312
|
assert_equal 'world', result['comments'].second['content']
|
|
301
313
|
end
|
|
302
314
|
|
|
303
|
-
test 'nesting multiple
|
|
315
|
+
test 'nesting multiple children from a non-Enumerable that responds to #map with inline loop' do
|
|
304
316
|
comments = NonEnumerable.new([ Comment.new('hello', 1), Comment.new('world', 2) ])
|
|
305
317
|
|
|
306
318
|
result = jbuild do |json|
|
|
@@ -554,6 +566,36 @@ class JbuilderTest < ActiveSupport::TestCase
|
|
|
554
566
|
assert_equal 'one', result['level1']
|
|
555
567
|
end
|
|
556
568
|
|
|
569
|
+
test 'key_format! can be changed in child elements' do
|
|
570
|
+
result = jbuild do |json|
|
|
571
|
+
json.key_format! camelize: :lower
|
|
572
|
+
|
|
573
|
+
json.level_one do
|
|
574
|
+
json.key_format! :upcase
|
|
575
|
+
json.value 'two'
|
|
576
|
+
end
|
|
577
|
+
end
|
|
578
|
+
|
|
579
|
+
assert_equal ['levelOne'], result.keys
|
|
580
|
+
assert_equal ['VALUE'], result['levelOne'].keys
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
test 'key_format! can be changed in array!' do
|
|
584
|
+
result = jbuild do |json|
|
|
585
|
+
json.key_format! camelize: :lower
|
|
586
|
+
|
|
587
|
+
json.level_one do
|
|
588
|
+
json.array! [{value: 'two'}] do |object|
|
|
589
|
+
json.key_format! :upcase
|
|
590
|
+
json.value object[:value]
|
|
591
|
+
end
|
|
592
|
+
end
|
|
593
|
+
end
|
|
594
|
+
|
|
595
|
+
assert_equal ['levelOne'], result.keys
|
|
596
|
+
assert_equal ['VALUE'], result['levelOne'][0].keys
|
|
597
|
+
end
|
|
598
|
+
|
|
557
599
|
test 'key_format! with no parameter' do
|
|
558
600
|
result = jbuild do |json|
|
|
559
601
|
json.key_format! :upcase
|
|
@@ -581,18 +623,173 @@ class JbuilderTest < ActiveSupport::TestCase
|
|
|
581
623
|
assert_equal ['oats and friends'], result.keys
|
|
582
624
|
end
|
|
583
625
|
|
|
626
|
+
test 'key_format! is not applied deeply by default' do
|
|
627
|
+
names = { first_name: 'camel', last_name: 'case' }
|
|
628
|
+
result = jbuild do |json|
|
|
629
|
+
json.key_format! camelize: :lower
|
|
630
|
+
json.set! :all_names, names
|
|
631
|
+
end
|
|
632
|
+
|
|
633
|
+
assert_equal %i[first_name last_name], result['allNames'].keys
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
test 'applying key_format! deeply can be enabled per scope' do
|
|
637
|
+
names = { first_name: 'camel', last_name: 'case' }
|
|
638
|
+
result = jbuild do |json|
|
|
639
|
+
json.key_format! camelize: :lower
|
|
640
|
+
json.scope do
|
|
641
|
+
json.deep_format_keys!
|
|
642
|
+
json.set! :all_names, names
|
|
643
|
+
end
|
|
644
|
+
json.set! :all_names, names
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
assert_equal %w[firstName lastName], result['scope']['allNames'].keys
|
|
648
|
+
assert_equal %i[first_name last_name], result['allNames'].keys
|
|
649
|
+
end
|
|
650
|
+
|
|
651
|
+
test 'applying key_format! deeply can be disabled per scope' do
|
|
652
|
+
names = { first_name: 'camel', last_name: 'case' }
|
|
653
|
+
result = jbuild do |json|
|
|
654
|
+
json.key_format! camelize: :lower
|
|
655
|
+
json.deep_format_keys!
|
|
656
|
+
json.set! :all_names, names
|
|
657
|
+
json.scope do
|
|
658
|
+
json.deep_format_keys! false
|
|
659
|
+
json.set! :all_names, names
|
|
660
|
+
end
|
|
661
|
+
end
|
|
662
|
+
|
|
663
|
+
assert_equal %w[firstName lastName], result['allNames'].keys
|
|
664
|
+
assert_equal %i[first_name last_name], result['scope']['allNames'].keys
|
|
665
|
+
end
|
|
666
|
+
|
|
667
|
+
test 'applying key_format! deeply can be enabled globally' do
|
|
668
|
+
names = { first_name: 'camel', last_name: 'case' }
|
|
669
|
+
|
|
670
|
+
Jbuilder.deep_format_keys true
|
|
671
|
+
result = jbuild do |json|
|
|
672
|
+
json.key_format! camelize: :lower
|
|
673
|
+
json.set! :all_names, names
|
|
674
|
+
end
|
|
675
|
+
|
|
676
|
+
assert_equal %w[firstName lastName], result['allNames'].keys
|
|
677
|
+
Jbuilder.send(:class_variable_set, '@@deep_format_keys', false)
|
|
678
|
+
end
|
|
679
|
+
|
|
680
|
+
test 'deep key_format! with merge!' do
|
|
681
|
+
hash = { camel_style: 'for JS' }
|
|
682
|
+
result = jbuild do |json|
|
|
683
|
+
json.key_format! camelize: :lower
|
|
684
|
+
json.deep_format_keys!
|
|
685
|
+
json.merge! hash
|
|
686
|
+
end
|
|
687
|
+
|
|
688
|
+
assert_equal ['camelStyle'], result.keys
|
|
689
|
+
end
|
|
690
|
+
|
|
691
|
+
test 'deep key_format! with merge! deep' do
|
|
692
|
+
hash = { camel_style: { sub_attr: 'for JS' } }
|
|
693
|
+
result = jbuild do |json|
|
|
694
|
+
json.key_format! camelize: :lower
|
|
695
|
+
json.deep_format_keys!
|
|
696
|
+
json.merge! hash
|
|
697
|
+
end
|
|
698
|
+
|
|
699
|
+
assert_equal ['subAttr'], result['camelStyle'].keys
|
|
700
|
+
end
|
|
701
|
+
|
|
702
|
+
test 'deep key_format! with set! array of hashes' do
|
|
703
|
+
names = [{ first_name: 'camel', last_name: 'case' }]
|
|
704
|
+
result = jbuild do |json|
|
|
705
|
+
json.key_format! camelize: :lower
|
|
706
|
+
json.deep_format_keys!
|
|
707
|
+
json.set! :names, names
|
|
708
|
+
end
|
|
709
|
+
|
|
710
|
+
assert_equal %w[firstName lastName], result['names'][0].keys
|
|
711
|
+
end
|
|
712
|
+
|
|
713
|
+
test 'deep key_format! with set! extracting hash from object' do
|
|
714
|
+
comment = Struct.new(:author).new({ first_name: 'camel', last_name: 'case' })
|
|
715
|
+
result = jbuild do |json|
|
|
716
|
+
json.key_format! camelize: :lower
|
|
717
|
+
json.deep_format_keys!
|
|
718
|
+
json.set! :comment, comment, :author
|
|
719
|
+
end
|
|
720
|
+
|
|
721
|
+
assert_equal %w[firstName lastName], result['comment']['author'].keys
|
|
722
|
+
end
|
|
723
|
+
|
|
724
|
+
test 'deep key_format! with array! of hashes' do
|
|
725
|
+
names = [{ first_name: 'camel', last_name: 'case' }]
|
|
726
|
+
result = jbuild do |json|
|
|
727
|
+
json.key_format! camelize: :lower
|
|
728
|
+
json.deep_format_keys!
|
|
729
|
+
json.array! names
|
|
730
|
+
end
|
|
731
|
+
|
|
732
|
+
assert_equal %w[firstName lastName], result[0].keys
|
|
733
|
+
end
|
|
734
|
+
|
|
735
|
+
test 'deep key_format! with merge! array of hashes' do
|
|
736
|
+
names = [{ first_name: 'camel', last_name: 'case' }]
|
|
737
|
+
new_names = [{ first_name: 'snake', last_name: 'case' }]
|
|
738
|
+
result = jbuild do |json|
|
|
739
|
+
json.key_format! camelize: :lower
|
|
740
|
+
json.deep_format_keys!
|
|
741
|
+
json.array! names
|
|
742
|
+
json.merge! new_names
|
|
743
|
+
end
|
|
744
|
+
|
|
745
|
+
assert_equal %w[firstName lastName], result[1].keys
|
|
746
|
+
end
|
|
747
|
+
|
|
748
|
+
test 'deep key_format! is applied to hash extracted from object' do
|
|
749
|
+
comment = Struct.new(:author).new({ first_name: 'camel', last_name: 'case' })
|
|
750
|
+
result = jbuild do |json|
|
|
751
|
+
json.key_format! camelize: :lower
|
|
752
|
+
json.deep_format_keys!
|
|
753
|
+
json.extract! comment, :author
|
|
754
|
+
end
|
|
755
|
+
|
|
756
|
+
assert_equal %w[firstName lastName], result['author'].keys
|
|
757
|
+
end
|
|
758
|
+
|
|
759
|
+
test 'deep key_format! is applied to hash extracted from hash' do
|
|
760
|
+
comment = {author: { first_name: 'camel', last_name: 'case' }}
|
|
761
|
+
result = jbuild do |json|
|
|
762
|
+
json.key_format! camelize: :lower
|
|
763
|
+
json.deep_format_keys!
|
|
764
|
+
json.extract! comment, :author
|
|
765
|
+
end
|
|
766
|
+
|
|
767
|
+
assert_equal %w[firstName lastName], result['author'].keys
|
|
768
|
+
end
|
|
769
|
+
|
|
770
|
+
test 'deep key_format! is applied to hash extracted directly from array' do
|
|
771
|
+
comments = [Struct.new(:author).new({ first_name: 'camel', last_name: 'case' })]
|
|
772
|
+
result = jbuild do |json|
|
|
773
|
+
json.key_format! camelize: :lower
|
|
774
|
+
json.deep_format_keys!
|
|
775
|
+
json.array! comments, :author
|
|
776
|
+
end
|
|
777
|
+
|
|
778
|
+
assert_equal %w[firstName lastName], result[0]['author'].keys
|
|
779
|
+
end
|
|
780
|
+
|
|
584
781
|
test 'default key_format!' do
|
|
585
782
|
Jbuilder.key_format camelize: :lower
|
|
586
783
|
result = jbuild{ |json| json.camel_style 'for JS' }
|
|
587
784
|
assert_equal ['camelStyle'], result.keys
|
|
588
785
|
end
|
|
589
786
|
|
|
590
|
-
test '
|
|
787
|
+
test 'use default key formatter when configured' do
|
|
591
788
|
Jbuilder.key_format
|
|
592
789
|
jbuild{ |json| json.key 'value' }
|
|
593
790
|
formatter = Jbuilder.send(:class_variable_get, '@@key_formatter')
|
|
594
791
|
cache = formatter.instance_variable_get('@cache')
|
|
595
|
-
|
|
792
|
+
assert_includes cache, :key
|
|
596
793
|
end
|
|
597
794
|
|
|
598
795
|
test 'ignore_nil! without a parameter' do
|
|
@@ -733,12 +930,17 @@ class JbuilderTest < ActiveSupport::TestCase
|
|
|
733
930
|
end
|
|
734
931
|
end
|
|
735
932
|
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
933
|
+
test "respects JSON encoding customizations" do
|
|
934
|
+
# Active Support overrides Time#as_json for custom formatting.
|
|
935
|
+
# Ensure we call #to_json on the final attributes instead of JSON.dump.
|
|
936
|
+
result = JSON.load(Jbuilder.encode { |json| json.time Time.parse("2018-05-13 11:51:00.485 -0400") })
|
|
937
|
+
assert_equal "2018-05-13T11:51:00.485-04:00", result["time"]
|
|
938
|
+
end
|
|
939
|
+
|
|
940
|
+
test "encode forwards options to new" do
|
|
941
|
+
Jbuilder.encode(key_formatter: 1, ignore_nil: 2) do |json|
|
|
942
|
+
assert_equal 1, json.instance_eval{ @key_formatter }
|
|
943
|
+
assert_equal 2, json.instance_eval{ @ignore_nil }
|
|
742
944
|
end
|
|
743
945
|
end
|
|
744
946
|
end
|
|
@@ -2,57 +2,73 @@ require 'test_helper'
|
|
|
2
2
|
require 'rails/generators/test_case'
|
|
3
3
|
require 'generators/rails/scaffold_controller_generator'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
assert_match %r{
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
5
|
+
class ScaffoldApiControllerGeneratorTest < Rails::Generators::TestCase
|
|
6
|
+
tests Rails::Generators::ScaffoldControllerGenerator
|
|
7
|
+
arguments %w(Post title body:text images:attachments --api --skip-routes)
|
|
8
|
+
destination File.expand_path('../tmp', __FILE__)
|
|
9
|
+
setup :prepare_destination
|
|
10
|
+
|
|
11
|
+
test 'controller content' do
|
|
12
|
+
run_generator
|
|
13
|
+
|
|
14
|
+
assert_file 'app/controllers/posts_controller.rb' do |content|
|
|
15
|
+
assert_instance_method :index, content do |m|
|
|
16
|
+
assert_match %r{@posts = Post\.all}, m
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
assert_instance_method :show, content do |m|
|
|
20
|
+
assert m.blank?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
assert_instance_method :create, content do |m|
|
|
24
|
+
assert_match %r{@post = Post\.new\(post_params\)}, m
|
|
25
|
+
assert_match %r{@post\.save}, m
|
|
26
|
+
assert_match %r{render :show, status: :created, location: @post}, m
|
|
27
|
+
assert_match %r{render json: @post\.errors, status: :unprocessable_entity}, m
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
assert_instance_method :update, content do |m|
|
|
31
|
+
assert_match %r{render :show, status: :ok, location: @post}, m
|
|
32
|
+
assert_match %r{render json: @post.errors, status: :unprocessable_entity}, m
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
assert_instance_method :destroy, content do |m|
|
|
36
|
+
assert_match %r{@post\.destroy}, m
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
assert_match %r{def set_post}, content
|
|
40
|
+
if Rails::VERSION::MAJOR >= 8
|
|
41
|
+
assert_match %r{params\.expect\(:id\)}, content
|
|
42
|
+
else
|
|
43
|
+
assert_match %r{params\[:id\]}, content
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
assert_match %r{def post_params}, content
|
|
47
|
+
if Rails::VERSION::MAJOR >= 8
|
|
48
|
+
assert_match %r{params\.expect\(post: \[ :title, :body, images: \[\] \]\)}, content
|
|
49
|
+
else
|
|
50
|
+
assert_match %r{params\.require\(:post\)\.permit\(:title, :body, images: \[\]\)}, content
|
|
47
51
|
end
|
|
48
52
|
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
test "don't use require and permit if there are no attributes" do
|
|
56
|
+
run_generator %w(Post --api --skip-routes)
|
|
57
|
+
|
|
58
|
+
assert_file 'app/controllers/posts_controller.rb' do |content|
|
|
59
|
+
assert_match %r{def post_params}, content
|
|
60
|
+
assert_match %r{params\.fetch\(:post, \{\}\)}, content
|
|
61
|
+
end
|
|
62
|
+
end
|
|
49
63
|
|
|
50
|
-
|
|
51
|
-
|
|
64
|
+
test 'handles virtual attributes' do
|
|
65
|
+
run_generator %w(Message content:rich_text video:attachment photos:attachments --skip-routes)
|
|
52
66
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
assert_match %r{params\.
|
|
67
|
+
assert_file 'app/controllers/messages_controller.rb' do |content|
|
|
68
|
+
if Rails::VERSION::MAJOR >= 8
|
|
69
|
+
assert_match %r{params\.expect\(message: \[ :content, :video, photos: \[\] \]\)}, content
|
|
70
|
+
else
|
|
71
|
+
assert_match %r{params\.require\(:message\)\.permit\(:content, :video, photos: \[\]\)}, content
|
|
56
72
|
end
|
|
57
73
|
end
|
|
58
74
|
end
|
|
@@ -4,7 +4,7 @@ require 'generators/rails/scaffold_controller_generator'
|
|
|
4
4
|
|
|
5
5
|
class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
|
|
6
6
|
tests Rails::Generators::ScaffoldControllerGenerator
|
|
7
|
-
arguments %w(Post title body:text images:attachments)
|
|
7
|
+
arguments %w(Post title body:text images:attachments --skip-routes)
|
|
8
8
|
destination File.expand_path('../tmp', __FILE__)
|
|
9
9
|
setup :prepare_destination
|
|
10
10
|
|
|
@@ -31,40 +31,76 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
|
|
|
31
31
|
assert_instance_method :create, content do |m|
|
|
32
32
|
assert_match %r{@post = Post\.new\(post_params\)}, m
|
|
33
33
|
assert_match %r{@post\.save}, m
|
|
34
|
-
assert_match %r{format\.html \{ redirect_to @post, notice:
|
|
34
|
+
assert_match %r{format\.html \{ redirect_to @post, notice: "Post was successfully created\." \}}, m
|
|
35
35
|
assert_match %r{format\.json \{ render :show, status: :created, location: @post \}}, m
|
|
36
|
-
assert_match %r{format\.html \{ render :new \}}, m
|
|
36
|
+
assert_match %r{format\.html \{ render :new, status: :unprocessable_entity \}}, m
|
|
37
37
|
assert_match %r{format\.json \{ render json: @post\.errors, status: :unprocessable_entity \}}, m
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
assert_instance_method :update, content do |m|
|
|
41
|
-
assert_match %r{format\.html \{ redirect_to @post, notice:
|
|
41
|
+
assert_match %r{format\.html \{ redirect_to @post, notice: "Post was successfully updated\.", status: :see_other \}}, m
|
|
42
42
|
assert_match %r{format\.json \{ render :show, status: :ok, location: @post \}}, m
|
|
43
|
-
assert_match %r{format\.html \{ render :edit \}}, m
|
|
43
|
+
assert_match %r{format\.html \{ render :edit, status: :unprocessable_entity \}}, m
|
|
44
44
|
assert_match %r{format\.json \{ render json: @post.errors, status: :unprocessable_entity \}}, m
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
assert_instance_method :destroy, content do |m|
|
|
48
48
|
assert_match %r{@post\.destroy}, m
|
|
49
|
-
assert_match %r{format\.html \{ redirect_to
|
|
49
|
+
assert_match %r{format\.html \{ redirect_to posts_path, notice: "Post was successfully destroyed\.", status: :see_other \}}, m
|
|
50
50
|
assert_match %r{format\.json \{ head :no_content \}}, m
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
+
assert_match %r{def set_post}, content
|
|
54
|
+
if Rails::VERSION::MAJOR >= 8
|
|
55
|
+
assert_match %r{params\.expect\(:id\)}, content
|
|
56
|
+
else
|
|
57
|
+
assert_match %r{params\[:id\]}, content
|
|
58
|
+
end
|
|
59
|
+
|
|
53
60
|
assert_match %r{def post_params}, content
|
|
54
|
-
if Rails::VERSION::MAJOR >=
|
|
55
|
-
assert_match %r{params\.
|
|
61
|
+
if Rails::VERSION::MAJOR >= 8
|
|
62
|
+
assert_match %r{params\.expect\(post: \[ :title, :body, images: \[\] \]\)}, content
|
|
56
63
|
else
|
|
57
|
-
assert_match %r{params\.require\(:post\)\.permit\(:title, :body, :
|
|
64
|
+
assert_match %r{params\.require\(:post\)\.permit\(:title, :body, images: \[\]\)}, content
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
test 'controller with namespace' do
|
|
70
|
+
run_generator %w(Admin::Post --model-name=Post --skip-routes)
|
|
71
|
+
assert_file 'app/controllers/admin/posts_controller.rb' do |content|
|
|
72
|
+
assert_instance_method :create, content do |m|
|
|
73
|
+
assert_match %r{format\.html \{ redirect_to \[:admin, @post\], notice: "Post was successfully created\." \}}, m
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
assert_instance_method :update, content do |m|
|
|
77
|
+
assert_match %r{format\.html \{ redirect_to \[:admin, @post\], notice: "Post was successfully updated\.", status: :see_other \}}, m
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
assert_instance_method :destroy, content do |m|
|
|
81
|
+
assert_match %r{format\.html \{ redirect_to admin_posts_path, notice: "Post was successfully destroyed\.", status: :see_other \}}, m
|
|
58
82
|
end
|
|
59
83
|
end
|
|
60
84
|
end
|
|
61
85
|
|
|
62
|
-
test '
|
|
63
|
-
run_generator %w(Post)
|
|
86
|
+
test "don't use require and permit if there are no attributes" do
|
|
87
|
+
run_generator %w(Post --skip-routes)
|
|
64
88
|
|
|
65
89
|
assert_file 'app/controllers/posts_controller.rb' do |content|
|
|
66
90
|
assert_match %r{def post_params}, content
|
|
67
91
|
assert_match %r{params\.fetch\(:post, \{\}\)}, content
|
|
68
92
|
end
|
|
69
93
|
end
|
|
94
|
+
|
|
95
|
+
test 'handles virtual attributes' do
|
|
96
|
+
run_generator %w(Message content:rich_text video:attachment photos:attachments --skip-routes)
|
|
97
|
+
|
|
98
|
+
assert_file 'app/controllers/messages_controller.rb' do |content|
|
|
99
|
+
if Rails::VERSION::MAJOR >= 8
|
|
100
|
+
assert_match %r{params\.expect\(message: \[ :content, :video, photos: \[\] \]\)}, content
|
|
101
|
+
else
|
|
102
|
+
assert_match %r{params\.require\(:message\)\.permit\(:content, :video, photos: \[\]\)}, content
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
70
106
|
end
|
data/test/test_helper.rb
CHANGED
|
@@ -1,34 +1,47 @@
|
|
|
1
1
|
require "bundler/setup"
|
|
2
2
|
|
|
3
|
-
require "
|
|
3
|
+
require "rails"
|
|
4
|
+
|
|
5
|
+
require "jbuilder"
|
|
6
|
+
|
|
4
7
|
require "active_support/core_ext/array/access"
|
|
5
8
|
require "active_support/cache/memory_store"
|
|
6
9
|
require "active_support/json"
|
|
7
10
|
require "active_model"
|
|
8
|
-
require
|
|
9
|
-
require
|
|
10
|
-
|
|
11
|
-
require "jbuilder"
|
|
11
|
+
require 'action_controller/railtie'
|
|
12
|
+
require 'action_view/railtie'
|
|
12
13
|
|
|
13
14
|
require "active_support/testing/autorun"
|
|
14
|
-
require "mocha/
|
|
15
|
+
require "mocha/minitest"
|
|
15
16
|
|
|
16
17
|
ActiveSupport.test_order = :random
|
|
17
18
|
|
|
19
|
+
ENV["RAILS_ENV"] ||= "test"
|
|
20
|
+
|
|
18
21
|
class << Rails
|
|
19
|
-
|
|
22
|
+
redefine_method :cache do
|
|
20
23
|
@cache ||= ActiveSupport::Cache::MemoryStore.new
|
|
21
24
|
end
|
|
22
25
|
end
|
|
23
26
|
|
|
24
|
-
|
|
27
|
+
Jbuilder::CollectionRenderer.collection_cache = Rails.cache
|
|
28
|
+
|
|
29
|
+
class Post < Struct.new(:id, :body, :author_name)
|
|
30
|
+
def cache_key
|
|
31
|
+
"post-#{id}"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
25
34
|
|
|
26
35
|
class Racer < Struct.new(:id, :name)
|
|
27
36
|
extend ActiveModel::Naming
|
|
28
37
|
include ActiveModel::Conversion
|
|
29
38
|
end
|
|
30
39
|
|
|
31
|
-
|
|
40
|
+
# Instantiate an Application in order to trigger the initializers
|
|
41
|
+
Class.new(Rails::Application) do
|
|
42
|
+
config.secret_key_base = 'secret'
|
|
43
|
+
config.eager_load = false
|
|
44
|
+
end.initialize!
|
|
32
45
|
|
|
33
|
-
|
|
34
|
-
ActionView::Base.
|
|
46
|
+
# Touch AV::Base in order to trigger :action_view on_load hook before running the tests
|
|
47
|
+
ActionView::Base.inspect
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jbuilder
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.14.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Heinemeier Hansson
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: activesupport
|
|
@@ -16,33 +15,48 @@ dependencies:
|
|
|
16
15
|
requirements:
|
|
17
16
|
- - ">="
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
18
|
+
version: 7.0.0
|
|
20
19
|
type: :runtime
|
|
21
20
|
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
23
|
- - ">="
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
27
|
-
|
|
25
|
+
version: 7.0.0
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: actionview
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 7.0.0
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 7.0.0
|
|
28
40
|
email: david@basecamp.com
|
|
29
41
|
executables: []
|
|
30
42
|
extensions: []
|
|
31
43
|
extra_rdoc_files: []
|
|
32
44
|
files:
|
|
45
|
+
- ".devcontainer/devcontainer.json"
|
|
46
|
+
- ".github/workflows/ruby.yml"
|
|
33
47
|
- ".gitignore"
|
|
34
|
-
- ".travis.yml"
|
|
35
48
|
- Appraisals
|
|
36
|
-
- CHANGELOG.md
|
|
37
49
|
- CONTRIBUTING.md
|
|
38
50
|
- Gemfile
|
|
39
51
|
- MIT-LICENSE
|
|
40
52
|
- README.md
|
|
41
53
|
- Rakefile
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
- gemfiles/
|
|
45
|
-
- gemfiles/
|
|
54
|
+
- bin/release
|
|
55
|
+
- bin/test
|
|
56
|
+
- gemfiles/rails_7_0.gemfile
|
|
57
|
+
- gemfiles/rails_7_1.gemfile
|
|
58
|
+
- gemfiles/rails_7_2.gemfile
|
|
59
|
+
- gemfiles/rails_8_0.gemfile
|
|
46
60
|
- gemfiles/rails_head.gemfile
|
|
47
61
|
- jbuilder.gemspec
|
|
48
62
|
- lib/generators/rails/jbuilder_generator.rb
|
|
@@ -54,12 +68,14 @@ files:
|
|
|
54
68
|
- lib/generators/rails/templates/show.json.jbuilder
|
|
55
69
|
- lib/jbuilder.rb
|
|
56
70
|
- lib/jbuilder/blank.rb
|
|
57
|
-
- lib/jbuilder/
|
|
71
|
+
- lib/jbuilder/collection_renderer.rb
|
|
58
72
|
- lib/jbuilder/errors.rb
|
|
59
73
|
- lib/jbuilder/jbuilder.rb
|
|
74
|
+
- lib/jbuilder/jbuilder_dependency_tracker.rb
|
|
60
75
|
- lib/jbuilder/jbuilder_template.rb
|
|
61
76
|
- lib/jbuilder/key_formatter.rb
|
|
62
77
|
- lib/jbuilder/railtie.rb
|
|
78
|
+
- lib/jbuilder/version.rb
|
|
63
79
|
- test/jbuilder_dependency_tracker_test.rb
|
|
64
80
|
- test/jbuilder_generator_test.rb
|
|
65
81
|
- test/jbuilder_template_test.rb
|
|
@@ -70,8 +86,12 @@ files:
|
|
|
70
86
|
homepage: https://github.com/rails/jbuilder
|
|
71
87
|
licenses:
|
|
72
88
|
- MIT
|
|
73
|
-
metadata:
|
|
74
|
-
|
|
89
|
+
metadata:
|
|
90
|
+
bug_tracker_uri: https://github.com/rails/jbuilder/issues
|
|
91
|
+
changelog_uri: https://github.com/rails/jbuilder/releases/tag/v2.14.1
|
|
92
|
+
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
|
93
|
+
source_code_uri: https://github.com/rails/jbuilder/tree/v2.14.1
|
|
94
|
+
rubygems_mfa_required: 'true'
|
|
75
95
|
rdoc_options: []
|
|
76
96
|
require_paths:
|
|
77
97
|
- lib
|
|
@@ -79,15 +99,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
79
99
|
requirements:
|
|
80
100
|
- - ">="
|
|
81
101
|
- !ruby/object:Gem::Version
|
|
82
|
-
version:
|
|
102
|
+
version: 3.0.0
|
|
83
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
84
104
|
requirements:
|
|
85
105
|
- - ">="
|
|
86
106
|
- !ruby/object:Gem::Version
|
|
87
107
|
version: '0'
|
|
88
108
|
requirements: []
|
|
89
|
-
rubygems_version: 3.
|
|
90
|
-
signing_key:
|
|
109
|
+
rubygems_version: 3.6.9
|
|
91
110
|
specification_version: 4
|
|
92
111
|
summary: Create JSON structures via a Builder-style DSL
|
|
93
112
|
test_files:
|