service_contract 0.0.10 → 0.1.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/.gitignore +1 -0
- data/lib/service_contract/avro/endpoint.rb +2 -0
- data/lib/service_contract/avro/protocol.rb +5 -0
- data/lib/service_contract/avro/type.rb +15 -1
- data/lib/service_contract/version.rb +1 -1
- data/test/assertions_test.rb +18 -1
- data/test/sample/1/compiled/city_state.avpr +68 -0
- data/test/sample/1/source/city_state.avdl +30 -0
- data/test/sample/2/compiled/search_param.avpr +25 -0
- data/test/sample/2/source/search_param.avdl +12 -0
- data/test/service_test.rb +57 -2
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8cb40a77b33371d743328e30c58742c07a57d77c
|
4
|
+
data.tar.gz: b9bc84d00c6147ef1c3ecfec18ad7753cf17ec89
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b18b92ce0dcd4eefa1dac486dc51e98bfa4b6353717fb0175b0781b297c0f94694f85942071b49b40d9ea04069c3a9ae6b08b5e6daf3cf9fe7b6fc46f55b6863
|
7
|
+
data.tar.gz: 8f02a7a4235704d826932c5cb5b3d1c9b7f9f2ae9ce1a43f277af081b3d19a6020984202ffe6e922eb57b5eae24db855452c4a7958138d25cee09324814f462b
|
data/.gitignore
CHANGED
@@ -21,6 +21,11 @@ module ServiceContract
|
|
21
21
|
File.join(service.path, resource_name)
|
22
22
|
end
|
23
23
|
|
24
|
+
def main_type
|
25
|
+
# convert protocol name to a class like name. i.e. "city_state" => "CityState"
|
26
|
+
name.split("_").map{|o| o.capitalize}.join
|
27
|
+
end
|
28
|
+
|
24
29
|
protected
|
25
30
|
|
26
31
|
def resource_name
|
@@ -16,7 +16,9 @@ module ServiceContract
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def to_s
|
19
|
-
name
|
19
|
+
return name unless union?
|
20
|
+
|
21
|
+
union_types.map(&:name).join(", ")
|
20
22
|
end
|
21
23
|
|
22
24
|
def subtype
|
@@ -36,6 +38,10 @@ module ServiceContract
|
|
36
38
|
type_string == "record"
|
37
39
|
end
|
38
40
|
|
41
|
+
def union?
|
42
|
+
type_string == "union"
|
43
|
+
end
|
44
|
+
|
39
45
|
def valid_ruby_types
|
40
46
|
case type_string
|
41
47
|
when "array"
|
@@ -48,6 +54,10 @@ module ServiceContract
|
|
48
54
|
[Float]
|
49
55
|
when "boolean"
|
50
56
|
[TrueClass, FalseClass]
|
57
|
+
when "null"
|
58
|
+
[NilClass]
|
59
|
+
when "union"
|
60
|
+
union_types.map(&:valid_ruby_types).flatten
|
51
61
|
else # a complex type
|
52
62
|
[Hash]
|
53
63
|
end
|
@@ -55,6 +65,10 @@ module ServiceContract
|
|
55
65
|
|
56
66
|
protected
|
57
67
|
|
68
|
+
def union_types
|
69
|
+
definition.schemas.map{|schema| Type.build(schema)}
|
70
|
+
end
|
71
|
+
|
58
72
|
def type_string
|
59
73
|
type = definition.type
|
60
74
|
type = type.type_sym.to_s if type.respond_to?(:type_sym)
|
data/test/assertions_test.rb
CHANGED
@@ -8,7 +8,7 @@ class AssertionsTest < Minitest::Test
|
|
8
8
|
assert service, "expect to find a service by version"
|
9
9
|
assert_equal "1", service.version
|
10
10
|
|
11
|
-
assert_equal
|
11
|
+
assert_equal 3, service.protocols.length
|
12
12
|
protocol = service.protocol("location")
|
13
13
|
endpoint = protocol.endpoint("index")
|
14
14
|
|
@@ -41,4 +41,21 @@ class AssertionsTest < Minitest::Test
|
|
41
41
|
assert_endpoint_response(data, endpoint)
|
42
42
|
end
|
43
43
|
|
44
|
+
def test_union_data_matching
|
45
|
+
service = SampleService.find(2)
|
46
|
+
assert service, "expect to find a service by version"
|
47
|
+
|
48
|
+
protocol = service.protocol("search_param")
|
49
|
+
endpoint = protocol.endpoint("index")
|
50
|
+
|
51
|
+
# test can be nil
|
52
|
+
assert_endpoint_response([{customer_id: nil}], endpoint)
|
53
|
+
|
54
|
+
# should be able to be an integer
|
55
|
+
assert_endpoint_response([{customer_id: 4}], endpoint)
|
56
|
+
|
57
|
+
# should be able to be an array of ints
|
58
|
+
assert_endpoint_response([{customer_id: [1,2,3]}], endpoint)
|
59
|
+
end
|
60
|
+
|
44
61
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
{
|
2
|
+
"protocol" : "CityState",
|
3
|
+
"namespace" : "Gnomon",
|
4
|
+
"types" : [ {
|
5
|
+
"type" : "record",
|
6
|
+
"name" : "Timestamp",
|
7
|
+
"fields" : [ {
|
8
|
+
"name" : "timestamp",
|
9
|
+
"type" : "int"
|
10
|
+
} ]
|
11
|
+
}, {
|
12
|
+
"type" : "record",
|
13
|
+
"name" : "CityState",
|
14
|
+
"doc" : "This main class for this protocol",
|
15
|
+
"fields" : [ {
|
16
|
+
"name" : "id",
|
17
|
+
"type" : "int",
|
18
|
+
"doc" : "foo"
|
19
|
+
}, {
|
20
|
+
"name" : "city_id",
|
21
|
+
"type" : "int"
|
22
|
+
}, {
|
23
|
+
"name" : "state_id",
|
24
|
+
"type" : "int"
|
25
|
+
} ]
|
26
|
+
}, {
|
27
|
+
"type" : "record",
|
28
|
+
"name" : "FetchOption",
|
29
|
+
"fields" : [ {
|
30
|
+
"name" : "page",
|
31
|
+
"type" : "int",
|
32
|
+
"default" : 0
|
33
|
+
}, {
|
34
|
+
"name" : "per_page",
|
35
|
+
"type" : "int",
|
36
|
+
"default" : 30
|
37
|
+
} ]
|
38
|
+
} ],
|
39
|
+
"messages" : {
|
40
|
+
"bogus" : {
|
41
|
+
"doc" : "bogus method for testing no parameters",
|
42
|
+
"request" : [ ],
|
43
|
+
"response" : "null"
|
44
|
+
},
|
45
|
+
"non_member_method" : {
|
46
|
+
"doc" : "method that uses non \"main_type\" as the first parameter is considered non-member",
|
47
|
+
"request" : [ {
|
48
|
+
"name" : "options",
|
49
|
+
"type" : "FetchOption"
|
50
|
+
} ],
|
51
|
+
"response" : {
|
52
|
+
"type" : "array",
|
53
|
+
"items" : "CityState"
|
54
|
+
}
|
55
|
+
},
|
56
|
+
"member_method" : {
|
57
|
+
"doc" : "method that uses \"main_type\" as the first parameter is considered member",
|
58
|
+
"request" : [ {
|
59
|
+
"name" : "params",
|
60
|
+
"type" : "CityState"
|
61
|
+
} ],
|
62
|
+
"response" : {
|
63
|
+
"type" : "array",
|
64
|
+
"items" : "CityState"
|
65
|
+
}
|
66
|
+
}
|
67
|
+
}
|
68
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
@namespace("Gnomon")
|
2
|
+
|
3
|
+
protocol CityState {
|
4
|
+
|
5
|
+
record Timestamp {
|
6
|
+
int timestamp;
|
7
|
+
}
|
8
|
+
|
9
|
+
/** This main class for this protocol */
|
10
|
+
record CityState {
|
11
|
+
/** foo */
|
12
|
+
int id;
|
13
|
+
int city_id;
|
14
|
+
int state_id;
|
15
|
+
}
|
16
|
+
|
17
|
+
record FetchOption {
|
18
|
+
int page = 0;
|
19
|
+
int per_page = 30;
|
20
|
+
}
|
21
|
+
|
22
|
+
/** bogus method for testing no parameters */
|
23
|
+
void bogus();
|
24
|
+
|
25
|
+
/** method that uses non "main_type" as the first parameter is considered non-member */
|
26
|
+
array<CityState> non_member_method(FetchOption options);
|
27
|
+
|
28
|
+
/** method that uses "main_type" as the first parameter is considered member */
|
29
|
+
array<CityState> member_method(CityState params);
|
30
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
{
|
2
|
+
"protocol" : "SearchParam",
|
3
|
+
"namespace" : "Gnomon",
|
4
|
+
"types" : [ {
|
5
|
+
"type" : "record",
|
6
|
+
"name" : "SearchParam",
|
7
|
+
"fields" : [ {
|
8
|
+
"name" : "customer_id",
|
9
|
+
"type" : [ "null", "int", {
|
10
|
+
"type" : "array",
|
11
|
+
"items" : "int"
|
12
|
+
} ],
|
13
|
+
"doc" : "Required search params"
|
14
|
+
} ]
|
15
|
+
} ],
|
16
|
+
"messages" : {
|
17
|
+
"index" : {
|
18
|
+
"request" : [ ],
|
19
|
+
"response" : {
|
20
|
+
"type" : "array",
|
21
|
+
"items" : "SearchParam"
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
data/test/service_test.rb
CHANGED
@@ -3,7 +3,7 @@ require 'test_helper'
|
|
3
3
|
class ServiceTest < Minitest::Test
|
4
4
|
|
5
5
|
def test_all
|
6
|
-
assert_equal(
|
6
|
+
assert_equal(2, SampleService.all.length)
|
7
7
|
end
|
8
8
|
|
9
9
|
def test_find
|
@@ -11,11 +11,66 @@ class ServiceTest < Minitest::Test
|
|
11
11
|
assert service, "expect to find a service by version"
|
12
12
|
assert_equal "1", service.version
|
13
13
|
|
14
|
-
assert_equal
|
14
|
+
assert_equal 3, service.protocols.length
|
15
15
|
protocol = service.protocol("location")
|
16
16
|
|
17
17
|
assert_equal "location", protocol.name
|
18
18
|
assert_equal 3, protocol.endpoints.length
|
19
19
|
end
|
20
20
|
|
21
|
+
def test_null_params
|
22
|
+
# the member? method would error if the endpoint method had no parameters. This test verifies the fix.
|
23
|
+
service = SampleService.find(1)
|
24
|
+
protocol = service.protocol("city_state")
|
25
|
+
|
26
|
+
# find the endpoint with no parameters.
|
27
|
+
empty_param_endpoints = protocol.endpoints.select{|e| e.parameters.empty?}
|
28
|
+
assert !empty_param_endpoints.empty?
|
29
|
+
|
30
|
+
empty_param_endpoints.each do |endpoint|
|
31
|
+
assert_equal(false, endpoint.send("member?"))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# The member? method determines if an endpoint is a "member" by looking at its first parameter. If that parameter
|
36
|
+
# is equal to the 'main_type' then it is a member, otherwise it is not a member. Main_type is nothing more than the
|
37
|
+
# classname of the protocol.
|
38
|
+
def test_member_endpoint
|
39
|
+
service = SampleService.find(1)
|
40
|
+
protocol = service.protocol("city_state")
|
41
|
+
|
42
|
+
# only one endpoint is a member method, "member_method"
|
43
|
+
member_names = protocol.endpoints.select{|e| e.send("member?")}.map(&:name)
|
44
|
+
assert_equal(1, member_names.length)
|
45
|
+
assert_equal('member_method', member_names.first)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_non_member_endpoint
|
49
|
+
service = SampleService.find(1)
|
50
|
+
protocol = service.protocol("city_state")
|
51
|
+
|
52
|
+
# two endpoints are non member method, "bogus" and "non_member_method"
|
53
|
+
non_member_names = protocol.endpoints.select{|e| !e.send("member?")}.map(&:name)
|
54
|
+
assert_equal(2, non_member_names.length)
|
55
|
+
assert non_member_names.include?('non_member_method')
|
56
|
+
assert non_member_names.include?('bogus')
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_union_types
|
60
|
+
service = SampleService.find(2)
|
61
|
+
protocol = service.protocol('search_param')
|
62
|
+
|
63
|
+
type = protocol.type('SearchParam')
|
64
|
+
assert(type, 'expected to find a SearchParam type')
|
65
|
+
|
66
|
+
field = type.fields.detect{|field| field.name == 'customer_id'}
|
67
|
+
assert(field, 'expected to find a customer_id field')
|
68
|
+
|
69
|
+
field_type = field.type
|
70
|
+
|
71
|
+
assert_equal('union', field_type.name)
|
72
|
+
assert_equal('null, int, Array(int)', field_type.to_s)
|
73
|
+
assert_equal([NilClass, Fixnum, Array], field_type.valid_ruby_types)
|
74
|
+
end
|
75
|
+
|
21
76
|
end
|
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.0
|
4
|
+
version: 0.1.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: 2014-
|
11
|
+
date: 2014-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: avro
|
@@ -120,10 +120,14 @@ files:
|
|
120
120
|
- src/avro-tools-1.7.7.jar
|
121
121
|
- test/assertions_test.rb
|
122
122
|
- test/mock_test.rb
|
123
|
+
- test/sample/1/compiled/city_state.avpr
|
123
124
|
- test/sample/1/compiled/location.avpr
|
124
125
|
- test/sample/1/compiled/sales_region.avpr
|
126
|
+
- test/sample/1/source/city_state.avdl
|
125
127
|
- test/sample/1/source/location.avdl
|
126
128
|
- test/sample/1/source/sales_region.avdl
|
129
|
+
- test/sample/2/compiled/search_param.avpr
|
130
|
+
- test/sample/2/source/search_param.avdl
|
127
131
|
- test/service_test.rb
|
128
132
|
- test/test_helper.rb
|
129
133
|
homepage: ''
|
@@ -153,10 +157,14 @@ summary: Abstract the definition of a service's interface contract
|
|
153
157
|
test_files:
|
154
158
|
- test/assertions_test.rb
|
155
159
|
- test/mock_test.rb
|
160
|
+
- test/sample/1/compiled/city_state.avpr
|
156
161
|
- test/sample/1/compiled/location.avpr
|
157
162
|
- test/sample/1/compiled/sales_region.avpr
|
163
|
+
- test/sample/1/source/city_state.avdl
|
158
164
|
- test/sample/1/source/location.avdl
|
159
165
|
- test/sample/1/source/sales_region.avdl
|
166
|
+
- test/sample/2/compiled/search_param.avpr
|
167
|
+
- test/sample/2/source/search_param.avdl
|
160
168
|
- test/service_test.rb
|
161
169
|
- test/test_helper.rb
|
162
170
|
has_rdoc:
|