type_struct 0.2.1 → 0.3.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 +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.
|