type_struct 0.2.1 → 0.3.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 +41 -5
- data/lib/type_struct.rb +37 -57
- data/lib/type_struct/{arrayof.rb → array_of.rb} +4 -7
- data/lib/type_struct/array_of_test.rb +38 -0
- data/lib/type_struct/ext.rb +4 -5
- data/lib/type_struct/hash_of.rb +24 -0
- data/lib/type_struct/hash_of_test.rb +41 -0
- data/lib/type_struct/interface.rb +35 -0
- data/lib/type_struct/interface_test.rb +58 -0
- data/lib/type_struct/union.rb +6 -0
- data/lib/type_struct/union_test.rb +7 -0
- data/lib/type_struct/version.rb +1 -1
- data/lib/type_struct_test.rb +107 -8
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e2cfa24de41d389c4673dbfb4ed687240ce20657
|
4
|
+
data.tar.gz: 601c08537cfc0b5611c56c84dc038be39c126d07
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49c262034c7d567bd0a9a92750f2252d159d65d6b907cff5482fef960c4c018781e072686bb30da35630d7b54cde69b4e728cab050dfd71c76439d5fcbc3347f
|
7
|
+
data.tar.gz: 45c7fdf89ea4980a161cba41d09ef89fbf6375f1e25a4a7f78a00dfe2d771145e30a8da28b647330ea765dcdc220c9f37611d228dad3d5b4185253065dde8845
|
data/README.md
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
|
5
5
|
Imitating static typed struct.
|
6
6
|
|
7
|
+
All type is checked by `===` method.
|
8
|
+
|
7
9
|
## Usage
|
8
10
|
|
9
11
|
### Check type
|
@@ -38,6 +40,8 @@ sample.str = 1 #=> TypeError
|
|
38
40
|
|
39
41
|
### Mapping from Hash
|
40
42
|
|
43
|
+
Generate object from hash recursive
|
44
|
+
|
41
45
|
```ruby
|
42
46
|
Point = TypeStruct.new(
|
43
47
|
x: Integer,
|
@@ -61,14 +65,15 @@ line.stort
|
|
61
65
|
#=> NoMethodError
|
62
66
|
```
|
63
67
|
|
64
|
-
##
|
68
|
+
## Four special notation
|
65
69
|
|
66
70
|
### Union
|
67
71
|
|
72
|
+
Union is a object express class that some classes as one class like crystal `Union`.
|
73
|
+
|
68
74
|
```ruby
|
69
|
-
require "union"
|
70
75
|
Foo = TypeStruct.new(
|
71
|
-
bar: Union.new(TrueClass, FalseClass)
|
76
|
+
bar: TypeStruct::Union.new(TrueClass, FalseClass)
|
72
77
|
)
|
73
78
|
p Foo.new(bar: false) #=> #<Foo bar=false>
|
74
79
|
```
|
@@ -76,7 +81,7 @@ p Foo.new(bar: false) #=> #<Foo bar=false>
|
|
76
81
|
or
|
77
82
|
|
78
83
|
```ruby
|
79
|
-
require "
|
84
|
+
require "type_struct/ext"
|
80
85
|
using UnionExt
|
81
86
|
Foo = TypeStruct.new(
|
82
87
|
bar: TrueClass | FalseClass,
|
@@ -85,16 +90,46 @@ Foo = TypeStruct.new(
|
|
85
90
|
|
86
91
|
### ArrayOf
|
87
92
|
|
93
|
+
ArrayOf is a object express array type.
|
94
|
+
|
88
95
|
```ruby
|
89
96
|
Bar = TypeStruct.new(
|
90
|
-
baz: ArrayOf.new(Integer),
|
97
|
+
baz: TypeStruct::ArrayOf.new(Integer),
|
91
98
|
)
|
92
99
|
p Bar.new(baz: [1, 2, 3]) #=> #<Bar baz=[1, 2, 3]>
|
93
100
|
```
|
94
101
|
|
102
|
+
### HashOf
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
Baz = TypeStruct.new(
|
106
|
+
qux: TypeStruct::HashOf.new(String, TypeStruct::ArrayOf.new(Integer))
|
107
|
+
)
|
108
|
+
p Baz.new(qux: { "a" => [1, 2, 3] }) #=> #<Baz qux={"a"=>[1, 2, 3]}>
|
109
|
+
p Baz.from_hash(qux: { "a" => [1, 2, 3] }) #<Baz qux={"a"=>[1, 2, 3]}>
|
110
|
+
p Baz.new(qux: { :a => [1, 2, 3] }) #=> TypeError
|
111
|
+
p Baz.new(qux: { "a" => [1, 2, nil] }) #=> TypeError
|
112
|
+
```
|
113
|
+
|
114
|
+
### Interface
|
115
|
+
|
116
|
+
Interface is a object for duck typing like golang `interface`.
|
117
|
+
|
118
|
+
`Interface#===` check all method using `respond_to?`
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
Foo = TypeStruct.new(
|
122
|
+
bar: TypeStruct::Interface.new(:read, :write)
|
123
|
+
# or Interface.new(:read, :write) on required 'type_struct/ext'
|
124
|
+
)
|
125
|
+
Foo.new(bar: $stdin)
|
126
|
+
Foo.new(bar: 1) #=> TypeError
|
127
|
+
```
|
128
|
+
|
95
129
|
### Mix
|
96
130
|
|
97
131
|
```ruby
|
132
|
+
require "type_struct/ext"
|
98
133
|
using UnionExt
|
99
134
|
Baz = TypeStruct.new(
|
100
135
|
qux: ArrayOf.new(Integer | TrueClass | FalseClass) | NilClass
|
@@ -103,6 +138,7 @@ p Baz.new(qux: [1]) #=> #<AAA::Baz qux=[1]>
|
|
103
138
|
p Baz.new(qux: [true, false]) #=> #<AAA::Baz qux=[true, false]>
|
104
139
|
p Baz.new(qux: nil) #=> #<AAA::Baz qux=nil>
|
105
140
|
p Baz.new(qux: 1) #=> TypeError
|
141
|
+
p Baz.from_hash(qux: [1, 2, false, true]) #=> #<A::Baz qux=[1, 2, false, true]>
|
106
142
|
```
|
107
143
|
|
108
144
|
## Installation
|
data/lib/type_struct.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
require "type_struct/union"
|
2
|
-
require "type_struct/arrayof"
|
3
|
-
|
4
1
|
class TypeStruct
|
2
|
+
require "type_struct/union"
|
3
|
+
require "type_struct/array_of"
|
4
|
+
require "type_struct/hash_of"
|
5
|
+
require "type_struct/interface"
|
5
6
|
require "type_struct/version"
|
6
7
|
|
7
|
-
|
8
|
-
end
|
8
|
+
UnionNotFoundError = Class.new(StandardError)
|
9
9
|
|
10
10
|
def initialize(arg)
|
11
11
|
sym_arg = {}
|
@@ -37,6 +37,7 @@ class TypeStruct
|
|
37
37
|
end
|
38
38
|
"#<#{self.class} #{m.join(', ')}>"
|
39
39
|
end
|
40
|
+
alias to_s inspect
|
40
41
|
|
41
42
|
def to_h
|
42
43
|
m = {}
|
@@ -48,27 +49,43 @@ class TypeStruct
|
|
48
49
|
|
49
50
|
class << self
|
50
51
|
def try_convert(klass, value)
|
51
|
-
return nil unless klass
|
52
|
+
return nil unless !klass.nil? && !value.nil?
|
52
53
|
|
53
54
|
if Union === klass
|
55
|
+
errors = []
|
54
56
|
klass.each do |k|
|
55
|
-
t =
|
57
|
+
t = begin
|
58
|
+
try_convert(k, value)
|
59
|
+
rescue TypeError => e
|
60
|
+
errors << e
|
61
|
+
nil
|
62
|
+
end
|
56
63
|
return t if !t.nil?
|
57
64
|
end
|
58
|
-
|
65
|
+
raise UnionNotFoundError, "#{klass} is not found with errors:\n#{errors.join("\n")}"
|
59
66
|
elsif ArrayOf === klass
|
60
67
|
value.map { |v| try_convert(klass.type, v) }
|
61
|
-
elsif klass
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
68
|
+
elsif HashOf === klass
|
69
|
+
return value unless Hash === value
|
70
|
+
new_hash = {}
|
71
|
+
value.each do |hk, hv|
|
72
|
+
new_hash[hk] = try_convert(klass.value_type, hv)
|
73
|
+
end
|
74
|
+
new_hash
|
75
|
+
elsif klass.respond_to?(:ancestors)
|
76
|
+
if klass.ancestors.include?(TypeStruct)
|
77
|
+
return nil unless Hash === value
|
78
|
+
klass.from_hash(value)
|
79
|
+
elsif klass.ancestors.include?(Struct)
|
80
|
+
struct = klass.new
|
81
|
+
value.each { |k, v| struct[k] = v }
|
82
|
+
struct
|
83
|
+
else
|
84
|
+
value
|
85
|
+
end
|
67
86
|
else
|
68
87
|
value
|
69
88
|
end
|
70
|
-
rescue
|
71
|
-
nil
|
72
89
|
end
|
73
90
|
|
74
91
|
def from_hash(h)
|
@@ -76,28 +93,7 @@ class TypeStruct
|
|
76
93
|
h.each do |key, value|
|
77
94
|
key = key.to_sym
|
78
95
|
t = type(key)
|
79
|
-
|
80
|
-
case
|
81
|
-
when t.ancestors.include?(TypeStruct)
|
82
|
-
args[key] = t.from_hash(value)
|
83
|
-
when t.ancestors.include?(Struct)
|
84
|
-
struct = t.new
|
85
|
-
value.each { |k, v| struct[k] = v }
|
86
|
-
args[key] = struct
|
87
|
-
when t.respond_to?(:new)
|
88
|
-
args[key] = t.new(value)
|
89
|
-
else
|
90
|
-
args[key] = value
|
91
|
-
end
|
92
|
-
elsif ArrayOf === t
|
93
|
-
args[key] = if value.respond_to?(:map)
|
94
|
-
value.map { |v| try_convert(t.type, v) }
|
95
|
-
else
|
96
|
-
value
|
97
|
-
end
|
98
|
-
else
|
99
|
-
args[key] = try_convert(t, value)
|
100
|
-
end
|
96
|
+
args[key] = try_convert(t, value)
|
101
97
|
end
|
102
98
|
new(args)
|
103
99
|
end
|
@@ -111,26 +107,11 @@ class TypeStruct
|
|
111
107
|
end
|
112
108
|
|
113
109
|
def type(k)
|
114
|
-
|
115
|
-
if Hash === t
|
116
|
-
t[:type]
|
117
|
-
else
|
118
|
-
t
|
119
|
-
end
|
110
|
+
definition[k]
|
120
111
|
end
|
121
112
|
|
122
113
|
def valid?(k, v)
|
123
|
-
|
124
|
-
if ArrayOf === t && Array === v
|
125
|
-
v.all? { |vv| t.type === vv }
|
126
|
-
elsif Array === t
|
127
|
-
return false if v.nil?
|
128
|
-
v.all? { |i| t.any? { |c| c === i } }
|
129
|
-
elsif TypeStruct === v
|
130
|
-
t == v.class
|
131
|
-
else
|
132
|
-
t === v
|
133
|
-
end
|
114
|
+
definition[k] === v
|
134
115
|
end
|
135
116
|
|
136
117
|
alias original_new new
|
@@ -142,13 +123,12 @@ class TypeStruct
|
|
142
123
|
alias_method :new, :original_new
|
143
124
|
end
|
144
125
|
|
145
|
-
args.
|
126
|
+
args.each_key do |k|
|
146
127
|
define_method(k) do
|
147
128
|
instance_variable_get("@#{k}")
|
148
129
|
end
|
149
130
|
|
150
131
|
define_method("#{k}=") do |v|
|
151
|
-
raise TypeStruct::NoMemberError unless respond_to?(k)
|
152
132
|
unless self.class.valid?(k, v)
|
153
133
|
raise TypeError, "#{self.class}##{k} expect #{self.class.type(k)} got #{v.inspect}"
|
154
134
|
end
|
@@ -2,23 +2,20 @@ require "type_struct/union"
|
|
2
2
|
|
3
3
|
class TypeStruct
|
4
4
|
class ArrayOf
|
5
|
+
include Unionable
|
5
6
|
attr_reader :type
|
6
7
|
def initialize(type)
|
7
8
|
@type = type
|
8
9
|
end
|
9
10
|
|
10
|
-
def |(other)
|
11
|
-
Union.new(self, other)
|
12
|
-
end
|
13
|
-
|
14
11
|
def to_s
|
15
|
-
"
|
12
|
+
"#{self.class}(#{@type})"
|
16
13
|
end
|
17
14
|
alias inspect to_s
|
18
15
|
|
19
16
|
def ===(other)
|
20
|
-
return false unless other
|
21
|
-
other.
|
17
|
+
return false unless Array === other
|
18
|
+
other.all? { |o| @type === o }
|
22
19
|
end
|
23
20
|
end
|
24
21
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "type_struct/array_of"
|
2
|
+
|
3
|
+
module ArrayOfTest
|
4
|
+
def test_initialize(t)
|
5
|
+
unless ArrayOf === ArrayOf.new(Integer)
|
6
|
+
t.error("failed when array of integer")
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_equal(t)
|
11
|
+
int = ArrayOf.new(Integer)
|
12
|
+
str = ArrayOf.new(String)
|
13
|
+
|
14
|
+
unless int === []
|
15
|
+
t.error("empty array check was failed")
|
16
|
+
end
|
17
|
+
|
18
|
+
unless int === [1, 2, 3]
|
19
|
+
t.error("array of integer check was failed")
|
20
|
+
end
|
21
|
+
|
22
|
+
unless str === %w(foo bar baz)
|
23
|
+
t.error("array of string check was failed")
|
24
|
+
end
|
25
|
+
|
26
|
+
if str === [1, 2, 3]
|
27
|
+
t.error("array of integer is not string")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_to_s(t)
|
32
|
+
array_of = ArrayOf.new(Symbol)
|
33
|
+
expect = "TypeStruct::ArrayOf(Symbol)"
|
34
|
+
unless expect == array_of.to_s
|
35
|
+
t.error("to_s string was break #{expect} != #{array_of}")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/type_struct/ext.rb
CHANGED
@@ -1,16 +1,15 @@
|
|
1
|
-
require "type_struct
|
2
|
-
require "type_struct/arrayof"
|
1
|
+
require "type_struct"
|
3
2
|
|
4
3
|
class TypeStruct
|
5
4
|
module UnionExt
|
6
5
|
refine Class do
|
7
|
-
|
8
|
-
Union.new(self, other)
|
9
|
-
end
|
6
|
+
include Unionable
|
10
7
|
end
|
11
8
|
end
|
12
9
|
end
|
13
10
|
|
14
11
|
ArrayOf = TypeStruct::ArrayOf
|
12
|
+
HashOf = TypeStruct::HashOf
|
15
13
|
Union = TypeStruct::Union
|
16
14
|
UnionExt = TypeStruct::UnionExt
|
15
|
+
Interface = TypeStruct::Interface
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "type_struct/union"
|
2
|
+
|
3
|
+
class TypeStruct
|
4
|
+
class HashOf
|
5
|
+
include Unionable
|
6
|
+
|
7
|
+
attr_reader :key_type, :value_type
|
8
|
+
def initialize(key_type, value_type)
|
9
|
+
@key_type = key_type
|
10
|
+
@value_type = value_type
|
11
|
+
end
|
12
|
+
|
13
|
+
def ===(other)
|
14
|
+
return false unless Hash === other
|
15
|
+
other.all? do |k, v|
|
16
|
+
@key_type === k && @value_type === v
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
"#{self.class}(#{@key_type}, #{@value_type})"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "type_struct/hash_of"
|
2
|
+
|
3
|
+
module HashOfTest
|
4
|
+
def test_initialize(t)
|
5
|
+
unless HashOf === HashOf.new(String, String)
|
6
|
+
t.error("make hash of")
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_equal(t)
|
11
|
+
ssh = HashOf.new(String, String)
|
12
|
+
unless ssh === { "a" => "b", "c" => "d" }
|
13
|
+
t.error("=== equal check failed")
|
14
|
+
end
|
15
|
+
if ssh === { "a" => "b", "c" => :d }
|
16
|
+
t.error("=== equal check failed")
|
17
|
+
end
|
18
|
+
if ssh === { "a" => "b", :c => "d" }
|
19
|
+
t.error("=== equal check failed")
|
20
|
+
end
|
21
|
+
|
22
|
+
ifh = HashOf.new(Integer, Float)
|
23
|
+
unless ifh === { 1 => 1.0, 2 => Float::NAN }
|
24
|
+
t.error("=== equal check failed")
|
25
|
+
end
|
26
|
+
if ifh === { 1 => 1, 2 => Float::NAN }
|
27
|
+
t.error("=== equal check failed")
|
28
|
+
end
|
29
|
+
if ifh === { 1 => 1.0, "2" => "1" }
|
30
|
+
t.error("=== equal check failed")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_to_s(t)
|
35
|
+
hash_of = HashOf.new(Symbol, Integer)
|
36
|
+
expect = "TypeStruct::HashOf(Symbol, Integer)"
|
37
|
+
unless expect == hash_of.to_s
|
38
|
+
t.error("to_s string was break #{expect} != #{hash_of}")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "type_struct/union"
|
2
|
+
|
3
|
+
class TypeStruct
|
4
|
+
# IOLike = TypeStruct::Interface.new(
|
5
|
+
# :read,
|
6
|
+
# :write,
|
7
|
+
# :close,
|
8
|
+
# :closed?
|
9
|
+
# )
|
10
|
+
# IOLike === StringIO.new #=> true
|
11
|
+
# IOLike === $stdin #=> true
|
12
|
+
# IOLike === 1 #=> false
|
13
|
+
# IOLike === "io" #=> false
|
14
|
+
#
|
15
|
+
# case $stdin
|
16
|
+
# when IOLike
|
17
|
+
# puts "this is a io like object!"
|
18
|
+
# end
|
19
|
+
class Interface
|
20
|
+
include Unionable
|
21
|
+
def initialize(*methods)
|
22
|
+
@methods = methods
|
23
|
+
end
|
24
|
+
|
25
|
+
def ===(other)
|
26
|
+
@methods.all? do |m|
|
27
|
+
other.respond_to?(m)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_s
|
32
|
+
"#<#{self.class}(#{@methods.map(&:inspect).join(',')})>"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require "type_struct/interface"
|
2
|
+
|
3
|
+
module InterfaceTest
|
4
|
+
Interface = TypeStruct::Interface
|
5
|
+
def test_initialize(t)
|
6
|
+
unless Interface === Interface.new
|
7
|
+
t.error("return value was break")
|
8
|
+
end
|
9
|
+
unless Interface === Interface.new(:foo)
|
10
|
+
t.error("return value was break")
|
11
|
+
end
|
12
|
+
unless Interface === Interface.new(:foo, :bar)
|
13
|
+
t.error("return value was break")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
Reader = Interface.new(:read)
|
18
|
+
Writer = Interface.new(:write)
|
19
|
+
ReadWriter = Interface.new(:read, :write)
|
20
|
+
|
21
|
+
def test_equal(t)
|
22
|
+
r = Object.new
|
23
|
+
def r.read
|
24
|
+
end
|
25
|
+
case r
|
26
|
+
when Reader
|
27
|
+
else
|
28
|
+
t.error("expect Reader === r is true")
|
29
|
+
end
|
30
|
+
|
31
|
+
w = Object.new
|
32
|
+
def w.write
|
33
|
+
end
|
34
|
+
case w
|
35
|
+
when Writer
|
36
|
+
else
|
37
|
+
t.error("expect Writer === w is true")
|
38
|
+
end
|
39
|
+
|
40
|
+
case r
|
41
|
+
when ReadWriter
|
42
|
+
t.error("expect ReadWriter === r is false")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_or(t)
|
47
|
+
r_or_w = Reader | Writer
|
48
|
+
r = Object.new
|
49
|
+
def r.read
|
50
|
+
end
|
51
|
+
|
52
|
+
case r
|
53
|
+
when r_or_w
|
54
|
+
else
|
55
|
+
t.error("expect rw === r is true")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/type_struct/union.rb
CHANGED
data/lib/type_struct/version.rb
CHANGED
data/lib/type_struct_test.rb
CHANGED
@@ -46,6 +46,7 @@ module TypeStructTest
|
|
46
46
|
c: BoolClass,
|
47
47
|
d: B,
|
48
48
|
e: ArrayOf.new(B),
|
49
|
+
f: HashOf.new(String, Integer),
|
49
50
|
)
|
50
51
|
|
51
52
|
def test_s_from_hash_a(t)
|
@@ -59,28 +60,102 @@ module TypeStructTest
|
|
59
60
|
{ a: 2, b: true, c: [1, 2, 3], d: [false], e: { a: [true] } },
|
60
61
|
{ a: 3, b: true, c: [1, 2, 3], d: [false], e: { a: [true] } },
|
61
62
|
],
|
63
|
+
f: {
|
64
|
+
"a" => 1,
|
65
|
+
"c" => 2,
|
66
|
+
},
|
67
|
+
)
|
68
|
+
aa = A.new(
|
69
|
+
a: [1, 2, 3],
|
70
|
+
b: [false, true, false],
|
71
|
+
c: false,
|
72
|
+
d: B.new(a: 1, b: false, c: [1, 2, 3], d: [false], e: C.new(a: [true])),
|
73
|
+
e: [
|
74
|
+
B.new(a: 1, b: false, c: [1, 2, 3], d: [false], e: C.new(a: [true])),
|
75
|
+
B.new(a: 2, b: true, c: [1, 2, 3], d: [false], e: C.new(a: [true])),
|
76
|
+
B.new(a: 3, b: true, c: [1, 2, 3], d: [false], e: C.new(a: [true])),
|
77
|
+
],
|
78
|
+
f: {
|
79
|
+
"a" => 1,
|
80
|
+
"c" => 2,
|
81
|
+
},
|
62
82
|
)
|
63
83
|
unless A === a
|
64
|
-
t.error("
|
84
|
+
t.error("instance type miss")
|
85
|
+
end
|
86
|
+
|
87
|
+
unless a == aa
|
88
|
+
t.error("not same new and from_hash")
|
65
89
|
end
|
66
90
|
end
|
67
91
|
|
68
|
-
def
|
69
|
-
|
70
|
-
|
71
|
-
|
92
|
+
def test_hash_of(t)
|
93
|
+
b = TypeStruct.new(b: Integer)
|
94
|
+
hc = TypeStruct.new(
|
95
|
+
a: HashOf.new(Symbol, b),
|
96
|
+
)
|
97
|
+
|
98
|
+
h = hc.new(
|
99
|
+
a: { sym: b.new(b: 1) },
|
100
|
+
)
|
101
|
+
unless 1 === h.a[:sym].b
|
102
|
+
t.error("assign failed")
|
72
103
|
end
|
73
104
|
|
74
|
-
|
105
|
+
p HashOf.new(Symbol, b) === []
|
106
|
+
begin
|
107
|
+
hc.new(
|
108
|
+
a: [],
|
109
|
+
)
|
110
|
+
rescue TypeError
|
111
|
+
else
|
112
|
+
t.error("TypeError was not railsed")
|
113
|
+
end
|
114
|
+
|
115
|
+
hh = hc.from_hash(
|
116
|
+
a: { sym: { b: 1 } },
|
117
|
+
)
|
118
|
+
unless hh == h
|
119
|
+
t.error("new and from_hash dose not make equal object")
|
120
|
+
end
|
121
|
+
|
122
|
+
begin
|
123
|
+
hh = hc.from_hash(a: 1)
|
124
|
+
rescue TypeError
|
125
|
+
else
|
126
|
+
t.error("TypeError dose not raise error")
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_array_of(t)
|
131
|
+
a = TypeStruct.new(a: Integer)
|
132
|
+
b = TypeStruct.new(a: ArrayOf.new(a))
|
133
|
+
bb = b.new(a: [a.new(a: 1), a.new(a: 2), a.new(a: 3)])
|
134
|
+
unless b === bb
|
135
|
+
t.error("type error")
|
136
|
+
end
|
137
|
+
|
138
|
+
unless bb == b.from_hash(a: [{ a: 1 }, { a: 2 }, { a: 3 }])
|
139
|
+
t.error("from_hash error")
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_s_from_hash(t)
|
144
|
+
foo = Foo.from_hash(bar: { baz: [1, 2, 3] })
|
75
145
|
unless Foo === foo
|
76
146
|
t.error("return value was break")
|
77
147
|
end
|
78
148
|
|
79
149
|
begin
|
80
|
-
Foo.from_hash(bar: { baz: [1, 2, 3] }
|
150
|
+
Foo.from_hash(bar: { baz: [1, 2, "3"] })
|
81
151
|
rescue TypeError
|
82
152
|
else
|
83
|
-
t.error("
|
153
|
+
t.error("'3' is not valid value for Baz.baz:#{Bar.definition.fetch(:baz)}")
|
154
|
+
end
|
155
|
+
|
156
|
+
foo = Foo.from_hash("bar" => { "baz" => [1, 2, 3] })
|
157
|
+
unless Foo === foo
|
158
|
+
t.error("return value was break")
|
84
159
|
end
|
85
160
|
|
86
161
|
foo = Foo.from_hash(bar: { baz: [1, 2, 3] }, nil: nil)
|
@@ -105,6 +180,30 @@ module TypeStructTest
|
|
105
180
|
end
|
106
181
|
end
|
107
182
|
|
183
|
+
def test_s_from_hash_union(t)
|
184
|
+
a = TypeStruct.new(a: Integer)
|
185
|
+
b = TypeStruct.new(b: Integer)
|
186
|
+
c = TypeStruct.new(c: Integer)
|
187
|
+
u = TypeStruct::Union.new(a, b, c)
|
188
|
+
d = TypeStruct.new(d: u)
|
189
|
+
|
190
|
+
d.from_hash(d: { b: 1 })
|
191
|
+
|
192
|
+
begin
|
193
|
+
d.from_hash(d: [b: 1])
|
194
|
+
rescue TypeStruct::UnionNotFoundError
|
195
|
+
else
|
196
|
+
t.error("error dose not raised")
|
197
|
+
end
|
198
|
+
|
199
|
+
begin
|
200
|
+
d.from_hash(d: { b: "a" })
|
201
|
+
rescue TypeStruct::UnionNotFoundError
|
202
|
+
else
|
203
|
+
t.error("error dose not raised")
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
108
207
|
def test_s_from_hash_equal(t)
|
109
208
|
expect = Foo.new(bar: Bar.new(baz: [1, 2, 3]))
|
110
209
|
actual = Foo.from_hash(bar: { baz: [1, 2, 3] })
|
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.3.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-02-
|
11
|
+
date: 2016-02-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,8 +66,13 @@ files:
|
|
66
66
|
- README.md
|
67
67
|
- Rakefile
|
68
68
|
- lib/type_struct.rb
|
69
|
-
- lib/type_struct/
|
69
|
+
- lib/type_struct/array_of.rb
|
70
|
+
- lib/type_struct/array_of_test.rb
|
70
71
|
- lib/type_struct/ext.rb
|
72
|
+
- lib/type_struct/hash_of.rb
|
73
|
+
- lib/type_struct/hash_of_test.rb
|
74
|
+
- lib/type_struct/interface.rb
|
75
|
+
- lib/type_struct/interface_test.rb
|
71
76
|
- lib/type_struct/union.rb
|
72
77
|
- lib/type_struct/union_test.rb
|
73
78
|
- lib/type_struct/version.rb
|
@@ -93,7 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
98
|
version: '0'
|
94
99
|
requirements: []
|
95
100
|
rubyforge_project:
|
96
|
-
rubygems_version: 2.5.
|
101
|
+
rubygems_version: 2.5.2
|
97
102
|
signing_key:
|
98
103
|
specification_version: 4
|
99
104
|
summary: Imitating static typed struct.
|