polyfill-data 1.0.3 → 1.0.5

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: 20b2218a1dd7298ead1e7bd8f08502558a2828f7aef9a5be33424084bd2d1c9b
4
- data.tar.gz: fc1c0a53cab242883ffcae75f523a959e5a9b273c14f9e8fd334f5db78875802
3
+ metadata.gz: 159535856d8a85a17e4a90dff438911c7e3a04fcff60b1a016662f97e2575e68
4
+ data.tar.gz: c83127bfa5a28bd26dccfcdfbe0b095236136635c3180720cab55912a2fa9796
5
5
  SHA512:
6
- metadata.gz: 9291cd87f95c34b47e5a32f87bffa79f5eca7d0419c1fc741ee88ca3e3518a7435b63c827db569a2960b7fb3d516a408058db3a7fbde49f2dc1328d8dcc5109d
7
- data.tar.gz: df56331c22ecc1ce85aaf5f2e743230b944f07298b1fdc248a337c3731628152f5fffc699d4eaa6ca3490767ff71ab23ea5cb98bbe9dd3f778fbe525c46e9807
6
+ metadata.gz: 2527a6f9e79192cf29d798ee4eb34059e1562690d9b9e8afd921a421b816cefe6f888273d29f6d186a42f459d35217b5639e8eca505235d72c35434fcaa07177
7
+ data.tar.gz: f3a3fe35c950d650a13831df4fb6eabe97eac73b6dd2f55ad518a12180d74202a30492c0fad50caa854dea57d9534bf9d60c9658be0f996f752632dd694c84e7
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## 1.0.5
9
+
10
+ ### Fixed
11
+
12
+ - member methods take precedence over methods defined in the block passed to `define`
13
+
14
+ ## 1.0.4
15
+
16
+ ### Fixed
17
+
18
+ - loading from `Marshal.load` will create a frozen object
19
+ - `dup` will return a frozen object
20
+ - `define` cannot be used on Data subclasses
21
+ - `with` returns `self` when given no arguments
22
+
8
23
  ## 1.0.3
9
24
 
10
25
  ### Fixed
data/lib/data.rb CHANGED
@@ -9,18 +9,26 @@ else
9
9
  class Data < Object
10
10
  class << self
11
11
  undef_method :new
12
+ attr_reader :members
12
13
  end
13
14
 
14
15
  def self.define(*args, &block)
15
16
  raise ArgumentError if args.any?(/=/)
16
- klass = ::Class.new(self, &block)
17
+ if block
18
+ mod = Module.new
19
+ mod.define_singleton_method(:_,) do |klass|
20
+ klass.class_eval(&block)
21
+ end
22
+ arity_converter = mod.method(:_)
23
+ end
24
+ klass = ::Class.new(self)
17
25
 
18
26
  if args.first.is_a?(String)
19
27
  name = args.shift
20
28
  Data.const_set(name, klass)
21
29
  end
22
30
 
23
- klass.define_singleton_method(:members) { args.map{ _1.intern } }
31
+ klass.instance_variable_set(:@members, args)
24
32
 
25
33
  klass.define_singleton_method(:new) do |*new_args, **new_kwargs, &block|
26
34
  init_kwargs = if new_args.any?
@@ -34,8 +42,10 @@ else
34
42
  instance.send(:initialize, **init_kwargs, &block)
35
43
  end.freeze
36
44
  end
45
+
37
46
  class << klass
38
47
  alias_method :[], :new
48
+ undef_method :define
39
49
  end
40
50
 
41
51
  args.map do |arg|
@@ -47,6 +57,10 @@ else
47
57
  end
48
58
  end
49
59
 
60
+ if arity_converter
61
+ klass.class_eval(&arity_converter)
62
+ end
63
+
50
64
  klass
51
65
  end
52
66
 
@@ -97,17 +111,36 @@ else
97
111
  end
98
112
 
99
113
  def inspect
100
- name = ["data", self.class.name].compact.join(" ")
101
114
  attribute_markers = @attributes.map do |key, value|
102
115
  insect_key = key.to_s.start_with?("@") ? ":#{key}" : key
103
116
  "#{insect_key}=#{value}"
104
- end
105
- %(#<#{name} #{attribute_markers.join(", ")}>)
117
+ end.join(", ")
118
+
119
+ display = ["data", self.class.name, attribute_markers].compact.join(" ")
120
+
121
+ "#<#{display}>"
106
122
  end
107
123
  alias_method :to_s, :inspect
108
124
 
109
125
  def with(**kwargs)
126
+ return self if kwargs.empty?
127
+
110
128
  self.class.new(**@attributes.merge(kwargs))
111
129
  end
130
+
131
+ private
132
+
133
+ def marshal_dump
134
+ @attributes
135
+ end
136
+
137
+ def marshal_load(attributes)
138
+ @attributes = attributes
139
+ freeze
140
+ end
141
+
142
+ def initialize_copy(source)
143
+ super.freeze
144
+ end
112
145
  end
113
146
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Polyfill
4
4
  module Data
5
- VERSION = "1.0.3"
5
+ VERSION = "1.0.5"
6
6
  end
7
7
  end
data/test/test_data.rb CHANGED
@@ -13,6 +13,8 @@ class TestData < Minitest::Test
13
13
 
14
14
  # Because some code is shared with Struct, check we don't share unnecessary functionality
15
15
  assert_raises(TypeError) { Data.define(:foo, keyword_init: true) }
16
+
17
+ refute_respond_to(Data.define, :define, "Cannot define from defined Data class")
16
18
  end
17
19
 
18
20
  def test_define_edge_cases
@@ -59,6 +61,7 @@ class TestData < Minitest::Test
59
61
  assert_equal(1, test.foo)
60
62
  assert_equal(2, test.bar)
61
63
  assert_equal(test, klass.new(1, 2))
64
+ assert_predicate(test, :frozen?)
62
65
 
63
66
  # Keywords
64
67
  test_kw = klass.new(foo: 1, bar: 2)
@@ -121,8 +124,6 @@ class TestData < Minitest::Test
121
124
  test = klass.new(bar: 2, foo: 1)
122
125
  assert_equal([1, 2], test.deconstruct)
123
126
 
124
- assert_predicate(test, :frozen?)
125
-
126
127
  assert_kind_of(Integer, test.hash)
127
128
  end
128
129
 
@@ -165,6 +166,65 @@ class TestData < Minitest::Test
165
166
  refute_operator(o1, :eql?, o3)
166
167
  end
167
168
 
169
+ def test_with
170
+ klass = Data.define(:foo, :bar)
171
+ source = klass.new(foo: 1, bar: 2)
172
+
173
+ # Simple
174
+ test = source.with
175
+ assert_equal(source.object_id, test.object_id)
176
+
177
+ # Changes
178
+ test = source.with(foo: 10)
179
+
180
+ assert_equal(1, source.foo)
181
+ assert_equal(2, source.bar)
182
+ assert_equal(source, klass.new(foo: 1, bar: 2))
183
+
184
+ assert_equal(10, test.foo)
185
+ assert_equal(2, test.bar)
186
+ assert_equal(test, klass.new(foo: 10, bar: 2))
187
+
188
+ test = source.with(foo: 10, bar: 20)
189
+
190
+ assert_equal(1, source.foo)
191
+ assert_equal(2, source.bar)
192
+ assert_equal(source, klass.new(foo: 1, bar: 2))
193
+
194
+ assert_equal(10, test.foo)
195
+ assert_equal(20, test.bar)
196
+ assert_equal(test, klass.new(foo: 10, bar: 20))
197
+
198
+ # Keyword splat
199
+ changes = { foo: 10, bar: 20 }
200
+ test = source.with(**changes)
201
+
202
+ assert_equal(1, source.foo)
203
+ assert_equal(2, source.bar)
204
+ assert_equal(source, klass.new(foo: 1, bar: 2))
205
+
206
+ assert_equal(10, test.foo)
207
+ assert_equal(20, test.bar)
208
+ assert_equal(test, klass.new(foo: 10, bar: 20))
209
+
210
+ # Wrong protocol
211
+ assert_raises(ArgumentError, "wrong number of arguments (given 1, expected 0)") do
212
+ source.with(10)
213
+ end
214
+ assert_raises(ArgumentError, "unknown keywords: :baz, :quux") do
215
+ source.with(foo: 1, bar: 2, baz: 3, quux: 4)
216
+ end
217
+ assert_raises(ArgumentError, "wrong number of arguments (given 1, expected 0)") do
218
+ source.with(1, bar: 2)
219
+ end
220
+ assert_raises(ArgumentError, "wrong number of arguments (given 2, expected 0)") do
221
+ source.with(1, 2)
222
+ end
223
+ assert_raises(ArgumentError, "wrong number of arguments (given 1, expected 0)") do
224
+ source.with({ bar: 2 })
225
+ end unless RUBY_VERSION < "2.8.0"
226
+ end
227
+
168
228
  def test_memberless
169
229
  klass = Data.define
170
230
 
@@ -187,9 +247,47 @@ class TestData < Minitest::Test
187
247
  assert_equal('km', distance.unit)
188
248
  end
189
249
 
250
+ def test_dup
251
+ klass = Data.define(:foo, :bar)
252
+ test = klass.new(foo: 1, bar: 2)
253
+ assert_equal(klass.new(foo: 1, bar: 2), test.dup)
254
+ assert_predicate(test.dup, :frozen?)
255
+ end
256
+
257
+ Klass = Data.define(:foo, :bar)
258
+
259
+ def test_marshal
260
+ test = Klass.new(foo: 1, bar: 2)
261
+ loaded = Marshal.load(Marshal.dump(test))
262
+ assert_equal(test, loaded)
263
+ refute_same(test, loaded)
264
+ assert_predicate(loaded, :frozen?)
265
+ end
266
+
190
267
  def test_namespaced_constant
191
268
  klass = Data.define("Measure", :amount, :unit)
192
269
 
193
270
  assert_equal(Data::Measure, klass)
194
271
  end
272
+
273
+ def test_member_precedence
274
+ name_mod = Module.new do
275
+ def name
276
+ "default name"
277
+ end
278
+
279
+ def other
280
+ "other"
281
+ end
282
+ end
283
+
284
+ klass = Data.define(:name) do
285
+ include name_mod
286
+ end
287
+
288
+ data = klass.new("test")
289
+
290
+ assert_equal("test", data.name)
291
+ assert_equal("other", data.other)
292
+ end
195
293
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: polyfill-data
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Gay
@@ -34,9 +34,9 @@ cert_chain:
34
34
  dxkiKqcX+yzo9RJLD9l/E1AWX125r1Fhiif4l6ehdl7Vllc3NQUOm1abdmHtCYjw
35
35
  dG3yPWBWzzN4ovoBRqsuTJbF1wjkCjl5ex5KhfYbeDc=
36
36
  -----END CERTIFICATE-----
37
- date: 2023-01-22 00:00:00.000000000 Z
37
+ date: 2023-01-24 00:00:00.000000000 Z
38
38
  dependencies: []
39
- description: Add the ruby 3.2 Data class to older rubies
39
+ description: Add the ruby 3.2 Data class to older rubies. Do nothing in 3.2
40
40
  email:
41
41
  - jim@saturnflyer.com
42
42
  executables: []
@@ -76,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
78
  requirements: []
79
- rubygems_version: 3.1.6
79
+ rubygems_version: 3.2.27
80
80
  signing_key:
81
81
  specification_version: 4
82
82
  summary: Add the ruby 3.2 Data class to older rubies
metadata.gz.sig CHANGED
Binary file