pbbuilder 0.18.0 → 0.19.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 75cb2682f8933e0e8acb2b3bb6a525df5447dab8a65b2d8509f54a3c2b430c35
4
- data.tar.gz: '0282cfeb404460224fd8cb2d32d134335b9d307d2edefc4af854368b9c8788e1'
3
+ metadata.gz: 1ea3598ad1ed31172d0b3154c6968649f63073f23de0d94abf191a07dbdbf4e0
4
+ data.tar.gz: 7285883ae069eeff4f1860eb9b4c4a727585e6762b3bfd974ce1fb9e51928086
5
5
  SHA512:
6
- metadata.gz: d429891ca19333b9e626ccd9bf63462fbe61eea672c8ac14f427aafdc392a2f12e36370e63f1a4522c384b4375e81433d63d804f447d508346744aedca448fbf
7
- data.tar.gz: 1af6634160780c84f93a99d9b6b282e90500da24d654bfa36f1220b48260bec074412da69f83267a2df8f935e33218b332a27cf102765e6eff7b3db853ec686e
6
+ metadata.gz: e051d79882379fb30f3f0b4bab503e6591034d1cc16639918d685a0ef19e6f7cc42ea224954bf755db739f6a2b2c2c86a8c7666e23065ce337aafb862486b4f6
7
+ data.tar.gz: 90f2266161a9a101fd4b67afb71130a009b17ec9a5139dc583db18d02a1a32a2bd7730f1ea872c3d4b77a4d64f953b1a34e72cb35f845dc6a879f117f7c3c5ec
@@ -14,21 +14,12 @@ jobs:
14
14
  fail-fast: false
15
15
  matrix:
16
16
  ruby: ["3.0", "3.1", "3.2", "3.3"]
17
-
18
- gemfile: [ "rails_6_1", "rails_7_0"]
17
+ gemfile: [ "rails_6_1", "rails_7_0", "rails_7_2"]
18
+ exclude:
19
+ - ruby: "3.0"
20
+ gemfile: "rails_7_2"
19
21
  experimental: [false]
20
22
 
21
- #include:
22
- # - ruby: '2.7'
23
- # gemfile: rails_head
24
- # experimental: true
25
- # - ruby: '3.0'
26
- # gemfile: rails_head
27
- # experimental: true
28
- # - ruby: '3.1'
29
- # gemfile: rails_head
30
- # experimental: true
31
-
32
23
  steps:
33
24
  - uses: actions/checkout@v3
34
25
 
data/Appraisals CHANGED
@@ -6,6 +6,6 @@ appraise "rails-7-0" do
6
6
  gem "rails", "~> 7.0.0"
7
7
  end
8
8
 
9
- appraise "rails-7-1" do
10
- gem "rails", "~> 7.1.0"
11
- end
9
+ appraise "rails-7-2" do
10
+ gem "rails", "~> 7.2.0"
11
+ end
data/CHANGELOG.md CHANGED
@@ -3,6 +3,15 @@ All notable changes to this project will be documented in this file.
3
3
 
4
4
  This format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5
5
 
6
+ ## 0.19.0
7
+ ### Added
8
+ - Add support for rails 7.2, but leave out rails 7.1 support. This is because ActionView has a breaking bug in 7.1 that renders the template back as a string
9
+ instead of an object, like we need for Pbbuilder https://github.com/rails/rails/pull/51023
10
+
11
+ ## 0.18.0
12
+ ### Added
13
+ - Allow literal assignment of protos to fields
14
+
6
15
  ## 0.17.0
7
16
  ### Changed
8
17
  - Instead of appending to repeated enum message, we're replacing it to avoid issues in case output will be rendered twice
data/Gemfile CHANGED
@@ -7,5 +7,3 @@ gemspec
7
7
 
8
8
  gem "rake"
9
9
  gem "appraisal"
10
-
11
- gem "ruby-lsp"
data/README.md CHANGED
@@ -1,22 +1,19 @@
1
1
  # Pbbuilder
2
- PBBuilder generates [Protobuf](https://developers.google.com/protocol-buffers) Messages with a simple DSL similar to [JBuilder](https://rubygems.org/gems/jbuilder) gem.
2
+ PBBuilder generates [Protobuf](https://developers.google.com/protocol-buffers) Messages with a simple DSL similar to the [JBuilder](https://rubygems.org/gems/jbuilder) gem.
3
3
 
4
4
 
5
- At least Rails 6.1 is required.
6
-
7
- > [!WARNING]
8
- > There currently is a regression in ActionView (the part of Rails which renders) that forces rendered objects into strings. This is only present
9
- > in Rails 7.1, and is fixed in Rails. However, a 7.1 gem containing the fix hasn't been released yet. For the moment you should refrain
10
- > from using pbbuilder and rails-twirp with Rails 7.1 and wait for the next version to be released.
5
+ At least Rails 6.1 is required and rails 7.1 is currently not supported.
6
+ There currently is a regression in ActionView (the part of Rails which renders) that forces rendered objects into strings, but for Pbbuilder we need the raw objects.
7
+ This is only present in Rails 7.1, and a fix is released in Rails 7.2. https://github.com/rails/rails/pull/51023
11
8
 
12
9
  ## Compatibility with jBuilder
13
10
  We don't aim to have 100% compitability and coverage with jbuilder gem, but we closely follow jbuilder's API design to maintain familiarity.
14
11
 
15
12
  | | Jbuilder | Pbbuilder |
16
13
  |---|---|---|
17
- | set! | ✅ | ✅ |
18
- | cache! | ✅ | ✅ |
19
- | cache_if! | ✅ | ✅ |
14
+ | set! | ✅ | ✅ |
15
+ | cache! | ✅ | ✅ |
16
+ | cache_if! | ✅ | ✅ |
20
17
  | cache_root! | ✅| |
21
18
  | fragment cache | ✅| ✅ |
22
19
  | extract! | ✅ | ✅ |
@@ -25,7 +22,7 @@ We don't aim to have 100% compitability and coverage with jbuilder gem, but we c
25
22
  | array! | ✅ | |
26
23
  | .call | ✅ | |
27
24
 
28
- Due to protobuf message implementation, there is absolutely no need to implement support for `deep_format_keys!`, `key_format!`, `key_format`, `deep_format_keys`, `ignore_nil!`, `ignore_nil!`, `nil`. So those would never be added.
25
+ Due to the protobuf message implementation, there is absolutely no need to implement support for `deep_format_keys!`, `key_format!`, `key_format`, `deep_format_keys`, `ignore_nil!`, `ignore_nil!`, `nil`. So those would never be added.
29
26
 
30
27
  ## Usage
31
28
  The main difference is that it can use introspection to figure out what kind of protobuf message it needs to create.
@@ -61,7 +58,7 @@ pb.phone_number account.phone_number
61
58
  pb.tag account.tag
62
59
  ```
63
60
 
64
- could be rewritten to a shorter version with a use of `extract!`.
61
+ can be rewritten to a shorter version with the use of `extract!`.
65
62
  ```
66
63
  pb.extract! account, :id, :phone_number, :tag
67
64
  ```
@@ -80,7 +77,7 @@ Using partial while passing a variable to it
80
77
  pb.account partial: "account", account: @account
81
78
  ```
82
79
 
83
- Here is way to use partials with collection while passing a variable to it
80
+ Here is a way to use partials with a collection while passing a variable to it
84
81
 
85
82
  ```
86
83
  pb.accounts @accounts, partial: "account", as: account
@@ -96,7 +93,7 @@ pb.friends partial: "racers/racer", as: :racer, collection: @racers
96
93
  pb.friends "racers/racer", as: :racer, collection: @racers
97
94
  ```
98
95
 
99
- And there are other ways, that don't use Collection Renderer (not very effective probably)
96
+ And there are other ways, that don't use CollectionRenderer
100
97
  ```ruby
101
98
  pb.partial! @racer, racer: Racer.new(123, "Chris Harris", friends)
102
99
  ```
@@ -105,7 +102,7 @@ pb.friends @friends, partial: "racers/racer", as: :racer
105
102
  ```
106
103
 
107
104
  ### Caching
108
- it uses Rails.cache and works like caching in HTML templates:
105
+ It uses Rails.cache and works like caching in HTML templates:
109
106
 
110
107
  ```
111
108
  pb.cache! "cache-key", expires_in: 10.minutes do
@@ -121,7 +118,7 @@ pb.cache_if! !admin?, "cache-key", expires_in: 10.minutes do
121
118
  end
122
119
  ```
123
120
 
124
- Fragment caching currently works through ActionView::CollectionRenderer and can be used only with the following syntax:
121
+ Fragment caching currently works through ActionView::CollectionRenderer and can only be used with the following syntax:
125
122
 
126
123
  ```ruby
127
124
  pb.friends partial: "racers/racer", as: :racer, collection: @racers, cached: true
@@ -151,10 +148,14 @@ $ gem install pbbuilder
151
148
 
152
149
  When debugging, make sure to prepend `::Kernel` to any calls such as `puts` as otherwise the code will think you're trying to add another attribute into protobuf object.
153
150
 
154
- In case, you're looking to use breakpoints for debugging purposes - it's better to use `pry`. Just make sure to [change pbbuilder superclass from `ProxyObject/BasicObject` to `Object`](lib/pbbuilder/pbbuilder.rb).
151
+ In case you're looking to use breakpoints (for debugging purposes via `binding.pry` for instance), let Pbbuilder inherit from `Object` instead of `BasicObject`]
152
+ Seen in:
153
+ [Pbbuilder](lib/pbbuilder/pbbuilder.rb)
154
+ [Errors](lib/pbbuilder/errors.rb)
155
155
 
156
156
  ## Testing
157
- Running `bundle exec appraisal rake test` locally will run entire testsuit with all version of rails. To run tests only for certain rails version do the following `bundle exec appraisal rails-7-0 rake test`
157
+ Running `bundle exec appraisal rake test` locally will run the entire testsuit with all versions of rails.
158
+ To run tests only for a certain rails version do the following `bundle exec appraisal rails-7-0 rake test`
158
159
 
159
160
  To run only one tests from file - use `m` utility. Like this:
160
161
  `bundle exec appraisal rails-7-0 m test/pbbuilder_template_test.rb:182`
data/Rakefile CHANGED
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "bundler/setup"
4
3
  require "bundler/gem_tasks"
5
4
  require "rake/testtask"
6
5
 
@@ -11,10 +10,28 @@ if !ENV["APPRAISAL_INITIALIZED"] && !ENV["CI"]
11
10
  else
12
11
  Rake::TestTask.new(:test) do |t|
13
12
  t.libs << "test"
14
- t.pattern = "test/**/*_test.rb"
15
- t.verbose = false
16
- t.warning = false
13
+ t.libs << "lib"
14
+
15
+ # Running specific tests with line numbers, like with rails test, is not supported by default in rake.
16
+ # By setting the TESTOPS env var we can however specify the name of a single test with underscores instead of spaces.
17
+ # So run your single test by calling for ex:
18
+ #
19
+ # rake test /Users/sebastian/projects/cheddar/rails-twirp/test/ping_controller_test.rb "uncaught errors should bubble up to the test"
20
+
21
+ file_name = ARGV[1]
22
+ test_name = ARGV[2]&.tr(" ", "_")
23
+
24
+ ENV["TESTOPTS"] = "--verbose"
25
+
26
+ t.test_files = if file_name
27
+ if test_name
28
+ ENV["TESTOPTS"] += " --name=test_#{test_name}"
29
+ end
30
+ [file_name]
31
+ else
32
+ FileList["test/**/*_test.rb"]
33
+ end
17
34
  end
18
35
 
19
36
  task default: :test
20
- end
37
+ end
@@ -4,7 +4,6 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "rake"
6
6
  gem "appraisal"
7
- gem "ruby-lsp"
8
7
  gem "rails", "~> 6.1.0"
9
8
 
10
9
  gemspec path: "../"
@@ -4,7 +4,6 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "rake"
6
6
  gem "appraisal"
7
- gem "ruby-lsp"
8
7
  gem "rails", "~> 7.0.0"
9
8
 
10
9
  gemspec path: "../"
@@ -4,7 +4,6 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "rake"
6
6
  gem "appraisal"
7
- gem "ruby-lsp"
8
- gem "rails", "~> 7.1.0"
7
+ gem "rails", "~> 7.2.0"
9
8
 
10
9
  gemspec path: "../"
@@ -1,12 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'pbbuilder'
4
-
5
- class Pbbuilder
3
+ class Pbbuilder < BasicObject
6
4
  class MergeError < ::StandardError
7
5
  def self.build(current_value, updates)
8
6
  message = "Can't merge #{updates.inspect} into #{current_value.inspect}"
9
7
  self.new(message)
10
8
  end
11
9
  end
12
- end
10
+ end
@@ -17,6 +17,7 @@ class PbbuilderTemplate < Pbbuilder
17
17
  end
18
18
 
19
19
  # Render a partial. Can be called as:
20
+ #
20
21
  # pb.partial! "name/of_partial", argument: 123
21
22
  # pb.partial! "name/of_partial", locals: {argument: 123}
22
23
  # pb.partial! partial: "name/of_partial", argument: 123
@@ -30,7 +31,7 @@ class PbbuilderTemplate < Pbbuilder
30
31
  end
31
32
  end
32
33
 
33
- # Set the value in the message field.
34
+ # Sets the value in the message field.
34
35
  #
35
36
  # @example
36
37
  # pb.friends @friends, partial: "friend", as: :friend
@@ -39,31 +40,30 @@ class PbbuilderTemplate < Pbbuilder
39
40
  # pb.friends "racers/racer", as: :racer, collection: [Racer.new(1, "Johnny Test", []), Racer.new(2, "Max Verstappen", [])]
40
41
 
41
42
  def set!(field, *args, **kwargs, &block)
42
- # If partial options are being passed, we render a submessage with a partial
43
+ # If any partial options are being passed, we render a submessage with a partial
43
44
  if kwargs.has_key?(:partial)
44
45
  if args.one? && kwargs.has_key?(:as)
45
- # example syntax that should end up here:
46
+ # Example syntax that should end up here:
46
47
  # pb.friends @friends, partial: "friend", as: :friend
47
48
  # Call set! on the super class, passing in a block that renders a partial for every element
48
49
  super(field, *args) do |element|
49
50
  _set_inline_partial(element, kwargs)
50
51
  end
51
52
  elsif kwargs.has_key?(:collection) && kwargs.has_key?(:as)
52
- # example syntax that should end up here:
53
+ # Example syntax that should end up here:
53
54
  # pb.friends partial: "racers/racer", as: :racer, collection: [Racer.new(1, "Johnny Test", []), Racer.new(2, "Max Verstappen", [])]
54
55
 
55
56
  _render_collection_with_options(field, kwargs[:collection], kwargs)
56
57
  else
57
- # # example syntax that should end up here:
58
+ # Example syntax that should end up here:
58
59
  # pb.best_friend partial: "person", person: @best_friend
59
-
60
60
  super(field, *args) do
61
61
  _render_partial_with_options(kwargs)
62
62
  end
63
63
  end
64
64
  else
65
65
  if args.one? && kwargs.has_key?(:collection) && kwargs.has_key?(:as)
66
- # example syntax that should end up here:
66
+ # Example syntax that should end up here:
67
67
  # pb.friends "racers/racer", as: :racer, collection: [Racer.new(1, "Johnny Test", []), Racer.new(2, "Max Verstappen", [])]
68
68
  _render_collection_with_options(field, kwargs[:collection], kwargs.merge(partial: args.first))
69
69
  else
@@ -72,7 +72,7 @@ class PbbuilderTemplate < Pbbuilder
72
72
  end
73
73
  end
74
74
 
75
- # Caches fragment of message. Can be called like the following:
75
+ # Caches a fragment of a message with a given cache key. Can be called like the following:
76
76
  # 'pb.cache! "cache-key" do; end'
77
77
  # 'pb.cache! "cache-key", expire_in: 1.min do; end'
78
78
  #
@@ -107,16 +107,16 @@ class PbbuilderTemplate < Pbbuilder
107
107
 
108
108
  private
109
109
 
110
- # Uses ActionView::CollectionRenderer to render collection effectively and to use rails built in fragment caching support.
110
+ # Uses ActionView::CollectionRenderer to render the collection effectively and to use rails' built-in fragment caching support.
111
111
  #
112
- # The way recursive rendering works is that the CollectionRenderer needs to be aware of the node its currently rendering and parent node.
113
- # There is no need to know the entire "stack" of nodes. ActionView::CollectionRenderer would traverse to bottom node render it first and then go one leve up in stack,
114
- # rince and repeat until entire stack is rendered.
112
+ # The way recursive rendering works is that the CollectionRenderer needs to be aware of the node it's currently rendering and it's parent node.
113
+ # There is no need to know the entire "stack" of nodes. ActionView::CollectionRenderer will traverse to the bottom node, render it first and then go one level up in the stack.
114
+ # Rinse and repeat until the entire stack is rendered.
115
115
 
116
116
  # CollectionRenderer uses locals[:pb] to render the partial as a protobuf message,
117
117
  # but also needs locals[:pb_parent] to apply the rendered partial to the top level protobuf message.
118
118
 
119
- # This logic can be found in CollectionRenderer#build_rendered_collection method that we overwrote.
119
+ # This logic can be found in the CollectionRenderer#build_rendered_collection method that we overwrote.
120
120
  def _render_collection_with_options(field, collection, options)
121
121
  partial = options[:partial]
122
122
 
@@ -128,15 +128,15 @@ class PbbuilderTemplate < Pbbuilder
128
128
  options[:locals].merge!(field: field)
129
129
 
130
130
  if options.has_key?(:layout)
131
- raise ::NotImplementedError, "The `:layout' option is not supported in collection rendering."
131
+ ::Kernel.raise ::NotImplementedError, "The `:layout' option is not supported in collection rendering."
132
132
  end
133
133
 
134
134
  if options.has_key?(:spacer_template)
135
- raise ::NotImplementedError, "The `:spacer_template' option is not supported in collection rendering."
135
+ ::Kernel.raise ::NotImplementedError, "The `:spacer_template' option is not supported in collection rendering."
136
136
  end
137
137
 
138
138
  CollectionRenderer
139
- .new(@context.lookup_context, options) { |&block| _scope(message[field.to_s],&block) }
139
+ .new(@context.lookup_context, options) { |&block| _scope(message[field.to_s], &block) }
140
140
  .render_collection_with_partial(collection, partial, @context, nil)
141
141
  end
142
142
 
@@ -172,10 +172,9 @@ class PbbuilderTemplate < Pbbuilder
172
172
  begin
173
173
  ::Rails.cache.write(key, value, options)
174
174
  rescue ::SystemCallError
175
- # In case ActiveSupport::Cache::FileStore in Rails is used as a cache,
176
- # File.atomic_write can have a race condition and fail to rename temporary
177
- # file. We're attempting to recover from that, by catching this specific
178
- # error and returning a value.
175
+ # In case `ActiveSupport::Cache::FileStore` in Rails is used as a cache,
176
+ # `File.atomic_write` can have a race condition and fails to rename temporary file.
177
+ # We're attempting to recover from that by catching this specific error and returning a value.
179
178
  #
180
179
  # @see https://github.com/rails/rails/pull/44151
181
180
  # @see https://github.com/rails/rails/blob/main/activesupport/lib/active_support/core_ext/file/atomic.rb#L50
data/lib/pbbuilder.rb CHANGED
@@ -1,12 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "pbbuilder/pbbuilder"
4
- require 'pbbuilder/errors'
3
+ require "pbbuilder/errors"
5
4
  require "pbbuilder/protobuf_extension"
6
5
  require "pbbuilder/railtie" if defined?(Rails)
7
6
 
8
-
9
- # Pbbuilder makes it easy to create a protobuf message using the builder pattern
7
+ # Pbbuilder makes it easy to create a protobuf message using the builder pattern.
10
8
  # It is heavily inspired by jbuilder
11
9
  #
12
10
  # Given this example message definition:
@@ -15,8 +13,10 @@ require "pbbuilder/railtie" if defined?(Rails)
15
13
  # repeated Person friends = 2;
16
14
  # }
17
15
  #
18
- # You could use Pbbuilder as follows:
16
+ # You can use Pbbuilder as follows:
17
+ #
19
18
  # person = RPC::Person.new
19
+ #
20
20
  # Pbbuilder.new(person) do |pb|
21
21
  # pb.name "Hello"
22
22
  # pb.friends [1, 2, 3] do |number|
@@ -29,7 +29,7 @@ require "pbbuilder/railtie" if defined?(Rails)
29
29
  # It basically works exactly like jbuilder. The main difference is that it can use introspection to figure out what kind
30
30
  # of protobuf message it needs to create.
31
31
 
32
- class Pbbuilder
32
+ class Pbbuilder < BasicObject
33
33
  def initialize(message)
34
34
  @message = message
35
35
 
@@ -48,11 +48,15 @@ class Pbbuilder
48
48
  !!_descriptor_for_field(field)
49
49
  end
50
50
 
51
+ # When calling for ex: response.drivers, where response is a Google::Protobuf object, 'drivers' is not a method on that. These
52
+ # methods (or messages in our case) get added here. This is of course based on what kind of message it is. Singular, an array
53
+ # (repeated) etc. with their arguments.
51
54
  def set!(field, *args, &block)
52
55
  name = field.to_s
53
56
  descriptor = _descriptor_for_field(name)
54
- ::Kernel.raise ::ArgumentError, "Unknown field #{name}" if descriptor.nil?
57
+ ::Kernel.raise ::ArgumentError, "Unknown field: #{name}" if descriptor.nil?
55
58
 
59
+ # An block is used to pass on it's children
56
60
  if ::Kernel.block_given?
57
61
  ::Kernel.raise ::ArgumentError, "can't pass block to non-message field" unless descriptor.type == :message
58
62
 
@@ -66,9 +70,11 @@ class Pbbuilder
66
70
  # example syntax that should end up here:
67
71
  # pb.field { pb.name "hello" }
68
72
  ::Kernel.raise ::ArgumentError, "wrong number of arguments (expected 0)" unless args.empty?
73
+
69
74
  message = (@message[name] ||= _new_message_from_descriptor(descriptor))
70
75
  _scope(message, &block)
71
76
  end
77
+ # No block given, but with 1 argument
72
78
  elsif args.length == 1
73
79
  arg = args.first
74
80
  if descriptor.label == :repeated
@@ -106,7 +112,7 @@ class Pbbuilder
106
112
  else
107
113
  # example syntax that should end up here:
108
114
  # pb.field "value"
109
-
115
+
110
116
  @message[name] = arg
111
117
  end
112
118
  else
@@ -128,6 +134,8 @@ class Pbbuilder
128
134
  end
129
135
  end
130
136
 
137
+ # Shorthand command for getting a few attributes from an object.
138
+ # pb.extract! racer, :name, :id, :age
131
139
  def extract!(element, *args)
132
140
  args.each { |arg| @message[arg.to_s] = element.send(arg) }
133
141
  end
@@ -181,6 +189,7 @@ class Pbbuilder
181
189
  @message
182
190
  end
183
191
 
192
+ # @param field string
184
193
  def new_message_for(field)
185
194
  descriptor = _descriptor_for_field(field)
186
195
  ::Kernel.raise ::ArgumentError, "Unknown field #{field}" if descriptor.nil?
@@ -190,11 +199,14 @@ class Pbbuilder
190
199
 
191
200
  private
192
201
 
202
+ # Lookup the field name (or 'attribute' name, for ex "best_friend") on the Google descriptor (Google::Protobuf::Descriptor) of our
203
+ # message object.
204
+ # @param field string
193
205
  def _descriptor_for_field(field)
194
206
  @message.class.descriptor.lookup(field.to_s)
195
207
  end
196
208
 
197
- # Appends protobuf message with existing @message object
209
+ # Appends protobuf objects to our 'repeated' attribute. This can create a list of items to a repeated field.
198
210
  #
199
211
  # @param name string
200
212
  # @param descriptor Google::Protobuf::FieldDescriptor
@@ -210,7 +222,8 @@ class Pbbuilder
210
222
  @message[name].push(*elements)
211
223
  end
212
224
 
213
- # Yields an Protobuf object in a scope of message and provided values.
225
+ # Yields a Protobuf object in the scope of message and provided values.
226
+ # This will 'assign' the field values as it were to the message attributes.
214
227
  #
215
228
  # @param message Google::Protobuf::(field_type)
216
229
  def _scope(message)
@@ -222,7 +235,7 @@ class Pbbuilder
222
235
  @message = old_message
223
236
  end
224
237
 
225
- # Build up empty protobuf message based on descriptor
238
+ # Builds up an empty protobuf message based on the given descriptor.
226
239
  #
227
240
  # @param descriptor Google::Protobuf::FieldDescriptor
228
241
  def _new_message_from_descriptor(descriptor)
data/pbbuilder.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "pbbuilder"
5
- spec.version = "0.18.0"
5
+ spec.version = "0.19.0"
6
6
  spec.authors = ["Bouke van der Bijl"]
7
7
  spec.email = ["bouke@cheddar.me"]
8
8
  spec.homepage = "https://github.com/cheddar-me/pbbuilder"
@@ -57,7 +57,7 @@ class PbbuilderTemplateTest < ActiveSupport::TestCase
57
57
  test "collection partial with fragment caching enabled" do
58
58
  template = <<-PBBUILDER
59
59
  racers = [Racer.new(1, "Johnny Test", [], nil, API::Asset.new(url: "https://google.com/test1.svg")), Racer.new(2, "Max Verstappen", [])]
60
- pb.friends partial: "racers/racer", as: :racer, collection: racers, cached: true
60
+ pb.friends partial: "racers/racer", collection: racers, cached: true, as: :racer
61
61
  PBBUILDER
62
62
  result = render(template)
63
63
 
@@ -83,7 +83,7 @@ class PbbuilderTemplateTest < ActiveSupport::TestCase
83
83
  end
84
84
 
85
85
  test "render collections with partial as arg" do
86
- skip("This will be addressed in future version of a gem")
86
+ skip("This will be addressed in a future version of this gem")
87
87
  result = render('pb.friends "racers/racer", as: :racer, collection: [Racer.new(1, "Johnny Test", []), Racer.new(2, "Max Verstappen", [])]')
88
88
 
89
89
  assert_equal 2, result.friends.count
@@ -62,7 +62,7 @@ class PbbuilderTest < ActiveSupport::TestCase
62
62
 
63
63
  assert_equal(["ok", "that's"], p.field_mask.paths)
64
64
  end
65
-
65
+
66
66
  test "sets the last value of the repeated field to be the only value" do
67
67
  person = Pbbuilder.new(API::Person.new) do |pb|
68
68
  pb.field_mask do
data/test/test_helper.rb CHANGED
@@ -55,10 +55,16 @@ class << Rails
55
55
  end
56
56
  end
57
57
 
58
+ Pbbuilder::CollectionRenderer.collection_cache = Rails.cache
59
+
58
60
  class Racer < Struct.new(:id, :name, :friends, :best_friend, :logo)
59
61
  extend ActiveModel::Naming
60
62
  include ActiveModel::Conversion
61
63
 
64
+ def cache_key
65
+ "racer-#{id}"
66
+ end
67
+
62
68
  # Fragment caching needs to know, if record could be persisted. We set it to false, this is a default in ActiveModel::API.
63
69
  def persisted?
64
70
  false
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pbbuilder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.0
4
+ version: 0.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bouke van der Bijl
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-25 00:00:00.000000000 Z
11
+ date: 2024-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-protobuf
@@ -89,13 +89,12 @@ files:
89
89
  - gemfiles/rails_6_1.gemfile
90
90
  - gemfiles/rails_7.gemfile
91
91
  - gemfiles/rails_7_0.gemfile
92
- - gemfiles/rails_7_1.gemfile
92
+ - gemfiles/rails_7_2.gemfile
93
93
  - gemfiles/rails_head.gemfile
94
94
  - lib/pbbuilder.rb
95
95
  - lib/pbbuilder/collection_renderer.rb
96
96
  - lib/pbbuilder/errors.rb
97
97
  - lib/pbbuilder/handler.rb
98
- - lib/pbbuilder/pbbuilder.rb
99
98
  - lib/pbbuilder/protobuf_extension.rb
100
99
  - lib/pbbuilder/railtie.rb
101
100
  - lib/pbbuilder/template.rb
@@ -123,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
122
  - !ruby/object:Gem::Version
124
123
  version: '0'
125
124
  requirements: []
126
- rubygems_version: 3.3.7
125
+ rubygems_version: 3.5.18
127
126
  signing_key:
128
127
  specification_version: 4
129
128
  summary: Generate Protobuf Messages with a simple DSL similar to JBuilder
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- Pbbuilder = Class.new(begin
4
- require 'active_support/proxy_object'
5
- ActiveSupport::ProxyObject
6
- rescue LoadError
7
- require 'active_support/basic_object'
8
- ActiveSupport::BasicObject
9
- end)