jbuilder_reopen 0.1.3

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b5446874dfdda2493ac6fb23c20412fde4268761754ffec2e6a95fabb4bc7862
4
+ data.tar.gz: 5297ce54a75bbcfacfc1b0d237bf164e397045b573a6bc5708358cfeabb7b561
5
+ SHA512:
6
+ metadata.gz: cbf407e0c17497c433e3ebc80083eeb7481c545f41d7dbd1f10df81ce98a54467061c1cf357305fdd73841034d15fe61a482dee3646bbdad356cdf1558a2e4f0
7
+ data.tar.gz: ac94bb0e47acace36e8c1aac753cbd370b34aadb5034b60da9e10204e6f4dab31c8c6708e7c160f9ffc828b75d833f314564168c14be6b68950c2f35de984aca
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ tmp
2
+ gemfiles/*.lock
3
+ Gemfile.lock
4
+ .ruby-version
5
+ pkg
6
+ *.gem
data/.travis.yml ADDED
@@ -0,0 +1,47 @@
1
+ language: ruby
2
+
3
+ cache: bundler
4
+
5
+ before_install:
6
+ - "gem update --system 2.7.9"
7
+ - "gem install bundler -v '<2'"
8
+
9
+ rvm:
10
+ - 2.2.10
11
+ - 2.3.8
12
+ - 2.4.6
13
+ - 2.5.5
14
+ - 2.6.2
15
+ - ruby-head
16
+ - rbx-3.107
17
+
18
+ gemfile:
19
+ - gemfiles/rails_5_0.gemfile
20
+ - gemfiles/rails_5_1.gemfile
21
+ - gemfiles/rails_5_2.gemfile
22
+ - gemfiles/rails_6_0.gemfile
23
+ - gemfiles/rails_head.gemfile
24
+
25
+ matrix:
26
+ exclude:
27
+ - rvm: 2.2.10
28
+ gemfile: gemfiles/rails_6_0.gemfile
29
+ - rvm: 2.3.8
30
+ gemfile: gemfiles/rails_6_0.gemfile
31
+ - rvm: 2.4.6
32
+ gemfile: gemfiles/rails_6_0.gemfile
33
+ - rvm: 2.2.10
34
+ gemfile: gemfiles/rails_head.gemfile
35
+ - rvm: 2.3.8
36
+ gemfile: gemfiles/rails_head.gemfile
37
+ - rvm: 2.4.6
38
+ gemfile: gemfiles/rails_head.gemfile
39
+ allow_failures:
40
+ - rvm: jruby-19mode
41
+ - rvm: rbx-3.107
42
+ - rvm: ruby-head
43
+ - gemfile: gemfiles/rails_head.gemfile
44
+ fast_finish: true
45
+
46
+ notifications:
47
+ email: false
data/Appraisals ADDED
@@ -0,0 +1,21 @@
1
+ appraise "rails-5-0" do
2
+ gem "rails", "~> 5.0.0"
3
+ end
4
+
5
+ appraise "rails-5-1" do
6
+ gem "rails", "~> 5.1.0"
7
+ end
8
+
9
+ appraise "rails-5-2" do
10
+ gem "rails", "~> 5.2.0"
11
+ end
12
+
13
+ if RUBY_VERSION >= "2.5.0"
14
+ appraise "rails-6-0" do
15
+ gem "rails", "~> 6.0.0"
16
+ end
17
+
18
+ appraise "rails-head" do
19
+ gem "rails", github: "rails/rails"
20
+ end
21
+ end
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "rake"
6
+ gem "mocha", require: false
7
+ gem "appraisal"
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2020 Jason Tian
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # JbuilderReopen
2
+
3
+ ## Installation
4
+
5
+ gem 'jbuilder_reopen'
6
+
7
+ ## Usage
8
+
9
+ To opmtimise cache, now you can reopen blocks and add additional fields
10
+
11
+ Examples:
12
+
13
+ json.cache! "cache-key" do
14
+ json.posts @posts, partial: "post", as: :post
15
+ end
16
+ json.reopen! ["posts"] do |post|
17
+ json.title post["body"]
18
+ json.reopen! ["author"] do |author|
19
+ json.middle_name author["first_name"]
20
+ end
21
+ end
22
+
23
+ ## Testing
24
+ bundle install
25
+ appraisal install
26
+ appraisal rake test
27
+
28
+ ## Credit
29
+ Thank you! https://github.com/rails/jbuilder
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ require "bundler/setup"
2
+ require "bundler/gem_tasks"
3
+ require "rake/testtask"
4
+
5
+ if !ENV["APPRAISAL_INITIALIZED"] && !ENV["TRAVIS"]
6
+ require "appraisal/task"
7
+ Appraisal::Task.new
8
+ task default: :appraisal
9
+ else
10
+ Rake::TestTask.new do |test|
11
+ require "rails/version"
12
+
13
+ test.libs << "test"
14
+
15
+ test.test_files = FileList["test/*_test.rb"]
16
+ end
17
+
18
+ task default: :test
19
+ end
@@ -0,0 +1,2 @@
1
+ ---
2
+ BUNDLE_RETRY: "1"
@@ -0,0 +1,10 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake"
6
+ gem "mocha", require: false
7
+ gem "appraisal"
8
+ gem "rails", "~> 5.0.0"
9
+
10
+ gemspec path: "../"
@@ -0,0 +1,10 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake"
6
+ gem "mocha", require: false
7
+ gem "appraisal"
8
+ gem "rails", "~> 5.1.0"
9
+
10
+ gemspec path: "../"
@@ -0,0 +1,10 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake"
6
+ gem "mocha", require: false
7
+ gem "appraisal"
8
+ gem "rails", "~> 5.2.0"
9
+
10
+ gemspec path: "../"
@@ -0,0 +1,10 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake"
6
+ gem "mocha", require: false
7
+ gem "appraisal"
8
+ gem "rails", "~> 6.0.0"
9
+
10
+ gemspec path: "../"
@@ -0,0 +1,10 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake"
6
+ gem "mocha", require: false
7
+ gem "appraisal"
8
+ gem "rails", github: "rails/rails"
9
+
10
+ gemspec path: "../"
@@ -0,0 +1,21 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'jbuilder_reopen/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "jbuilder_reopen"
8
+ spec.version = JbuilderReopen::VERSION
9
+ spec.authors = ["Ben Zhang", "Jason Tian"]
10
+ spec.email = ["jason.tian@pixelforcesystems.com.au"]
11
+ spec.summary = "Now you can reopen blocks and add additional fields"
12
+ spec.homepage = "https://www.github.com/jialitian/jbuilder-reopen"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files`.split("\n")
16
+ spec.test_files = `git ls-files -- test/*`.split("\n")
17
+
18
+ spec.required_ruby_version = '>= 2.2.2'
19
+
20
+ spec.add_dependency 'jbuilder', '~> 2.10'
21
+ end
@@ -0,0 +1,6 @@
1
+ require "jbuilder_reopen/version"
2
+ require "jbuilder_reopen/jbuilder_scope"
3
+ require "jbuilder_reopen/jbuilder_template"
4
+
5
+ module JbuilderReopen
6
+ end
@@ -0,0 +1,12 @@
1
+ module JbuilderScope
2
+ def _scope(_attributes=Jbuilder::Blank.new)
3
+ parent_attributes, parent_formatter = @attributes, @key_formatter
4
+ @attributes = _attributes
5
+ yield
6
+ @attributes
7
+ ensure
8
+ @attributes, @key_formatter = parent_attributes, parent_formatter
9
+ end
10
+ end
11
+
12
+ Jbuilder.prepend(JbuilderScope)
@@ -0,0 +1,20 @@
1
+ class JbuilderTemplate
2
+ def reopen!(keys=[], &block)
3
+ keys = keys.dup
4
+ if keys.empty?
5
+ _scope(@attributes) { yield @attributes }
6
+ else
7
+ return if _blank?
8
+ key = keys.shift
9
+ result = if ::Array === @attributes[key]
10
+ @attributes[key].map do |element|
11
+ _scope(element) { reopen!(keys, &block) }
12
+ end
13
+ elsif ::Hash === @attributes[key]
14
+ _scope(@attributes[key]) { reopen!(keys, &block) }
15
+ end
16
+ @attributes[key] = result if result.present?
17
+ @attributes
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,3 @@
1
+ module JbuilderReopen
2
+ VERSION = "0.1.3"
3
+ end
@@ -0,0 +1,193 @@
1
+ require "test_helper"
2
+ require "action_view/testing/resolvers"
3
+
4
+ class JbuilderTemplateTest < ActiveSupport::TestCase
5
+ POST_PARTIAL = <<-JBUILDER
6
+ json.extract! post, :id, :body
7
+ json.author do
8
+ first_name, last_name = post.author_name.split(nil, 2)
9
+ json.first_name first_name
10
+ json.last_name last_name
11
+ end
12
+ JBUILDER
13
+
14
+ COLLECTION_PARTIAL = <<-JBUILDER
15
+ json.extract! collection, :id, :name
16
+ JBUILDER
17
+
18
+ RACER_PARTIAL = <<-JBUILDER
19
+ json.extract! racer, :id, :name
20
+ JBUILDER
21
+
22
+ PARTIALS = {
23
+ "_partial.json.jbuilder" => "json.content content",
24
+ "_post.json.jbuilder" => POST_PARTIAL,
25
+ "racers/_racer.json.jbuilder" => RACER_PARTIAL,
26
+ "_collection.json.jbuilder" => COLLECTION_PARTIAL,
27
+
28
+ # Ensure we find only Jbuilder partials from within Jbuilder templates.
29
+ "_post.html.erb" => "Hello world!"
30
+ }
31
+
32
+ AUTHORS = [ "David Heinemeier Hansson", "Pavel Pravosud" ].cycle
33
+ POSTS = (1..10).collect { |i| Post.new(i, "Post ##{i}", AUTHORS.next) }
34
+
35
+ setup { Rails.cache.clear }
36
+
37
+ test "reopen array" do
38
+ code = <<-JBUILDER
39
+ json.cache! "cache-key" do
40
+ json.posts @posts, partial: "post", as: :post
41
+ end
42
+ json.reopen! ["posts"] do |post|
43
+ json.title ("title " + post["id"].to_s)
44
+ end
45
+ JBUILDER
46
+ result = render(code, posts: POSTS)
47
+ assert_equal "title 1", result["posts"][0]["title"]
48
+ end
49
+
50
+ test "reopen nested hash" do
51
+ code = <<-JBUILDER
52
+ json.cache! "cache-key" do
53
+ json.posts @posts, partial: "post", as: :post
54
+ end
55
+ json.reopen! ["posts"] do |post|
56
+ json.title post["body"]
57
+ end
58
+ json.reopen! ["posts", "author"] do |author|
59
+ json.middle_name author["first_name"]
60
+ end
61
+ JBUILDER
62
+ result = render(code, posts: POSTS)
63
+ assert_equal "Post #1", result["posts"][0]["title"]
64
+ assert_equal 1, result["posts"][0]["id"]
65
+ assert_equal "Post #1", result["posts"][0]["body"]
66
+ assert_equal "David", result["posts"][2]["author"]["first_name"]
67
+ assert_equal "Heinemeier Hansson", result["posts"][2]["author"]["last_name"]
68
+ assert_equal "David", result["posts"][2]["author"]["middle_name"]
69
+ assert_equal "Pavel", result["posts"][5]["author"]["middle_name"]
70
+ end
71
+
72
+ test "reopen nested reopen" do
73
+ code = <<-JBUILDER
74
+ json.cache! "cache-key" do
75
+ json.posts @posts, partial: "post", as: :post
76
+ end
77
+ json.reopen! ["posts"] do |post|
78
+ json.title post["body"]
79
+ json.reopen! ["author"] do |author|
80
+ json.middle_name author["first_name"]
81
+ end
82
+ end
83
+ JBUILDER
84
+ result = render(code, posts: POSTS)
85
+ assert_equal "Post #1", result["posts"][0]["title"]
86
+ assert_equal 1, result["posts"][0]["id"]
87
+ assert_equal "Post #1", result["posts"][0]["body"]
88
+ assert_equal "David", result["posts"][2]["author"]["first_name"]
89
+ assert_equal "Heinemeier Hansson", result["posts"][2]["author"]["last_name"]
90
+ assert_equal "David", result["posts"][2]["author"]["middle_name"]
91
+ assert_equal "Pavel", result["posts"][5]["author"]["middle_name"]
92
+ end
93
+
94
+ test "reopen nested array" do
95
+ code = <<-JBUILDER
96
+ json.cache! "cache-key" do
97
+ json.authors ["David Heinemeier Hansson", "Pavel Pravosud"] do |author|
98
+ json.name author
99
+ json.posts @posts, partial: "post", as: :post
100
+ end
101
+ end
102
+ json.reopen! ["authors", "posts"] do |_post|
103
+ json.title "test"
104
+ json.body nil
105
+ end
106
+ JBUILDER
107
+ result = render(code, posts: POSTS)
108
+ assert_equal "test", result["authors"][0]["posts"][2]["title"]
109
+ assert_nil result["authors"][0]["posts"][2]["body"]
110
+ end
111
+
112
+ test "raise error if change data type has been overrided" do
113
+ code = <<-JBUILDER
114
+ json.cache! "cache-key" do
115
+ json.posts @posts, partial: "post", as: :post
116
+ end
117
+ json.reopen! ["posts", "body"] do |_body|
118
+ json.title "test"
119
+ end
120
+ JBUILDER
121
+ result = render(code, posts: POSTS)
122
+ assert_nil result["posts"][0]["title"]
123
+ assert_equal "Post #1", result["posts"][0]["body"]
124
+ end
125
+
126
+ test "do nothing if anchor target is not found" do
127
+ code = <<-JBUILDER
128
+ json.cache! "cache-key" do
129
+ json.posts @posts, partial: "post", as: :post
130
+ end
131
+ json.reopen! ["posts", "title"] do |_body|
132
+ json.title "test"
133
+ end
134
+ JBUILDER
135
+ result = render(code, posts: POSTS)
136
+ assert_equal false, result["posts"][0].key?("title")
137
+ assert_equal "Post #1", result["posts"][0]["body"]
138
+ end
139
+
140
+ test "do nothing if anchor target is missing" do
141
+ discussions = [
142
+ {
143
+ title: "Discussion 1",
144
+ posts: POSTS
145
+ },
146
+ {
147
+ title: "Discussion 2",
148
+ posts: []
149
+ }
150
+ ]
151
+ code = <<-JBUILDER
152
+ json.cache! "cache-key" do
153
+ json.discussions @discussions do |discussion|
154
+ json.name discussion[:name]
155
+ json.posts discussion[:posts], partial: "post", as: :post
156
+ end
157
+ end
158
+ json.reopen! ["discussions", "posts", "author"] do |author|
159
+ json.middle_name "test"
160
+ end
161
+ JBUILDER
162
+ result = render(code, discussions: discussions)
163
+ assert_equal "test", result["discussions"][0]["posts"][0]["author"]["middle_name"]
164
+ assert_equal [], result["discussions"][1]["posts"]
165
+ end
166
+
167
+ private
168
+ def render(*args)
169
+ JSON.load render_without_parsing(*args)
170
+ end
171
+
172
+ def render_without_parsing(source, assigns = {})
173
+ view = build_view(fixtures: PARTIALS.merge("source.json.jbuilder" => source), assigns: assigns)
174
+ view.render(template: "source.json.jbuilder")
175
+ end
176
+
177
+ def build_view(options = {})
178
+ resolver = ActionView::FixtureResolver.new(options.fetch(:fixtures))
179
+ lookup_context = ActionView::LookupContext.new([ resolver ], {}, [""])
180
+ controller = ActionView::TestCase::TestController.new
181
+
182
+ # TODO: Use with_empty_template_cache unconditionally after dropping support for Rails <6.0.
183
+ view = if ActionView::Base.respond_to?(:with_empty_template_cache)
184
+ ActionView::Base.with_empty_template_cache.new(lookup_context, options.fetch(:assigns, {}), controller)
185
+ else
186
+ ActionView::Base.new(lookup_context, options.fetch(:assigns, {}), controller)
187
+ end
188
+
189
+ def view.view_cache_dependencies; []; end
190
+
191
+ view
192
+ end
193
+ end
@@ -0,0 +1,35 @@
1
+ require "bundler/setup"
2
+
3
+ require "active_support"
4
+ require "active_support/core_ext/array/access"
5
+ require "active_support/cache/memory_store"
6
+ require "active_support/json"
7
+ require "active_model"
8
+ require "action_view"
9
+ require "rails/version"
10
+
11
+ require "jbuilder"
12
+ require "jbuilder_reopen"
13
+
14
+ require "active_support/testing/autorun"
15
+ require "mocha/setup"
16
+
17
+ ActiveSupport.test_order = :random
18
+
19
+ class << Rails
20
+ def cache
21
+ @cache ||= ActiveSupport::Cache::MemoryStore.new
22
+ end
23
+ end
24
+
25
+ class Post < Struct.new(:id, :body, :author_name); end
26
+
27
+ class Racer < Struct.new(:id, :name)
28
+ extend ActiveModel::Naming
29
+ include ActiveModel::Conversion
30
+ end
31
+
32
+ ActionView::Template.register_template_handler :jbuilder, JbuilderHandler
33
+
34
+ ActionView::Base.remove_possible_method :fragment_name_with_digest
35
+ ActionView::Base.remove_possible_method :cache_fragment_name
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jbuilder_reopen
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.3
5
+ platform: ruby
6
+ authors:
7
+ - Ben Zhang
8
+ - Jason Tian
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2020-03-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: jbuilder
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '2.10'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '2.10'
28
+ description:
29
+ email:
30
+ - jason.tian@pixelforcesystems.com.au
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".gitignore"
36
+ - ".travis.yml"
37
+ - Appraisals
38
+ - Gemfile
39
+ - MIT-LICENSE
40
+ - README.md
41
+ - Rakefile
42
+ - gemfiles/.bundle/config
43
+ - gemfiles/rails_5_0.gemfile
44
+ - gemfiles/rails_5_1.gemfile
45
+ - gemfiles/rails_5_2.gemfile
46
+ - gemfiles/rails_6_0.gemfile
47
+ - gemfiles/rails_head.gemfile
48
+ - jbuilder_reopen.gemspec
49
+ - lib/jbuilder_reopen.rb
50
+ - lib/jbuilder_reopen/jbuilder_scope.rb
51
+ - lib/jbuilder_reopen/jbuilder_template.rb
52
+ - lib/jbuilder_reopen/version.rb
53
+ - test/jbuilder_template_test.rb
54
+ - test/test_helper.rb
55
+ homepage: https://www.github.com/jialitian/jbuilder-reopen
56
+ licenses:
57
+ - MIT
58
+ metadata: {}
59
+ post_install_message:
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: 2.2.2
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ requirements: []
74
+ rubygems_version: 3.0.6
75
+ signing_key:
76
+ specification_version: 4
77
+ summary: Now you can reopen blocks and add additional fields
78
+ test_files:
79
+ - test/jbuilder_template_test.rb
80
+ - test/test_helper.rb