emery 0.0.1 → 0.0.2
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/lib/emery/jsoner.rb +25 -0
- data/lib/emery/type.rb +18 -7
- data/test/jsoner_test.rb +24 -3
- data/test/type_test.rb +35 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e7526be75b8c44c624947657c22214dd7715170e1bbdb8b46a8369a6ca66d4fc
|
4
|
+
data.tar.gz: 5483955dd2c563ca2c6c04662aea8bc1f9b4a5e34817b9d60a046afa32ca5a04
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e1e408199c42d0c877c1ca9be978f698357449ac9f4c909c6157ec190bfb83f19434184e68bf7ab6cf96b93007e6658f1eae1f744c57a97d8fae0231eed03a76
|
7
|
+
data.tar.gz: 80f702c3cd1bd7edd8359a03576519db0002efcedd3db144ef1c3e94192ccd6fb129dd0ac8a25177f9d9dd96f016f3cf84c4237e69fe5d2e15c12f2790530456
|
data/lib/emery/jsoner.rb
CHANGED
@@ -76,6 +76,31 @@ module Emery
|
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
+
T::UnionType.class_eval do
|
80
|
+
def jsoner_deserialize(json_value)
|
81
|
+
if !json_value.is_a?(Hash)
|
82
|
+
raise JsonerError.new("JSON value type #{json_value.class} is not Hash")
|
83
|
+
end
|
84
|
+
if json_value.keys.length != 1
|
85
|
+
raise JsonerError.new("JSON value #{json_value} should have only one key to represent union type, found #{json_value.keys.length}")
|
86
|
+
end
|
87
|
+
case_key = json_value.keys[0]
|
88
|
+
if not cases.key? case_key.to_sym
|
89
|
+
raise JsonerError.new("JSON key '#{case_key}' does not match any case in union type #{self}")
|
90
|
+
end
|
91
|
+
type = cases[case_key.to_sym]
|
92
|
+
case_json_value = json_value[case_key]
|
93
|
+
return Jsoner.deserialize(type, case_json_value)
|
94
|
+
end
|
95
|
+
def jsoner_serialize(value)
|
96
|
+
T.check(self, value)
|
97
|
+
type = types.find {|t| T.instance_of?(t, value) }
|
98
|
+
case_key = cases.key(type)
|
99
|
+
result = { case_key => Jsoner.serialize(type, value) }
|
100
|
+
result
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
79
104
|
T::Nilable.class_eval do
|
80
105
|
def jsoner_deserialize(json_value)
|
81
106
|
if json_value != nil
|
data/lib/emery/type.rb
CHANGED
@@ -42,20 +42,27 @@ module Emery
|
|
42
42
|
"Any[#{types.map { |t| t.to_s}.join(', ')}]"
|
43
43
|
end
|
44
44
|
def check(value)
|
45
|
-
types.
|
46
|
-
|
47
|
-
|
48
|
-
return
|
49
|
-
rescue TypeError
|
50
|
-
end
|
45
|
+
type = types.find {|t| T.instance_of?(t, value) }
|
46
|
+
if type == nil
|
47
|
+
raise TypeError.new("Value '#{value.inspect.to_s}' type is #{value.class} - any of #{@types.map { |t| t.to_s}.join(', ')} required")
|
51
48
|
end
|
52
|
-
raise TypeError.new("Value '#{value.inspect.to_s}' type is #{value.class} - any of #{@types.map { |t| t.to_s}.join(', ')} required")
|
53
49
|
end
|
54
50
|
def ==(other)
|
55
51
|
T.instance_of?(AnyType, other) and (self.types - other.types).empty?
|
56
52
|
end
|
57
53
|
end
|
58
54
|
|
55
|
+
class UnionType < AnyType
|
56
|
+
attr_reader :cases
|
57
|
+
def initialize(cases)
|
58
|
+
@cases = cases
|
59
|
+
super(*cases.values)
|
60
|
+
end
|
61
|
+
def to_s
|
62
|
+
"Union[#{cases.map { |k, t| "#{k}: #{t}"}.join(', ')}]"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
59
66
|
class ArrayType
|
60
67
|
attr_reader :item_type
|
61
68
|
def initialize(item_type)
|
@@ -159,6 +166,10 @@ module Emery
|
|
159
166
|
AnyType.new(*typdefs)
|
160
167
|
end
|
161
168
|
|
169
|
+
def T.union(*cases)
|
170
|
+
UnionType.new(*cases)
|
171
|
+
end
|
172
|
+
|
162
173
|
def T.check_var(var_name, type, value)
|
163
174
|
begin
|
164
175
|
check(type, value)
|
data/test/jsoner_test.rb
CHANGED
@@ -216,13 +216,13 @@ module Emery
|
|
216
216
|
end
|
217
217
|
|
218
218
|
class AnyDeserialization < Test::Unit::TestCase
|
219
|
-
def
|
219
|
+
def test_deserialize
|
220
220
|
data = Jsoner.from_json(T.any(String, Integer), '"the string"')
|
221
221
|
T.check(T.any(String, Integer), data)
|
222
222
|
assert_equal "the string", data, "Should parse any type"
|
223
223
|
end
|
224
224
|
|
225
|
-
def
|
225
|
+
def test_deserialize_fail
|
226
226
|
assert_raise JsonerError do
|
227
227
|
Jsoner.from_json(T.any(Integer, Float), '"the string"')
|
228
228
|
end
|
@@ -230,10 +230,31 @@ module Emery
|
|
230
230
|
end
|
231
231
|
|
232
232
|
class AnySerialization < Test::Unit::TestCase
|
233
|
-
def
|
233
|
+
def test_serialize
|
234
234
|
data = Jsoner.to_json(T.any(String, Integer), "the string")
|
235
235
|
T.check(T.any(String, Integer), data)
|
236
236
|
assert_equal '"the string"', data, "Should serialize any type"
|
237
237
|
end
|
238
238
|
end
|
239
|
+
|
240
|
+
class UnionDeserialization < Test::Unit::TestCase
|
241
|
+
def test_deserialize
|
242
|
+
data = Jsoner.from_json(T.union(str: String, int: Integer), '{"str":"the string"}')
|
243
|
+
T.check(T.union(str: String, int: Integer), data)
|
244
|
+
assert_equal "the string", data, "Should parse union type"
|
245
|
+
end
|
246
|
+
|
247
|
+
def test_deserialize_any_fail
|
248
|
+
assert_raise JsonerError do
|
249
|
+
Jsoner.from_json(T.union(str: String, int: Integer), '{"bool":true}')
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
class UnionSerialization < Test::Unit::TestCase
|
255
|
+
def test_serialize
|
256
|
+
data = Jsoner.to_json(T.union(str: String, int: Integer), "the string")
|
257
|
+
assert_equal '{"str":"the string"}', data, "Should serialize union type with wrapping object"
|
258
|
+
end
|
259
|
+
end
|
239
260
|
end
|
data/test/type_test.rb
CHANGED
@@ -70,6 +70,28 @@ module Emery
|
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
+
class TypeToString < Test::Unit::TestCase
|
74
|
+
def test_nilable
|
75
|
+
assert_equal "Nilable[Integer]", T.nilable(Integer).to_s
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_array
|
79
|
+
assert_equal "Array[Integer]", T.array(Integer).to_s
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_hash
|
83
|
+
assert_equal "Hash[String, Integer]", T.hash(String, Integer).to_s
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_any
|
87
|
+
assert_equal "Any[String, Integer]", T.any(String, Integer).to_s
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_union
|
91
|
+
assert_equal "Union[str: String, int: Integer]", T.union(str: String, int: Integer).to_s
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
73
95
|
class TypeCheck < Test::Unit::TestCase
|
74
96
|
def test_nil
|
75
97
|
assert_equal nil, T.check(NilClass, nil)
|
@@ -182,4 +204,17 @@ module Emery
|
|
182
204
|
end
|
183
205
|
end
|
184
206
|
end
|
207
|
+
|
208
|
+
class TypeCheckUnion < Test::Unit::TestCase
|
209
|
+
def test_success
|
210
|
+
assert_equal(123, T.check(T.union(str: String, int: Integer), 123))
|
211
|
+
end
|
212
|
+
|
213
|
+
def test_fail
|
214
|
+
assert_raise TypeError do
|
215
|
+
T.check(T.union(str: String, int: Integer), true)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
185
220
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: emery
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Sapronov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-03-
|
11
|
+
date: 2020-03-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|