service_contract 0.4.1 → 0.5.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/CHANGELOG.md +9 -0
- data/lib/service_contract/abstract_type.rb +5 -1
- data/lib/service_contract/assertions.rb +1 -1
- data/lib/service_contract/avro/type.rb +30 -0
- data/lib/service_contract/version.rb +1 -1
- data/test/assertions_test.rb +45 -13
- data/test/sample/2/compiled/logging.avpr +33 -0
- data/test/sample/2/source/logging.avdl +13 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 958fc813b28a607f6fb71c40dee6afd54e04b57c
|
4
|
+
data.tar.gz: 21f8bd6925f79b150546c34c1ccc1244f69616e9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc126bb04f0f3511eb3d921afc8a2aead84764fe5732266a63fdcf487cc400ddc17ebc9266ef58c9797c0f9484c74f7fe144efbd13bf56a8b31128f431d9a7da
|
7
|
+
data.tar.gz: c912a0cf26a8a25a12b9bb43bd24b2e72f4feab3ef8a8f86b60952f49d78b97ffdd1f37e4bc5331cccac819253b7b5134c60f6308534549e17588da9147a1aeb
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module ServiceContract
|
2
2
|
AbstractType = Struct.new(:definition) do
|
3
3
|
def name
|
4
|
-
raise
|
4
|
+
raise NotImplementedError, "need to implement `name`"
|
5
5
|
end
|
6
6
|
|
7
7
|
def subtype
|
@@ -12,6 +12,10 @@ module ServiceContract
|
|
12
12
|
[]
|
13
13
|
end
|
14
14
|
|
15
|
+
def valid_type?(value)
|
16
|
+
valid_ruby_types.any?{|type| value.is_a?(type) }
|
17
|
+
end
|
18
|
+
|
15
19
|
def valid_value?(value)
|
16
20
|
if valid_values.empty?
|
17
21
|
true
|
@@ -10,7 +10,7 @@ module ServiceContract
|
|
10
10
|
return true if data.nil? && allow_nil
|
11
11
|
|
12
12
|
# basic type checking
|
13
|
-
assert type.
|
13
|
+
assert type.valid_type?(data), "expected `#{data}` (#{type.name}) to be one of #{type.valid_ruby_types}"
|
14
14
|
assert type.valid_value?(data), "#{data} is not an allowed value of type: #{type.name}"
|
15
15
|
|
16
16
|
# check subtype
|
@@ -16,6 +16,34 @@ module ServiceContract
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
class MapType < AbstractType
|
20
|
+
def name
|
21
|
+
"Map(#{subtype.name})"
|
22
|
+
end
|
23
|
+
|
24
|
+
def subtype
|
25
|
+
MapValue.new(Type.build(definition.values))
|
26
|
+
end
|
27
|
+
|
28
|
+
def valid_ruby_types
|
29
|
+
[Hash]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class MapValue < AbstractType
|
34
|
+
def name
|
35
|
+
definition.name
|
36
|
+
end
|
37
|
+
def valid_type?(value)
|
38
|
+
value.is_a?(Array) &&
|
39
|
+
value.length == 2 &&
|
40
|
+
definition.valid_type?(value[1])
|
41
|
+
end
|
42
|
+
def valid_ruby_types
|
43
|
+
definition.valid_ruby_types
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
19
47
|
class ArrayType < AbstractType
|
20
48
|
def name
|
21
49
|
"Array(#{subtype.name})"
|
@@ -134,6 +162,8 @@ module ServiceContract
|
|
134
162
|
BooleanType.new
|
135
163
|
when "null"
|
136
164
|
NullType.new
|
165
|
+
when "map"
|
166
|
+
MapType.new(definition)
|
137
167
|
else
|
138
168
|
raise "unknown type: #{type}"
|
139
169
|
end
|
data/test/assertions_test.rb
CHANGED
@@ -65,17 +65,10 @@ class AssertionsTest < Minitest::Test
|
|
65
65
|
protocol = service.protocol("search_param")
|
66
66
|
endpoint = protocol.endpoint("index")
|
67
67
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
rescue Minitest::Assertion => failure
|
73
|
-
failure_data = failure
|
74
|
-
end
|
75
|
-
|
76
|
-
assert !failure_data.nil?
|
77
|
-
assert failure_data.to_s.include?("not described in contract: bogus_param")
|
78
|
-
|
68
|
+
bad_data = [
|
69
|
+
{customer_id: nil, bogus_param: 1}
|
70
|
+
]
|
71
|
+
assert_bad_value(bad_data, endpoint, message: "not described in contract: bogus_param")
|
79
72
|
end
|
80
73
|
|
81
74
|
def test_enum_values
|
@@ -92,10 +85,49 @@ class AssertionsTest < Minitest::Test
|
|
92
85
|
|
93
86
|
assert_endpoint_response(data, endpoint)
|
94
87
|
|
95
|
-
# test can be nil
|
96
88
|
bad_data = [
|
97
89
|
{token: "sometoken", provider: "bad provider"}
|
98
90
|
]
|
91
|
+
assert_bad_value(bad_data, endpoint)
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_map_values
|
95
|
+
service = SampleService.find(2)
|
96
|
+
assert service, "expect to find a service by version"
|
97
|
+
|
98
|
+
protocol = service.protocol("logging")
|
99
|
+
endpoint = protocol.endpoint("index")
|
100
|
+
|
101
|
+
data = [
|
102
|
+
{
|
103
|
+
data: {
|
104
|
+
foo: 1,
|
105
|
+
bar: 2,
|
106
|
+
},
|
107
|
+
data2: {
|
108
|
+
qwer: nil,
|
109
|
+
asdf: 1,
|
110
|
+
zxcv: [2,3]
|
111
|
+
}
|
112
|
+
}
|
113
|
+
]
|
114
|
+
|
115
|
+
assert_endpoint_response(data, endpoint)
|
116
|
+
|
117
|
+
bad_data = [
|
118
|
+
{
|
119
|
+
data: {
|
120
|
+
foo: "asdf"
|
121
|
+
},
|
122
|
+
data2: {}
|
123
|
+
}
|
124
|
+
]
|
125
|
+
assert_bad_value(bad_data, endpoint, message: "to be one of")
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
def assert_bad_value(bad_data, endpoint, message: "is not an allowed value")
|
99
131
|
failure_data = nil
|
100
132
|
begin
|
101
133
|
assert_endpoint_response(bad_data, endpoint)
|
@@ -104,7 +136,7 @@ class AssertionsTest < Minitest::Test
|
|
104
136
|
end
|
105
137
|
|
106
138
|
assert !failure_data.nil?
|
107
|
-
assert failure_data.to_s.include?(
|
139
|
+
assert failure_data.to_s.include?(message), failure_data
|
108
140
|
end
|
109
141
|
|
110
142
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
{
|
2
|
+
"protocol" : "Logging",
|
3
|
+
"namespace" : "Gnomon",
|
4
|
+
"types" : [ {
|
5
|
+
"type" : "record",
|
6
|
+
"name" : "LogEntry",
|
7
|
+
"fields" : [ {
|
8
|
+
"name" : "data",
|
9
|
+
"type" : {
|
10
|
+
"type" : "map",
|
11
|
+
"values" : "int"
|
12
|
+
}
|
13
|
+
}, {
|
14
|
+
"name" : "data2",
|
15
|
+
"type" : {
|
16
|
+
"type" : "map",
|
17
|
+
"values" : [ "null", "int", {
|
18
|
+
"type" : "array",
|
19
|
+
"items" : "int"
|
20
|
+
} ]
|
21
|
+
}
|
22
|
+
} ]
|
23
|
+
} ],
|
24
|
+
"messages" : {
|
25
|
+
"index" : {
|
26
|
+
"request" : [ ],
|
27
|
+
"response" : {
|
28
|
+
"type" : "array",
|
29
|
+
"items" : "LogEntry"
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: service_contract
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeff Ching
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: avro
|
@@ -126,8 +126,10 @@ files:
|
|
126
126
|
- test/sample/1/source/city_state.avdl
|
127
127
|
- test/sample/1/source/location.avdl
|
128
128
|
- test/sample/1/source/sales_region.avdl
|
129
|
+
- test/sample/2/compiled/logging.avpr
|
129
130
|
- test/sample/2/compiled/search_param.avpr
|
130
131
|
- test/sample/2/compiled/social_login.avpr
|
132
|
+
- test/sample/2/source/logging.avdl
|
131
133
|
- test/sample/2/source/search_param.avdl
|
132
134
|
- test/sample/2/source/social_login.avdl
|
133
135
|
- test/service_test.rb
|
@@ -165,8 +167,10 @@ test_files:
|
|
165
167
|
- test/sample/1/source/city_state.avdl
|
166
168
|
- test/sample/1/source/location.avdl
|
167
169
|
- test/sample/1/source/sales_region.avdl
|
170
|
+
- test/sample/2/compiled/logging.avpr
|
168
171
|
- test/sample/2/compiled/search_param.avpr
|
169
172
|
- test/sample/2/compiled/social_login.avpr
|
173
|
+
- test/sample/2/source/logging.avdl
|
170
174
|
- test/sample/2/source/search_param.avdl
|
171
175
|
- test/sample/2/source/social_login.avdl
|
172
176
|
- test/service_test.rb
|