polyfill-data 1.0.2 → 1.0.4

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: 156f764bced601a2ebf8cc7a6ee095d63a4d3f813ee3e9fe7c3b273ce68f007f
4
- data.tar.gz: d7425307509c331ac61c33541da58effcbbb1f5b6ce675ede734b27c2acf0ed3
3
+ metadata.gz: 62f13af5e73dbe544ce73a294748dee539285c7f8405ec7e68f4d2187b51364c
4
+ data.tar.gz: 0d4c325885a85e5ced977b50e38af25d44508d6c85a7d6e02f512a9e56d2dff8
5
5
  SHA512:
6
- metadata.gz: 76a56991f1759077af526ef30236fcde606cd7fdc4dd9b5264e6d3012ad02e5a27feafa2dcf6900a54cd47e25525ee221702e07f41b6178f5cbb3cb7c4c2abfc
7
- data.tar.gz: 995d6359685044724e2fda6a31e8dab8c73cbdee97dc49034ef7c45ee39a04a3a05ab7ec3046f78705e931316e2957a0992cbe3b3a36c1fd7d43794e89ee22ca
6
+ metadata.gz: 73f956793df2920f6c13d564d56592c72a19327ed9451dd536c3f69a8057038775e5a02e1ec8962f85c135d588b0d54df8f337297eaf18f992e6d29ce910d6de
7
+ data.tar.gz: 25d0e20f500b2715c2ec352f8f2a46150832e40a9482f782450b2e0b2ebe3d9c6f78cafa19fc978b8fa78569771d22d10626b423ba71e555aa05f42112d38d03
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.4
9
+
10
+ ### Fixed
11
+
12
+ - loading from `Marshal.load` will create a frozen object
13
+ - `dup` will return a frozen object
14
+ - `define` cannot be used on Data subclasses
15
+ - `with` returns `self` when given no arguments
16
+
17
+ ## 1.0.3
18
+
19
+ ### Fixed
20
+
21
+ - `new` correctly raises ArugmentErrors with incorrect arguments on Data subclasses
22
+
8
23
  ## 1.0.2
9
24
 
10
25
  ### Fixed
data/lib/data.rb CHANGED
@@ -9,6 +9,7 @@ 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)
@@ -20,11 +21,11 @@ else
20
21
  Data.const_set(name, klass)
21
22
  end
22
23
 
23
- klass.define_singleton_method(:members) { args.map{ _1.intern } }
24
+ klass.instance_variable_set(:@members, args)
24
25
 
25
26
  klass.define_singleton_method(:new) do |*new_args, **new_kwargs, &block|
26
-
27
27
  init_kwargs = if new_args.any?
28
+ raise ArgumentError, "unknown arguments #{new_args[members.size..].join(', ')}" if new_args.size > members.size
28
29
  Hash[members.take(new_args.size).zip(new_args)]
29
30
  else
30
31
  new_kwargs
@@ -36,6 +37,7 @@ else
36
37
  end
37
38
  class << klass
38
39
  alias_method :[], :new
40
+ undef_method :define
39
41
  end
40
42
 
41
43
  args.map do |arg|
@@ -55,6 +57,17 @@ else
55
57
  end
56
58
 
57
59
  def initialize(**kwargs)
60
+ kwargs_size = kwargs.size
61
+ members_size = members.size
62
+
63
+ if kwargs_size > members_size
64
+ extras = kwargs.reject{|k, _v| members.include?(k) }.keys
65
+ raise ArgumentError, "unknown arguments #{extras.join(', ')}"
66
+ elsif kwargs_size < members_size
67
+ missing = members.select {|k, _v| !kwargs.include?(k) }
68
+ raise ArgumentError, "missing arguments #{missing.map{ ":#{_1}" }.join(', ')}"
69
+ end
70
+
58
71
  @attributes = Hash[members.map {|m| [m,kwargs[m]] }]
59
72
  end
60
73
 
@@ -96,7 +109,24 @@ else
96
109
  alias_method :to_s, :inspect
97
110
 
98
111
  def with(**kwargs)
112
+ return self if kwargs.empty?
113
+
99
114
  self.class.new(**@attributes.merge(kwargs))
100
115
  end
116
+
117
+ private
118
+
119
+ def marshal_dump
120
+ @attributes
121
+ end
122
+
123
+ def marshal_load(attributes)
124
+ @attributes = attributes
125
+ freeze
126
+ end
127
+
128
+ def initialize_copy(source)
129
+ super.freeze
130
+ end
101
131
  end
102
132
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Polyfill
4
4
  module Data
5
- VERSION = "1.0.2"
5
+ VERSION = "1.0.4"
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)
@@ -86,7 +89,7 @@ class TestData < Minitest::Test
86
89
  super(foo: 1, bar: 2) # so we can experiment with passing wrong numbers of args
87
90
  end
88
91
  end
89
- # require 'debug'; debugger
92
+
90
93
  assert_equal([[], {foo: 1, bar: 2}], klass.new(foo: 1, bar: 2).passed)
91
94
 
92
95
  # Positional arguments are converted to keyword ones
@@ -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,6 +247,23 @@ 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
 
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.2
4
+ version: 1.0.4
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-21 00:00:00.000000000 Z
37
+ date: 2023-01-22 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: []
metadata.gz.sig CHANGED
Binary file