type_struct 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|