polyfill-data 1.0.3 → 1.0.5

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: 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