type_struct 0.5.0 → 0.6.0
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 +4 -4
- data/README.md +3 -1
- data/lib/type_struct/exceptions.rb +25 -0
- data/lib/type_struct/version.rb +1 -1
- data/lib/type_struct.rb +120 -89
- data/lib/type_struct_benchmark_test.rb +36 -1
- data/lib/type_struct_test.rb +113 -44
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 155aa214f6353b480dc87c69555db00a31623f7d
|
4
|
+
data.tar.gz: 31e28839d1fa9930ba9fddddf288f32dbeb02dee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56c32708f5d233891dbfeda2a403fffb04d2d8e7a674749a6f6f1c80eadae3f6ac868815299c608cb156585768d0aaffee01a8bff9590530fe7b4d99991885bc
|
7
|
+
data.tar.gz: dffe91d28e705eee66d507a3552d94d2a7ece6bd6d52be9d949643e50eebb3568a4cd7e9ee4c4363b5321b397c332728edb002310d758b810af674ab1a6265c1
|
data/README.md
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
class TypeStruct
|
2
|
+
UnionNotFoundError = Class.new(StandardError)
|
3
|
+
|
4
|
+
class MultiTypeError < StandardError
|
5
|
+
THIS_LIB_REGEXP = %r{lib/type_struct[./]}
|
6
|
+
PWD = Pathname.new(Dir.pwd)
|
7
|
+
attr_reader :errors
|
8
|
+
def initialize(errors)
|
9
|
+
@errors = errors
|
10
|
+
super("\n#{build_message}")
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def build_message
|
16
|
+
@errors.map { |e|
|
17
|
+
b = e.backtrace_locations.find do |b|
|
18
|
+
b.absolute_path !~ THIS_LIB_REGEXP
|
19
|
+
end
|
20
|
+
relative_path = Pathname.new(b.absolute_path).relative_path_from(PWD)
|
21
|
+
"#{relative_path}:#{b.lineno}:in #{e.class} #{e}"
|
22
|
+
}.join("\n")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/type_struct/version.rb
CHANGED
data/lib/type_struct.rb
CHANGED
@@ -1,34 +1,44 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
1
3
|
class TypeStruct
|
2
4
|
require "type_struct/union"
|
3
5
|
require "type_struct/array_of"
|
4
6
|
require "type_struct/hash_of"
|
5
7
|
require "type_struct/interface"
|
8
|
+
require "type_struct/exceptions"
|
6
9
|
require "type_struct/version"
|
7
10
|
|
8
|
-
UnionNotFoundError = Class.new(StandardError)
|
9
|
-
|
10
11
|
def initialize(arg)
|
11
12
|
sym_arg = {}
|
12
13
|
arg.each do |k, v|
|
13
14
|
sym_arg[k.to_sym] = v
|
14
15
|
end
|
15
|
-
|
16
|
-
|
16
|
+
errors = []
|
17
|
+
klass = self.class
|
18
|
+
klass.members.each do |k|
|
19
|
+
unless klass.valid?(k, sym_arg[k])
|
20
|
+
begin
|
21
|
+
raise TypeError, "#{klass}##{k} expect #{klass.type(k)} got #{sym_arg[k].inspect}"
|
22
|
+
rescue TypeError => e
|
23
|
+
errors << e
|
24
|
+
end
|
25
|
+
end
|
26
|
+
instance_variable_set("@#{k}", sym_arg[k])
|
17
27
|
end
|
28
|
+
raise MultiTypeError, errors unless errors.empty?
|
18
29
|
end
|
19
30
|
|
20
31
|
def ==(other)
|
21
32
|
return false unless TypeStruct === other
|
22
|
-
|
23
|
-
true
|
33
|
+
to_h == other.to_h
|
24
34
|
end
|
25
35
|
|
26
36
|
def []=(k, v)
|
27
|
-
__send__
|
37
|
+
__send__ "#{k}=", v
|
28
38
|
end
|
29
39
|
|
30
40
|
def [](k)
|
31
|
-
__send__
|
41
|
+
__send__ k
|
32
42
|
end
|
33
43
|
|
34
44
|
def inspect
|
@@ -47,97 +57,117 @@ class TypeStruct
|
|
47
57
|
m
|
48
58
|
end
|
49
59
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
60
|
+
module ClassMethods
|
61
|
+
def from_hash(h)
|
62
|
+
unless Hash === h
|
63
|
+
h = h.to_hash if h.respond_to?(:to_hash)
|
64
|
+
unless Hash === h
|
65
|
+
raise TypeError, "#{self}.from_hash only accept Hash got `#{h.class}'"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
args = {}
|
69
|
+
errors = []
|
70
|
+
h.each do |key, value|
|
71
|
+
key = key.to_sym
|
72
|
+
t = type(key)
|
73
|
+
args[key] = try_convert(t, key, value, errors)
|
74
|
+
end
|
75
|
+
raise MultiTypeError, errors unless errors.empty?
|
76
|
+
new(args)
|
77
|
+
end
|
55
78
|
|
56
|
-
|
57
|
-
|
79
|
+
def definition
|
80
|
+
const_get(:DEFINITION)
|
81
|
+
end
|
58
82
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
unless Hash === h
|
63
|
-
raise TypeError, "#{self}.from_hash only accept Hash got `#{h.class}'"
|
64
|
-
end
|
65
|
-
end
|
66
|
-
args = {}
|
67
|
-
h.each do |key, value|
|
68
|
-
key = key.to_sym
|
69
|
-
t = type(key)
|
70
|
-
args[key] = try_convert(t, key, value)
|
71
|
-
end
|
72
|
-
new(args)
|
73
|
-
end
|
83
|
+
def members
|
84
|
+
definition.keys
|
85
|
+
end
|
74
86
|
|
75
|
-
|
76
|
-
|
77
|
-
|
87
|
+
def type(k)
|
88
|
+
definition[k]
|
89
|
+
end
|
78
90
|
|
79
|
-
|
80
|
-
|
81
|
-
|
91
|
+
def valid?(k, v)
|
92
|
+
definition[k] === v
|
93
|
+
end
|
82
94
|
|
83
|
-
|
84
|
-
|
95
|
+
private
|
96
|
+
|
97
|
+
def try_convert(klass, key, value, errors)
|
98
|
+
case klass
|
99
|
+
when Union
|
100
|
+
union_errors = []
|
101
|
+
klass.each do |k|
|
102
|
+
begin
|
103
|
+
return try_convert(k, key, value, nil)
|
104
|
+
rescue TypeError, MultiTypeError => e
|
105
|
+
union_errors << e
|
85
106
|
end
|
107
|
+
end
|
86
108
|
|
87
|
-
|
88
|
-
|
109
|
+
raise UnionNotFoundError, "#{klass} is not found with value `#{value}'\nerrors:\n#{union_errors.join("\n")}"
|
110
|
+
when ArrayOf
|
111
|
+
unless Array === value
|
112
|
+
begin
|
113
|
+
raise TypeError, "#{self}##{key} expect #{klass.inspect} got #{value.inspect}"
|
114
|
+
rescue TypeError => e
|
115
|
+
raise unless errors
|
116
|
+
errors << e
|
89
117
|
end
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
if klass.respond_to?(:ancestors)
|
125
|
-
if klass.ancestors.include?(TypeStruct)
|
126
|
-
klass.from_hash(value)
|
127
|
-
elsif klass.ancestors.include?(Struct)
|
128
|
-
struct = klass.new
|
129
|
-
value.each { |k, v| struct[k] = v }
|
130
|
-
struct
|
131
|
-
elsif klass === value
|
132
|
-
value
|
133
|
-
else
|
134
|
-
raise TypeError, "#{self}##{key} expect #{klass.inspect} got #{value.inspect}"
|
135
|
-
end
|
136
|
-
else
|
137
|
-
value
|
138
|
-
end
|
118
|
+
return value
|
119
|
+
end
|
120
|
+
value.map { |v| try_convert(klass.type, key, v, errors) }
|
121
|
+
when HashOf
|
122
|
+
unless Hash === value
|
123
|
+
begin
|
124
|
+
raise TypeError, "#{self}##{key} expect #{klass.inspect} got #{value.inspect}"
|
125
|
+
rescue TypeError => e
|
126
|
+
raise unless errors
|
127
|
+
errors << e
|
128
|
+
end
|
129
|
+
return value
|
130
|
+
end
|
131
|
+
new_hash = {}
|
132
|
+
value.each do |hk, hv|
|
133
|
+
new_hash[hk] = try_convert(klass.value_type, key, hv, errors)
|
134
|
+
end
|
135
|
+
new_hash
|
136
|
+
else
|
137
|
+
if klass.respond_to?(:ancestors)
|
138
|
+
if klass.ancestors.include?(TypeStruct)
|
139
|
+
klass.from_hash(value)
|
140
|
+
elsif klass.ancestors.include?(Struct)
|
141
|
+
struct = klass.new
|
142
|
+
value.each { |k, v| struct[k] = v }
|
143
|
+
struct
|
144
|
+
elsif klass === value
|
145
|
+
value
|
146
|
+
else
|
147
|
+
begin
|
148
|
+
raise TypeError, "#{self}##{key} expect #{klass} got #{value.inspect}"
|
149
|
+
rescue => e
|
150
|
+
raise unless errors
|
151
|
+
errors << e
|
139
152
|
end
|
153
|
+
value
|
140
154
|
end
|
155
|
+
else
|
156
|
+
value
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
class << self
|
163
|
+
alias original_new new
|
164
|
+
def new(**args, &block)
|
165
|
+
c = Class.new(TypeStruct) do
|
166
|
+
extend ClassMethods
|
167
|
+
const_set :DEFINITION, args
|
168
|
+
|
169
|
+
class << self
|
170
|
+
alias_method :new, :original_new
|
141
171
|
end
|
142
172
|
|
143
173
|
args.each_key do |k|
|
@@ -153,6 +183,7 @@ class TypeStruct
|
|
153
183
|
end
|
154
184
|
end
|
155
185
|
end
|
186
|
+
|
156
187
|
if block_given?
|
157
188
|
c.module_eval(&block)
|
158
189
|
end
|
@@ -16,6 +16,40 @@ module TypeStructBenchmarkTest
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
def benchmark_struct_new(b)
|
20
|
+
i = 0
|
21
|
+
while i < b.n
|
22
|
+
Struct.new(:a, :b, :c)
|
23
|
+
i += 1
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def benchmark_new_instance(b)
|
28
|
+
t = TypeStruct.new(
|
29
|
+
a: String,
|
30
|
+
b: Integer,
|
31
|
+
c: Regexp,
|
32
|
+
)
|
33
|
+
hash = { a: "aaa".freeze, b: 1, c: /abc/ }
|
34
|
+
i = 0
|
35
|
+
while i < b.n
|
36
|
+
t.new(hash)
|
37
|
+
i += 1
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def benchmark_struct_new_instance(b)
|
42
|
+
t = Struct.new(:a, :b, :c)
|
43
|
+
a1 = "aaa".freeze
|
44
|
+
a2 = 1
|
45
|
+
a3 = /abc/
|
46
|
+
i = 0
|
47
|
+
while i < b.n
|
48
|
+
t.new(a1, a2, a3)
|
49
|
+
i += 1
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
19
53
|
A = TypeStruct.new(
|
20
54
|
a: Integer,
|
21
55
|
)
|
@@ -34,8 +68,9 @@ module TypeStructBenchmarkTest
|
|
34
68
|
|
35
69
|
def benchmark_from_hash(b)
|
36
70
|
i = 0
|
71
|
+
hash = { e: { d: { c: { b: { a: 1 } } } } }
|
37
72
|
while i < b.n
|
38
|
-
E.from_hash(
|
73
|
+
E.from_hash(hash)
|
39
74
|
i += 1
|
40
75
|
end
|
41
76
|
end
|
data/lib/type_struct_test.rb
CHANGED
@@ -89,7 +89,7 @@ module TypeStructTest
|
|
89
89
|
hc.new(
|
90
90
|
a: [],
|
91
91
|
)
|
92
|
-
rescue
|
92
|
+
rescue TypeStruct::MultiTypeError
|
93
93
|
else
|
94
94
|
t.error("TypeError was not railsed")
|
95
95
|
end
|
@@ -103,7 +103,7 @@ module TypeStructTest
|
|
103
103
|
|
104
104
|
begin
|
105
105
|
hh = hc.from_hash(a: 1)
|
106
|
-
rescue
|
106
|
+
rescue TypeStruct::MultiTypeError
|
107
107
|
else
|
108
108
|
t.error("TypeError dose not raise error")
|
109
109
|
end
|
@@ -114,35 +114,27 @@ module TypeStructTest
|
|
114
114
|
begin
|
115
115
|
hsbn.from_hash(a: [])
|
116
116
|
rescue TypeStruct::UnionNotFoundError
|
117
|
-
rescue => e
|
118
|
-
t.error("Unexpected error #{e.class}: #{e.message}")
|
119
117
|
else
|
120
118
|
t.error("Unexpected behavior")
|
121
119
|
end
|
122
120
|
|
123
121
|
begin
|
124
|
-
hsbn.from_hash(a: {a: {b: 1.1}})
|
122
|
+
hsbn.from_hash(a: { a: { b: 1.1 } })
|
125
123
|
rescue TypeStruct::UnionNotFoundError
|
126
|
-
rescue => e
|
127
|
-
t.error("Unexpected error #{e.class}: #{e.message}")
|
128
124
|
else
|
129
125
|
t.error("Unexpected behavior")
|
130
126
|
end
|
131
127
|
|
132
128
|
begin
|
133
|
-
hsbn.from_hash(a: {"a" => {b: 1}})
|
134
|
-
rescue
|
135
|
-
rescue => e
|
136
|
-
t.error("Unexpected error #{e.class}: #{e.message}")
|
129
|
+
hsbn.from_hash(a: { "a" => { b: 1 } })
|
130
|
+
rescue TypeStruct::MultiTypeError
|
137
131
|
else
|
138
132
|
t.error("Unexpected behavior")
|
139
133
|
end
|
140
134
|
|
141
135
|
begin
|
142
|
-
hsbn.from_hash(a: {"a" => {b: 1.1}})
|
136
|
+
hsbn.from_hash(a: { "a" => { b: 1.1 } })
|
143
137
|
rescue TypeStruct::UnionNotFoundError
|
144
|
-
rescue => e
|
145
|
-
t.error("Unexpected error #{e.class}: #{e.message}")
|
146
138
|
else
|
147
139
|
t.error("Unexpected behavior")
|
148
140
|
end
|
@@ -165,9 +157,7 @@ module TypeStructTest
|
|
165
157
|
a = TypeStruct.new(a: ArrayOf(Integer))
|
166
158
|
begin
|
167
159
|
a.from_hash(a: [1.1])
|
168
|
-
rescue
|
169
|
-
rescue => e
|
170
|
-
t.error("Unexpected error #{e.class}")
|
160
|
+
rescue TypeStruct::MultiTypeError
|
171
161
|
else
|
172
162
|
t.error("Nothing raised TypeError")
|
173
163
|
end
|
@@ -176,8 +166,6 @@ module TypeStructTest
|
|
176
166
|
begin
|
177
167
|
b.from_hash(a: [1.1])
|
178
168
|
rescue TypeStruct::UnionNotFoundError
|
179
|
-
rescue => e
|
180
|
-
t.error("Unexpected error #{e.class}")
|
181
169
|
else
|
182
170
|
t.error("Nothing raised TypeStruct::UnionNotFoundError")
|
183
171
|
end
|
@@ -185,10 +173,8 @@ module TypeStructTest
|
|
185
173
|
c = TypeStruct.new(c: Integer)
|
186
174
|
d = TypeStruct.new(d: ArrayOf(c) | NilClass)
|
187
175
|
begin
|
188
|
-
d.from_hash(d: [{c: 1.1}])
|
176
|
+
d.from_hash(d: [{ c: 1.1 }])
|
189
177
|
rescue TypeStruct::UnionNotFoundError
|
190
|
-
rescue => e
|
191
|
-
t.error("Unexpected error #{e.class}")
|
192
178
|
else
|
193
179
|
t.error("Nothing raised TypeStruct::UnionNotFoundError")
|
194
180
|
end
|
@@ -236,7 +222,7 @@ module TypeStructTest
|
|
236
222
|
|
237
223
|
begin
|
238
224
|
foo.from_hash(bar: { baz: nil })
|
239
|
-
rescue
|
225
|
+
rescue TypeStruct::MultiTypeError
|
240
226
|
else
|
241
227
|
t.error("Bar.baz is not able to nil")
|
242
228
|
end
|
@@ -255,7 +241,7 @@ module TypeStructTest
|
|
255
241
|
end
|
256
242
|
|
257
243
|
def o.to_hash
|
258
|
-
{a: 1}
|
244
|
+
{ a: 1 }
|
259
245
|
end
|
260
246
|
unless a === a.from_hash(o)
|
261
247
|
t.error("Unexpected behavior")
|
@@ -263,30 +249,36 @@ module TypeStructTest
|
|
263
249
|
end
|
264
250
|
|
265
251
|
def test_s_from_hash_with_array_of(t)
|
266
|
-
a = TypeStruct.new(a: ArrayOf(Integer))
|
252
|
+
a = TypeStruct.new(a: ArrayOf(Integer), b: Integer)
|
267
253
|
begin
|
268
|
-
a.from_hash(a: 1)
|
269
|
-
rescue
|
270
|
-
|
271
|
-
|
254
|
+
a.from_hash(a: 1, b: 'a')
|
255
|
+
rescue TypeStruct::MultiTypeError => e
|
256
|
+
[
|
257
|
+
/#a expect ArrayOf\(Integer\) got 1/,
|
258
|
+
/#b expect Integer got "a"/,
|
259
|
+
].each do |expect|
|
260
|
+
unless expect =~ e.message
|
261
|
+
t.error("message was changed: #{e.message}")
|
262
|
+
end
|
272
263
|
end
|
273
|
-
rescue => e
|
274
|
-
t.error("Unexpected error #{e}")
|
275
264
|
else
|
276
265
|
t.error("Unexpected behavior")
|
277
266
|
end
|
278
267
|
end
|
279
268
|
|
280
269
|
def test_s_from_hash_with_hash_of(t)
|
281
|
-
a = TypeStruct.new(a: HashOf(String, Integer))
|
270
|
+
a = TypeStruct.new(a: HashOf(String, Integer), b: Integer)
|
282
271
|
begin
|
283
|
-
a.from_hash(a: 1)
|
284
|
-
rescue
|
285
|
-
|
286
|
-
|
272
|
+
a.from_hash(a: 1, b: 'a')
|
273
|
+
rescue TypeStruct::MultiTypeError => e
|
274
|
+
[
|
275
|
+
/#a expect HashOf\(String, Integer\) got 1/,
|
276
|
+
/#b expect Integer got "a"/,
|
277
|
+
].each do |expect|
|
278
|
+
unless expect =~ e.message
|
279
|
+
t.error("message was changed: #{e.message}")
|
280
|
+
end
|
287
281
|
end
|
288
|
-
rescue => e
|
289
|
-
t.error("Unexpected error #{e}")
|
290
282
|
else
|
291
283
|
t.error("Unexpected behavior")
|
292
284
|
end
|
@@ -296,7 +288,7 @@ module TypeStructTest
|
|
296
288
|
a = TypeStruct.new(a: "a")
|
297
289
|
begin
|
298
290
|
a.from_hash(a: "b")
|
299
|
-
rescue
|
291
|
+
rescue TypeStruct::MultiTypeError
|
300
292
|
else
|
301
293
|
t.error("Unexpected behavior")
|
302
294
|
end
|
@@ -309,11 +301,7 @@ module TypeStructTest
|
|
309
301
|
u = TypeStruct::Union.new(a, b, c)
|
310
302
|
d = TypeStruct.new(d: u)
|
311
303
|
|
312
|
-
|
313
|
-
d.from_hash(d: { b: 1 })
|
314
|
-
rescue => e
|
315
|
-
t.error("Unexpected error was raised #{e.class}: #{e.message}")
|
316
|
-
end
|
304
|
+
d.from_hash(d: { b: 1 })
|
317
305
|
|
318
306
|
begin
|
319
307
|
d.from_hash(d: [b: 1])
|
@@ -516,6 +504,87 @@ module TypeStructTest
|
|
516
504
|
end
|
517
505
|
end
|
518
506
|
|
507
|
+
def test_multi_type_error(t)
|
508
|
+
a = TypeStruct.new(
|
509
|
+
a: Integer,
|
510
|
+
b: Integer,
|
511
|
+
c: Integer,
|
512
|
+
)
|
513
|
+
begin
|
514
|
+
a.new(
|
515
|
+
a: 'a',
|
516
|
+
b: 1,
|
517
|
+
c: '1',
|
518
|
+
)
|
519
|
+
rescue TypeStruct::MultiTypeError => err
|
520
|
+
unless err.errors.all? { |e| TypeError === e }
|
521
|
+
t.error("Empty errors")
|
522
|
+
end
|
523
|
+
|
524
|
+
[
|
525
|
+
/a expect Integer got "a"/,
|
526
|
+
/c expect Integer got "1"/,
|
527
|
+
].each do |reg|
|
528
|
+
unless reg =~ err.message
|
529
|
+
t.error("should match error message #{reg} got #{err.message}")
|
530
|
+
end
|
531
|
+
end
|
532
|
+
rescue => err
|
533
|
+
raise err
|
534
|
+
else
|
535
|
+
t.error("Nothing raised an error")
|
536
|
+
end
|
537
|
+
end
|
538
|
+
|
539
|
+
def test_s_from_hash_multi_type_error(t)
|
540
|
+
a = TypeStruct.new(
|
541
|
+
a: Integer,
|
542
|
+
b: String,
|
543
|
+
c: ArrayOf(String),
|
544
|
+
)
|
545
|
+
b = TypeStruct.new(
|
546
|
+
b: a,
|
547
|
+
)
|
548
|
+
begin
|
549
|
+
b.from_hash(b: { a: '1', b: 1, c: /a/ })
|
550
|
+
rescue TypeStruct::MultiTypeError => err
|
551
|
+
unless err.errors.all? { |e| TypeError === e }
|
552
|
+
t.error("Empty errors")
|
553
|
+
end
|
554
|
+
|
555
|
+
[
|
556
|
+
/a expect Integer got "1"/,
|
557
|
+
/b expect String got 1/,
|
558
|
+
%r{c expect ArrayOf\(String\) got /a/},
|
559
|
+
].each do |reg|
|
560
|
+
unless reg =~ err.message
|
561
|
+
t.error("should match error message #{reg} got #{err.message}")
|
562
|
+
end
|
563
|
+
end
|
564
|
+
end
|
565
|
+
end
|
566
|
+
|
567
|
+
def test_s_from_hash_multi_type_error_with_union(t)
|
568
|
+
a = TypeStruct.new(
|
569
|
+
a: ArrayOf(String) | NilClass,
|
570
|
+
)
|
571
|
+
b = TypeStruct.new(
|
572
|
+
b: a,
|
573
|
+
)
|
574
|
+
begin
|
575
|
+
b.from_hash(b: { a: '1' })
|
576
|
+
rescue TypeStruct::UnionNotFoundError => err
|
577
|
+
[
|
578
|
+
/a expect ArrayOf\(String\) got "1"/,
|
579
|
+
/a expect NilClass got "1"/,
|
580
|
+
].each do |reg|
|
581
|
+
unless reg =~ err.message
|
582
|
+
t.error("should match error message #{reg} got #{err.message}")
|
583
|
+
end
|
584
|
+
end
|
585
|
+
end
|
586
|
+
end
|
587
|
+
|
519
588
|
def test_getter(t)
|
520
589
|
dummy = Dummy.new(str: "aaa", num: 123, reg: "abc", any: [1, "bbb"])
|
521
590
|
_, err = go { dummy[:str] }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: type_struct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ksss
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-04-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -68,6 +68,7 @@ files:
|
|
68
68
|
- lib/type_struct.rb
|
69
69
|
- lib/type_struct/array_of.rb
|
70
70
|
- lib/type_struct/array_of_test.rb
|
71
|
+
- lib/type_struct/exceptions.rb
|
71
72
|
- lib/type_struct/ext.rb
|
72
73
|
- lib/type_struct/hash_of.rb
|
73
74
|
- lib/type_struct/hash_of_test.rb
|
@@ -99,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
100
|
version: '0'
|
100
101
|
requirements: []
|
101
102
|
rubyforge_project:
|
102
|
-
rubygems_version: 2.6.
|
103
|
+
rubygems_version: 2.6.2
|
103
104
|
signing_key:
|
104
105
|
specification_version: 4
|
105
106
|
summary: Imitating static typed struct.
|