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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +15 -0
- data/lib/data.rb +32 -2
- data/lib/polyfill/data/version.rb +1 -1
- data/test/test_data.rb +80 -3
- data.tar.gz.sig +0 -0
- metadata +3 -3
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 62f13af5e73dbe544ce73a294748dee539285c7f8405ec7e68f4d2187b51364c
|
4
|
+
data.tar.gz: 0d4c325885a85e5ced977b50e38af25d44508d6c85a7d6e02f512a9e56d2dff8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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
|
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
|
-
|
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.
|
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-
|
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
|