pbbuilder 0.15.1 → 0.16.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc165db83a23b9c5bf32a6921b3cd959171083d48f7a6887df8c524f9920d574
4
- data.tar.gz: 7d3631f19dea340592918300b66e6d024889fe2c18776c729d4bebdb9424ad4b
3
+ metadata.gz: f4c9ff9f8ec71c8e3fee410430e9c29da1907e6e110ec6869531b52b8ec54ce5
4
+ data.tar.gz: 0f75e4c2fbdde5b6c33acc05dd62173b2b399d03c1030c7fd132c460d229b12b
5
5
  SHA512:
6
- metadata.gz: ad453cd1f12f8a71f05b98c5d60e34837848f1c4bdbe403d41a407762b980d5f47c6dc16925b01f2927fef427cb82b5a4b23801102fa7a46d280adf1245afe2f
7
- data.tar.gz: 1b0bb8019d473e1a433e3009ece6976d7a42992e00d207290106fef8a7de3fd16de5c49caaf6dc23a39aab5cdd6369caae06f62b34def0f431e6c16361210e03
6
+ metadata.gz: '0191dcf320aa97316c483230dda497cc1d83c20f1aac6caa5e4ce4a8883188a949a8217344f04445ab4375b1a4bf952c49eef115af357c87c8127f1c85db3ac7'
7
+ data.tar.gz: 287458b4fc6db49f90a0d76e4da273861b58bfd84d49edd86f966198a16cb694319cd47fca69200d5cad5767307fbbe83b2fa8c866519056313b3d435c5e917e
@@ -13,7 +13,7 @@ jobs:
13
13
  strategy:
14
14
  fail-fast: false
15
15
  matrix:
16
- ruby: ["2.7", "3.0", "3.1", "3.2"]
16
+ ruby: ["3.0", "3.1", "3.2", "3.3"]
17
17
 
18
18
  gemfile: [ "rails_6_1", "rails_7_0"]
19
19
  experimental: [false]
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-head" do
10
- gem "rails", github: "rails/rails", branch: "main"
11
- end
9
+ appraise "rails-7-1" do
10
+ gem "rails", "~> 7.1.0"
11
+ end
data/CHANGELOG.md CHANGED
@@ -3,6 +3,13 @@ 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.16.0
7
+ ### Added
8
+ - Added support for new collection rendering, that is backed by ActiveView::CollectionRenderer.
9
+
10
+ ### Changed
11
+ - Refactoring and simplification of #merge! method without a change in functionality.
12
+
6
13
  ## 0.15.1
7
14
  ### Fixed
8
15
  - #merge! method to handle repeated unintialized message object
data/Gemfile CHANGED
@@ -7,3 +7,5 @@ gemspec
7
7
 
8
8
  gem "rake"
9
9
  gem "appraisal"
10
+
11
+ gem "ruby-lsp"
data/README.md CHANGED
@@ -1,8 +1,11 @@
1
1
  # Pbbuilder
2
2
  PBBuilder generates [Protobuf](https://developers.google.com/protocol-buffers) Messages with a simple DSL similar to [JBuilder](https://rubygems.org/gems/jbuilder) gem.
3
3
 
4
- ## Compatibility
5
- We don't aim to have 100% compatibility with jbuilder gem, but we closely follow jbuilder's API design.
4
+
5
+ At least Rails 6.1 is required.
6
+
7
+ ## Compatibility with jBuilder
8
+ We don't aim to have 100% compitability and coverage with jbuilder gem, but we closely follow jbuilder's API design to maintain familiarity.
6
9
 
7
10
  | | Jbuilder | Pbbuilder |
8
11
  |---|---|---|
@@ -10,12 +13,14 @@ We don't aim to have 100% compatibility with jbuilder gem, but we closely follow
10
13
  | cache! | ✅ | ✅ |
11
14
  | cache_if! | ✅ | ✅ |
12
15
  | cache_root! | ✅| |
16
+ | collection cache | ✅| |
13
17
  | extract! | ✅ | ✅ |
14
18
  | merge! | ✅ | ✅ |
15
- | deep_format_keys! | ✅ | |
16
19
  | child! | ✅ | |
17
20
  | array! | ✅ | |
18
- | ignore_nil! | ✅ | |
21
+ | .call | ✅ | |
22
+
23
+ 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.
19
24
 
20
25
  ## Usage
21
26
  The main difference is that it can use introspection to figure out what kind of protobuf message it needs to create.
@@ -76,8 +81,26 @@ Here is way to use partials with collection while passing a variable to it
76
81
  pb.accounts @accounts, partial: "account", as: account
77
82
  ```
78
83
 
84
+ ## Collections (or Arrays)
85
+ There are two different methods to render a collection. One that uses ActiveView::CollectionRenderer
86
+ ```ruby
87
+ pb.friends partial: "racers/racer", as: :racer, collection: @racers
88
+ ```
89
+
90
+ ```ruby
91
+ pb.friends "racers/racer", as: :racer, collection: @racers
92
+ ```
93
+
94
+ And there are other ways, that don't use Collection Renderer (not very effective probably)
95
+ ```ruby
96
+ pb.partial! @racer, racer: Racer.new(123, "Chris Harris", friends)
97
+ ```
98
+ ```ruby
99
+ pb.friends @friends, partial: "racers/racer", as: :racer
100
+ ```
101
+
79
102
  ### Caching
80
- Fragment caching is supported, it uses Rails.cache and works like caching in HTML templates:
103
+ it uses Rails.cache and works like caching in HTML templates:
81
104
 
82
105
  ```
83
106
  pb.cache! "cache-key", expires_in: 10.minutes do
@@ -93,6 +116,8 @@ pb.cache_if! !admin?, "cache-key", expires_in: 10.minutes do
93
116
  end
94
117
  ```
95
118
 
119
+ Fragment caching support is currently in the works.
120
+
96
121
  ## Installation
97
122
  Add this line to your application's Gemfile:
98
123
 
@@ -0,0 +1,9 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake"
6
+ gem "appraisal"
7
+ gem "rails", "~> 6.0"
8
+
9
+ gemspec path: "../"
@@ -4,6 +4,7 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "rake"
6
6
  gem "appraisal"
7
+ gem "ruby-lsp"
7
8
  gem "rails", "~> 6.1.0"
8
9
 
9
10
  gemspec path: "../"
@@ -0,0 +1,9 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake"
6
+ gem "appraisal"
7
+ gem "rails", "~> 7.0"
8
+
9
+ gemspec path: "../"
@@ -4,6 +4,7 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "rake"
6
6
  gem "appraisal"
7
+ gem "ruby-lsp"
7
8
  gem "rails", "~> 7.0.0"
8
9
 
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 "appraisal"
7
+ gem "ruby-lsp"
8
+ gem "rails", "~> 7.1.0"
9
+
10
+ gemspec path: "../"
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'action_view/renderer/collection_renderer'
4
+
5
+ class Pbbuilder
6
+ class CollectionRenderer < ::ActionView::CollectionRenderer # :nodoc:
7
+ def initialize(lookup_context, options, &scope)
8
+ super(lookup_context, options)
9
+ @scope = scope
10
+ end
11
+
12
+ private
13
+
14
+ def build_rendered_template(content, template, layout = nil)
15
+ super(content || pb.attributes!, template)
16
+ end
17
+
18
+ def build_rendered_collection(templates, _spacer)
19
+ pb_parent.set!(field, templates.map(&:body))
20
+ end
21
+
22
+ def pb
23
+ @options[:locals].fetch(:pb)
24
+ end
25
+
26
+ def pb_parent
27
+ @options[:locals].fetch(:pb_parent)
28
+ end
29
+
30
+ def field
31
+ @options[:locals].fetch(:field).to_s
32
+ end
33
+ end
34
+ end
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Pbbuilder = Class.new(begin
4
- require 'active_support/proxy_object'
5
- ActiveSupport::ProxyObject
4
+ require 'active_support/proxy_object'
5
+ ActiveSupport::ProxyObject
6
6
  rescue LoadError
7
- require 'active_support/basic_object'
8
- ActiveSupport::BasicObject
7
+ require 'active_support/basic_object'
8
+ ActiveSupport::BasicObject
9
9
  end)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'pbbuilder/collection_renderer'
4
+
3
5
  # PbbuilderTemplate is an extension of Pbbuilder to be used as a Rails template
4
6
  # It adds support for partials.
5
7
  class PbbuilderTemplate < Pbbuilder
@@ -37,6 +39,39 @@ class PbbuilderTemplate < Pbbuilder
37
39
  super(field, *args) do |element|
38
40
  _set_inline_partial(element, kwargs)
39
41
  end
42
+ elsif kwargs.has_key?(:collection) && kwargs.has_key?(:as)
43
+ # pb.friends partial: "racers/racer", as: :racer, collection: [Racer.new(1, "Johnny Test", []), Racer.new(2, "Max Verstappen", [])]
44
+ # collection renderer
45
+ options = kwargs.deep_dup
46
+
47
+ options.reverse_merge! locals: options.except(:partial, :as, :collection, :cached)
48
+ options.reverse_merge! ::PbbuilderTemplate.template_lookup_options
49
+
50
+ collection = options[:collection] || []
51
+ partial = options[:partial]
52
+
53
+ # The way recursive rendering works is that CollectionRenderer needs to be aware of node its currently rendering and parent node,
54
+ # these is no need to know entire "stack" of nodes. CollectionRenderer would traverse to bottom node render that first and then go up in stack.
55
+
56
+ # CollectionRenderer uses locals[:pb] to render the partial as a protobuf message,
57
+ # but also needs locals[:pb_parent] to apply rendered partial to top level protobuf message.
58
+
59
+ # This logic could be found in CollectionRenderer#build_rendered_collection method that we over wrote.
60
+ options[:locals].merge!(pb: ::PbbuilderTemplate.new(@context, new_message_for(field)))
61
+ options[:locals].merge!(pb_parent: self)
62
+ options[:locals].merge!(field: field)
63
+
64
+ if options.has_key?(:layout)
65
+ raise ::NotImplementedError, "The `:layout' option is not supported in collection rendering."
66
+ end
67
+
68
+ if options.has_key?(:spacer_template)
69
+ raise ::NotImplementedError, "The `:spacer_template' option is not supported in collection rendering."
70
+ end
71
+
72
+ CollectionRenderer
73
+ .new(@context.lookup_context, options) { |&block| _scope(message[field.to_s],&block) }
74
+ .render_collection_with_partial(collection, partial, @context, nil)
40
75
  else
41
76
  # pb.best_friend partial: "person", person: @best_friend
42
77
  # Call set! as a submessage, passing in the kwargs as partial options
data/lib/pbbuilder.rb CHANGED
@@ -40,16 +40,20 @@ class Pbbuilder
40
40
  set!(...)
41
41
  end
42
42
 
43
+ def attributes!
44
+ @message.to_h
45
+ end
46
+
43
47
  def respond_to_missing?(field)
44
- !!@message.class.descriptor.lookup(field.to_s)
48
+ !!_descriptor_for_field(field)
45
49
  end
46
50
 
47
51
  def set!(field, *args, &block)
48
52
  name = field.to_s
49
- descriptor = @message.class.descriptor.lookup(name)
53
+ descriptor = _descriptor_for_field(name)
50
54
  ::Kernel.raise ::ArgumentError, "Unknown field #{name}" if descriptor.nil?
51
55
 
52
- if block
56
+ if ::Kernel.block_given?
53
57
  ::Kernel.raise ::ArgumentError, "can't pass block to non-message field" unless descriptor.type == :message
54
58
 
55
59
  if descriptor.label == :repeated
@@ -57,25 +61,28 @@ class Pbbuilder
57
61
  ::Kernel.raise ::ArgumentError, "wrong number of arguments #{args.length} (expected 1)" unless args.length == 1
58
62
  collection = args.first
59
63
  _append_repeated(name, descriptor, collection, &block)
60
- return
64
+ else
65
+ # pb.field { pb.name "hello" }
66
+ ::Kernel.raise ::ArgumentError, "wrong number of arguments (expected 0)" unless args.empty?
67
+ message = (@message[name] ||= _new_message_from_descriptor(descriptor))
68
+ _scope(message, &block)
61
69
  end
62
-
63
- ::Kernel.raise ::ArgumentError, "wrong number of arguments (expected 0)" unless args.empty?
64
- # pb.field { pb.name "hello" }
65
- message = (@message[name] ||= _new_message_from_descriptor(descriptor))
66
- _scope(message, &block)
67
70
  elsif args.length == 1
68
71
  arg = args.first
69
72
  if descriptor.label == :repeated
70
73
  if arg.respond_to?(:to_hash)
71
74
  # pb.fields {"one" => "two"}
72
- arg.to_hash.each do |k, v|
73
- @message[name][k] = v
74
- end
75
- elsif arg.respond_to?(:to_ary)
75
+ arg.to_hash.each { |k, v| @message[name][k] = v }
76
+ elsif arg.respond_to?(:to_ary) && !descriptor.type.eql?(:message)
76
77
  # pb.fields ["one", "two"]
77
78
  # Using concat so it behaves the same as _append_repeated
79
+
78
80
  @message[name].concat arg.to_ary
81
+ elsif arg.respond_to?(:to_ary) && descriptor.type.eql?(:message)
82
+ # pb.friends [Person.new(name: "Johnny Test"), Person.new(name: "Max Verstappen")]
83
+ # Concat another Protobuf message into parent Protobuf message (not ary of strings)
84
+
85
+ args.flatten.each {|obj| @message[name].push descriptor.subtype.msgclass.new(obj)}
79
86
  else
80
87
  # pb.fields "one"
81
88
  @message[name].push arg
@@ -103,10 +110,7 @@ class Pbbuilder
103
110
  end
104
111
 
105
112
  def extract!(element, *args)
106
- args.each do |arg|
107
- value = element.send(arg)
108
- @message[arg.to_s] = value
109
- end
113
+ args.each { |arg| @message[arg.to_s] = element.send(arg) }
110
114
  end
111
115
 
112
116
  # Merges object into a protobuf message, mainly used for caching.
@@ -115,11 +119,11 @@ class Pbbuilder
115
119
  def merge!(object)
116
120
  ::Kernel.raise Pbbuilder::MergeError.build(target!, object) unless object.class == ::Hash
117
121
 
118
- object.each_key do |key|
119
- next if object[key].respond_to?(:empty?) && object[key].empty?
122
+ object.each do |key, value|
123
+ next if value.respond_to?(:empty?) && value.empty?
120
124
 
121
- descriptor = @message.class.descriptor.lookup(key.to_s)
122
- ::Kernel.raise ::ArgumentError, "Unknown field #{name}" if descriptor.nil?
125
+ descriptor = _descriptor_for_field(key)
126
+ ::Kernel.raise ::ArgumentError, "Unknown field #{key}" if descriptor.nil?
123
127
 
124
128
  if descriptor.label == :repeated
125
129
  # optional empty fields don't show up in @message object,
@@ -128,50 +132,26 @@ class Pbbuilder
128
132
  @message[key.to_s] = _new_message_from_descriptor(descriptor)
129
133
  end
130
134
 
131
- if object[key].respond_to?(:to_hash)
132
- object[key].to_hash.each {|k, v| @message[key.to_s][k] = v}
133
- elsif object[key].respond_to?(:to_ary)
134
- elements = object[key].map do |obj|
135
+ if value.respond_to?(:to_hash)
136
+ value.to_hash.each {|k, v| @message[key.to_s][k] = v}
137
+ elsif value.respond_to?(:to_ary)
138
+ elements = value.map do |obj|
135
139
  descriptor.subtype ? descriptor.subtype.msgclass.new(obj) : obj
136
140
  end
137
141
 
138
142
  @message[key.to_s].replace(elements)
139
143
  end
140
144
  else
141
- if object[key].class == ::String
145
+ if descriptor.type == :message
146
+ @message[key.to_s] = descriptor.subtype.msgclass.new(value)
147
+ else
142
148
  # pb.fields {"one" => "two"}
143
- @message[key.to_s] = object[key]
144
- elsif object[key].class == ::TrueClass || object[key].class == ::FalseClass
145
149
  # pb.boolean true || false
146
- @message[key.to_s] = object[key]
147
- elsif object[key].class == ::Array
148
150
  # pb.field_name do
149
151
  # pb.tags ["ok", "cool"]
150
152
  # end
151
153
 
152
- @message[key.to_s] = object[key]
153
- elsif object[key].class == ::Hash
154
- if @message[key.to_s].nil?
155
- @message[key.to_s] = _new_message_from_descriptor(descriptor)
156
- end
157
-
158
- object[key].each do |k, v|
159
- if object[key][k].respond_to?(:to_hash)
160
- if @message[key.to_s][k.to_s].nil?
161
- descriptor = @message[key.to_s].class.descriptor.lookup(k.to_s)
162
- @message[key.to_s][k.to_s] = _new_message_from_descriptor(descriptor)
163
- end
164
-
165
- _scope(@message[key.to_s][k.to_s]) { self.merge!(object[key][k]) }
166
- elsif object[key][k].respond_to?(:to_ary)
167
- @message[key.to_s][k.to_s].replace object[key][k]
168
- else
169
- # Throws an error, if we try to merge nil object into empty value.
170
- next if object[key][k].nil? && @message[key.to_s][k.to_s].nil?
171
-
172
- @message[key.to_s][k.to_s] = object[key][k]
173
- end
174
- end
154
+ @message[key.to_s] = value
175
155
  end
176
156
  end
177
157
  end
@@ -182,8 +162,19 @@ class Pbbuilder
182
162
  @message
183
163
  end
184
164
 
165
+ def new_message_for(field)
166
+ descriptor = _descriptor_for_field(field)
167
+ ::Kernel.raise ::ArgumentError, "Unknown field #{field}" if descriptor.nil?
168
+
169
+ _new_message_from_descriptor(descriptor)
170
+ end
171
+
185
172
  private
186
173
 
174
+ def _descriptor_for_field(field)
175
+ @message.class.descriptor.lookup(field.to_s)
176
+ end
177
+
187
178
  # Appends protobuf message with existing @message object
188
179
  #
189
180
  # @param name string
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.15.1"
5
+ spec.version = "0.16.1"
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"
@@ -12,12 +12,20 @@ class PbbuilderTemplateTest < ActiveSupport::TestCase
12
12
  pb.extract! racer, :name
13
13
  pb.friends racer.friends, partial: "racers/racer", as: :racer
14
14
  pb.best_friend partial: "racers/racer", racer: racer.best_friend if racer.best_friend.present?
15
+ pb.logo partial: "asset", asset: racer.logo if racer.logo.present?
16
+ PBBUILDER
17
+
18
+ ASSET_PARTIAL = <<-PBBUILDER
19
+ pb.url asset.url
20
+ pb.url_2x asset.url
21
+ pb.url_3x asset.url
15
22
  PBBUILDER
16
23
 
17
24
  PARTIALS = {
18
25
  "_partial.pb.pbbuilder" => "pb.name name",
19
26
  "_person.pb.pbbuilder" => PERSON_PARTIAL,
20
27
  "racers/_racer.pb.pbbuilder" => RACER_PARTIAL,
28
+ "_asset.pb.pbbuilder" => ASSET_PARTIAL,
21
29
 
22
30
  # Ensure we find only Pbbuilder partials from within Pbbuilder templates.
23
31
  "_person.html.erb" => "Hello world!"
@@ -30,6 +38,45 @@ class PbbuilderTemplateTest < ActiveSupport::TestCase
30
38
  assert_equal "hello", result.name
31
39
  end
32
40
 
41
+ test "render collections with partial as kwarg" do
42
+ template = <<-PBBUILDER
43
+ more_friends = [Racer.new(4, "Johnny Brave", [], nil, API::Asset.new(url: "https://google.com/test3.svg"))]
44
+ friends_of_racer = [Racer.new(3, "Chris Harris", more_friends, nil, API::Asset.new(url: "https://google.com/test2.svg"))]
45
+ racers = [Racer.new(1, "Johnny Test", friends_of_racer, nil, API::Asset.new(url: "https://google.com/test1.svg")), Racer.new(2, "Max Verstappen", [])]
46
+ pb.friends partial: "racers/racer", as: :racer, collection: racers
47
+ PBBUILDER
48
+ result = render(template)
49
+
50
+ assert_equal 2, result.friends.count
51
+ assert_nil result.logo
52
+ assert_equal "https://google.com/test1.svg", result.friends.first.logo.url
53
+ assert_equal "https://google.com/test2.svg", result.friends.first.friends.first.logo.url
54
+ assert_equal "https://google.com/test3.svg", result.friends.first.friends.first.friends.first.logo.url
55
+ end
56
+
57
+ test "CollectionRenderer: raises an error on a render with :layout option" do
58
+ error = assert_raises NotImplementedError do
59
+ render('pb.friends partial: "racers/racer", as: :racer, layout: "layout", collection: [Racer.new(1, "Johnny Test", []), Racer.new(2, "Max Verstappen", [])]')
60
+ end
61
+
62
+ assert_equal "The `:layout' option is not supported in collection rendering.", error.message
63
+ end
64
+
65
+ test "CollectionRenderer: raises an error on a render with :spacer_template option" do
66
+ error = assert_raises NotImplementedError do
67
+ render('pb.friends partial: "racers/racer", as: :racer, spacer_template: "template", collection: [Racer.new(1, "Johnny Test", []), Racer.new(2, "Max Verstappen", [])]')
68
+ end
69
+
70
+ assert_equal "The `:spacer_template' option is not supported in collection rendering.", error.message
71
+ end
72
+
73
+ test "render collections with partial as arg" do
74
+ skip("This will be addressed in future version of a gem")
75
+ result = render('pb.friends "racers/racer", as: :racer, collection: [Racer.new(1, "Johnny Test", []), Racer.new(2, "Max Verstappen", [])]')
76
+
77
+ assert_equal 2, result.friends.count
78
+ end
79
+
33
80
  test "partial by name with top-level locals" do
34
81
  result = render('pb.partial! "partial", name: "hello"')
35
82
  assert_equal "hello", result.name
data/test/test_helper.rb CHANGED
@@ -46,6 +46,7 @@ end
46
46
 
47
47
  module API
48
48
  Person = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("pbbuildertest.Person").msgclass
49
+ Asset = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("pbbuildertest.Asset").msgclass
49
50
  end
50
51
 
51
52
  class << Rails
@@ -54,7 +55,7 @@ class << Rails
54
55
  end
55
56
  end
56
57
 
57
- class Racer < Struct.new(:id, :name, :friends, :best_friend)
58
+ class Racer < Struct.new(:id, :name, :friends, :best_friend, :logo)
58
59
  extend ActiveModel::Naming
59
60
  include ActiveModel::Conversion
60
61
  end
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.15.1
4
+ version: 0.16.1
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: 2023-06-07 00:00:00.000000000 Z
11
+ date: 2023-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-protobuf
@@ -76,7 +76,6 @@ files:
76
76
  - ".github/dependabot.yml"
77
77
  - ".github/workflows/test.yml"
78
78
  - ".gitignore"
79
- - ".ruby-version"
80
79
  - Appraisals
81
80
  - CHANGELOG.md
82
81
  - Gemfile
@@ -86,10 +85,14 @@ files:
86
85
  - bin/appraisal
87
86
  - bin/test
88
87
  - gemfiles/.bundle/config
88
+ - gemfiles/rails_6.gemfile
89
89
  - gemfiles/rails_6_1.gemfile
90
+ - gemfiles/rails_7.gemfile
90
91
  - gemfiles/rails_7_0.gemfile
92
+ - gemfiles/rails_7_1.gemfile
91
93
  - gemfiles/rails_head.gemfile
92
94
  - lib/pbbuilder.rb
95
+ - lib/pbbuilder/collection_renderer.rb
93
96
  - lib/pbbuilder/errors.rb
94
97
  - lib/pbbuilder/handler.rb
95
98
  - lib/pbbuilder/pbbuilder.rb
@@ -120,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
123
  - !ruby/object:Gem::Version
121
124
  version: '0'
122
125
  requirements: []
123
- rubygems_version: 3.3.7
126
+ rubygems_version: 3.4.20
124
127
  signing_key:
125
128
  specification_version: 4
126
129
  summary: Generate Protobuf Messages with a simple DSL similar to JBuilder
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- 3.1.2