komoju 0.0.0 → 0.0.3
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 +2 -14
- data/.gitmodules +3 -0
- data/Gemfile.lock +34 -0
- data/LICENSE.txt +1 -1
- data/README.md +14 -2
- data/Rakefile +9 -0
- data/bin/generate-client +11 -0
- data/komoju.gemspec +15 -6
- data/lib/komoju/client.rb +460 -0
- data/lib/komoju/version.rb +1 -1
- data/lib/komoju.rb +10 -2
- data/test/client_test.rb +8 -0
- data/test/helper.rb +1 -0
- data/vendor/heroics/lib/heroics/cli.rb +88 -0
- data/vendor/heroics/lib/heroics/client.rb +109 -0
- data/vendor/heroics/lib/heroics/client_generator.rb +99 -0
- data/vendor/heroics/lib/heroics/command.rb +67 -0
- data/vendor/heroics/lib/heroics/errors.rb +6 -0
- data/vendor/heroics/lib/heroics/link.rb +120 -0
- data/vendor/heroics/lib/heroics/naming.rb +19 -0
- data/vendor/heroics/lib/heroics/resource.rb +30 -0
- data/vendor/heroics/lib/heroics/schema.rb +444 -0
- data/vendor/heroics/lib/heroics/version.rb +3 -0
- data/vendor/heroics/lib/heroics.rb +22 -0
- data/vendor/heroics/test/cli_test.rb +236 -0
- data/vendor/heroics/test/client_generator_test.rb +34 -0
- data/vendor/heroics/test/client_test.rb +215 -0
- data/vendor/heroics/test/command_test.rb +214 -0
- data/vendor/heroics/test/helper.rb +204 -0
- data/vendor/heroics/test/link_test.rb +398 -0
- data/vendor/heroics/test/naming_test.rb +45 -0
- data/vendor/heroics/test/resource_test.rb +35 -0
- data/vendor/heroics/test/schema_test.rb +287 -0
- data/vendor/heroics/test/version_test.rb +9 -0
- data/vendor/heroics/test.rb +42 -0
- metadata +139 -8
@@ -0,0 +1,214 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
class CommandTest < MiniTest::Unit::TestCase
|
5
|
+
include ExconHelper
|
6
|
+
|
7
|
+
# Command.name returns the name of the command, which is made up by joining
|
8
|
+
# the resource name and link title with a colon.
|
9
|
+
def test_name
|
10
|
+
schema = Heroics::Schema.new(SAMPLE_SCHEMA)
|
11
|
+
client = Heroics::client_from_schema(schema, 'https://example.com')
|
12
|
+
output = StringIO.new
|
13
|
+
command = Heroics::Command.new(
|
14
|
+
'cli', schema.resource('resource').link('list'), client, output)
|
15
|
+
assert_equal('resource:list', command.name)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Command.description returns a description for the command.
|
19
|
+
def test_description
|
20
|
+
schema = Heroics::Schema.new(SAMPLE_SCHEMA)
|
21
|
+
client = Heroics::client_from_schema(schema, 'https://example.com')
|
22
|
+
output = StringIO.new
|
23
|
+
command = Heroics::Command.new(
|
24
|
+
'cli', schema.resource('resource').link('list'), client, output)
|
25
|
+
assert_equal('Show all sample resources', command.description)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Command.run calls the correct method on the client when no link parameters
|
29
|
+
# are provided.
|
30
|
+
def test_run_without_parameters
|
31
|
+
schema = Heroics::Schema.new(SAMPLE_SCHEMA)
|
32
|
+
client = Heroics::client_from_schema(schema, 'https://example.com')
|
33
|
+
output = StringIO.new
|
34
|
+
command = Heroics::Command.new(
|
35
|
+
'cli', schema.resource('resource').link('list'), client, output)
|
36
|
+
|
37
|
+
body = ['Hello', 'World!']
|
38
|
+
Excon.stub(method: :get) do |request|
|
39
|
+
assert_equal('/resource', request[:path])
|
40
|
+
Excon.stubs.pop
|
41
|
+
{status: 200, headers: {'Content-Type' => 'application/json'},
|
42
|
+
body: MultiJson.dump(body)}
|
43
|
+
end
|
44
|
+
|
45
|
+
command.run
|
46
|
+
assert_equal(MultiJson.dump(body, pretty: true) + "\n", output.string)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Command.run calls the correct method on the client and passes link
|
50
|
+
# parameters when they're provided.
|
51
|
+
def test_run_with_parameters
|
52
|
+
schema = Heroics::Schema.new(SAMPLE_SCHEMA)
|
53
|
+
client = Heroics::client_from_schema(schema, 'https://example.com')
|
54
|
+
output = StringIO.new
|
55
|
+
command = Heroics::Command.new(
|
56
|
+
'cli', schema.resource('resource').link('info'), client, output)
|
57
|
+
|
58
|
+
uuid = '1ab1c589-df46-40aa-b786-60e83b1efb10'
|
59
|
+
body = {'Hello' => 'World!'}
|
60
|
+
Excon.stub(method: :get) do |request|
|
61
|
+
assert_equal("/resource/#{uuid}", request[:path])
|
62
|
+
Excon.stubs.pop
|
63
|
+
{status: 200, headers: {'Content-Type' => 'application/json'},
|
64
|
+
body: MultiJson.dump(body)}
|
65
|
+
end
|
66
|
+
|
67
|
+
command.run(uuid)
|
68
|
+
assert_equal(MultiJson.dump(body, pretty: true) + "\n", output.string)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Command.run calls the correct method on the client and passes a request
|
72
|
+
# body to the link when it's provided.
|
73
|
+
def test_run_with_request_body_and_text_response
|
74
|
+
schema = Heroics::Schema.new(SAMPLE_SCHEMA)
|
75
|
+
client = Heroics::client_from_schema(schema, 'https://example.com')
|
76
|
+
output = StringIO.new
|
77
|
+
command = Heroics::Command.new(
|
78
|
+
'cli', schema.resource('resource').link('create'), client, output)
|
79
|
+
|
80
|
+
body = {'Hello' => 'World!'}
|
81
|
+
Excon.stub(method: :post) do |request|
|
82
|
+
assert_equal('/resource', request[:path])
|
83
|
+
assert_equal('application/json', request[:headers]['Content-Type'])
|
84
|
+
assert_equal(body, MultiJson.load(request[:body]))
|
85
|
+
Excon.stubs.pop
|
86
|
+
{status: 201}
|
87
|
+
end
|
88
|
+
|
89
|
+
command.run(body)
|
90
|
+
assert_equal('', output.string)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Command.run calls the correct method on the client and converts the result
|
94
|
+
# to an array, if a range response is received, before writing it out.
|
95
|
+
def test_run_with_range_response
|
96
|
+
schema = Heroics::Schema.new(SAMPLE_SCHEMA)
|
97
|
+
client = Heroics::client_from_schema(schema, 'https://example.com')
|
98
|
+
output = StringIO.new
|
99
|
+
command = Heroics::Command.new(
|
100
|
+
'cli', schema.resource('resource').link('list'), client, output)
|
101
|
+
|
102
|
+
Excon.stub(method: :get) do |request|
|
103
|
+
Excon.stubs.shift
|
104
|
+
{status: 206, headers: {'Content-Type' => 'application/json',
|
105
|
+
'Content-Range' => 'id 1..2; max=200'},
|
106
|
+
body: MultiJson.dump([2])}
|
107
|
+
end
|
108
|
+
|
109
|
+
Excon.stub(method: :get) do |request|
|
110
|
+
Excon.stubs.shift
|
111
|
+
{status: 206, headers: {'Content-Type' => 'application/json',
|
112
|
+
'Content-Range' => 'id 0..1; max=200',
|
113
|
+
'Next-Range' => '201'},
|
114
|
+
body: MultiJson.dump([1])}
|
115
|
+
end
|
116
|
+
|
117
|
+
command.run
|
118
|
+
assert_equal(MultiJson.dump([1, 2], pretty: true) + "\n", output.string)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Command.run calls the correct method on the client and passes parameters
|
122
|
+
# and a request body to the link when they're provided.
|
123
|
+
def test_run_with_request_body_and_parameters
|
124
|
+
schema = Heroics::Schema.new(SAMPLE_SCHEMA)
|
125
|
+
client = Heroics::client_from_schema(schema, 'https://example.com')
|
126
|
+
output = StringIO.new
|
127
|
+
command = Heroics::Command.new(
|
128
|
+
'cli', schema.resource('resource').link('update'), client, output)
|
129
|
+
|
130
|
+
uuid = '1ab1c589-df46-40aa-b786-60e83b1efb10'
|
131
|
+
body = {'Hello' => 'World!'}
|
132
|
+
result = {'Goodbye' => 'Universe!'}
|
133
|
+
Excon.stub(method: :patch) do |request|
|
134
|
+
assert_equal("/resource/#{uuid}", request[:path])
|
135
|
+
assert_equal('application/json', request[:headers]['Content-Type'])
|
136
|
+
assert_equal(body, MultiJson.load(request[:body]))
|
137
|
+
Excon.stubs.pop
|
138
|
+
{status: 200, headers: {'Content-Type' => 'application/json'},
|
139
|
+
body: MultiJson.dump(result)}
|
140
|
+
end
|
141
|
+
|
142
|
+
command.run(uuid, body)
|
143
|
+
assert_equal(MultiJson.dump(result, pretty: true) + "\n", output.string)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Command.run raises an ArgumentError if too few parameters are provided.
|
147
|
+
def test_run_with_too_few_parameters
|
148
|
+
schema = Heroics::Schema.new(SAMPLE_SCHEMA)
|
149
|
+
client = Heroics::client_from_schema(schema, 'https://example.com')
|
150
|
+
output = StringIO.new
|
151
|
+
command = Heroics::Command.new(
|
152
|
+
'cli', schema.resource('resource').link('info'), client, output)
|
153
|
+
assert_raises ArgumentError do
|
154
|
+
command.run
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# Command.run raises an ArgumentError if too many parameters are provided.
|
159
|
+
def test_run_with_too_many_parameters
|
160
|
+
schema = Heroics::Schema.new(SAMPLE_SCHEMA)
|
161
|
+
client = Heroics::client_from_schema(schema, 'https://example.com')
|
162
|
+
output = StringIO.new
|
163
|
+
command = Heroics::Command.new(
|
164
|
+
'cli', schema.resource('resource').link('info'), client, output)
|
165
|
+
assert_raises ArgumentError do
|
166
|
+
command.run('too', 'many', 'parameters')
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# Command.usage displays usage information.
|
171
|
+
def test_usage
|
172
|
+
schema = Heroics::Schema.new(SAMPLE_SCHEMA)
|
173
|
+
client = Heroics::client_from_schema(schema, 'https://example.com')
|
174
|
+
output = StringIO.new
|
175
|
+
command = Heroics::Command.new(
|
176
|
+
'cli', schema.resource('resource').link('update'), client, output)
|
177
|
+
command.usage
|
178
|
+
expected = <<-USAGE
|
179
|
+
Usage: cli resource:update <uuid_field> <body>
|
180
|
+
|
181
|
+
Description:
|
182
|
+
Update a sample resource
|
183
|
+
|
184
|
+
Body example:
|
185
|
+
{
|
186
|
+
"date_field": "2013-10-19 22:10:29Z",
|
187
|
+
"string_field": "Sample text.",
|
188
|
+
"boolean_field": true,
|
189
|
+
"uuid_field": "44724831-bf66-4bc2-865f-e2c4c2b14c78",
|
190
|
+
"email_field": "username@example.com"
|
191
|
+
}
|
192
|
+
USAGE
|
193
|
+
assert_equal(expected, output.string)
|
194
|
+
end
|
195
|
+
|
196
|
+
# Command.usage correctly handles parameters that are described by 'oneOf'
|
197
|
+
# and 'anyOf' sub-parameter lists.
|
198
|
+
def test_usage_with_one_of_field
|
199
|
+
schema = Heroics::Schema.new(SAMPLE_SCHEMA)
|
200
|
+
client = Heroics::client_from_schema(schema, 'https://example.com')
|
201
|
+
output = StringIO.new
|
202
|
+
command = Heroics::Command.new(
|
203
|
+
'cli', schema.resource('resource').link('identify_resource'), client,
|
204
|
+
output)
|
205
|
+
command.usage
|
206
|
+
expected = <<-USAGE
|
207
|
+
Usage: cli resource:identify-resource <uuid_field|email_field>
|
208
|
+
|
209
|
+
Description:
|
210
|
+
Show a sample resource
|
211
|
+
USAGE
|
212
|
+
assert_equal(expected, output.string)
|
213
|
+
end
|
214
|
+
end
|
@@ -0,0 +1,204 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
require 'heroics'
|
5
|
+
|
6
|
+
module ExconHelper
|
7
|
+
def setup
|
8
|
+
super
|
9
|
+
Excon.stubs.clear
|
10
|
+
Excon.defaults[:mock] = true
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
# FIXME This is a bit ugly, but Excon doesn't provide a builtin way to
|
15
|
+
# ensure that a request was invoked, so we have to do it ourselves.
|
16
|
+
# Without this, and the Excon.stubs.pop calls in the tests that use this
|
17
|
+
# helper, tests will pass if request logic is completely removed from
|
18
|
+
# application code. -jkakar
|
19
|
+
assert(Excon.stubs.empty?, 'Expected HTTP requests were not made.')
|
20
|
+
super
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# A simple JSON schema for testing purposes.
|
25
|
+
SAMPLE_SCHEMA = {
|
26
|
+
'description' => 'Sample schema for use in tests.',
|
27
|
+
'definitions' => {
|
28
|
+
'resource' => {
|
29
|
+
'description' => 'A sample resource to use in tests.',
|
30
|
+
'id' => 'schema/resource',
|
31
|
+
'$schema' => 'http://json-schema.org/draft-04/hyper-schema',
|
32
|
+
'title' => 'Sample resource title',
|
33
|
+
'type' => ['object'],
|
34
|
+
|
35
|
+
'definitions' => {
|
36
|
+
'date_field' => {
|
37
|
+
'description' => 'A sample date field',
|
38
|
+
'example' => '2013-10-19 22:10:29Z',
|
39
|
+
'format' => 'date-time',
|
40
|
+
'readOnly' => true,
|
41
|
+
'type' => ['string']
|
42
|
+
},
|
43
|
+
|
44
|
+
'string_field' => {
|
45
|
+
'description' => 'A sample string field',
|
46
|
+
'example' => 'Sample text.',
|
47
|
+
'readOnly' => true,
|
48
|
+
'type' => ['string']
|
49
|
+
},
|
50
|
+
|
51
|
+
'boolean_field' => {
|
52
|
+
'description' => 'A sample boolean field',
|
53
|
+
'example' => true,
|
54
|
+
'type' => ['boolean']
|
55
|
+
},
|
56
|
+
|
57
|
+
'uuid_field' => {
|
58
|
+
'description' => 'A sample UUID field',
|
59
|
+
'example' => '44724831-bf66-4bc2-865f-e2c4c2b14c78',
|
60
|
+
'format' => 'uuid',
|
61
|
+
'readOnly' => true,
|
62
|
+
'type' => ['string']
|
63
|
+
},
|
64
|
+
|
65
|
+
'email_field' => {
|
66
|
+
'description' => 'A sample email address field',
|
67
|
+
'example' => 'username@example.com',
|
68
|
+
'format' => 'email',
|
69
|
+
'readOnly' => true,
|
70
|
+
'type' => ['string']
|
71
|
+
},
|
72
|
+
|
73
|
+
'identity' => {
|
74
|
+
'oneOf' => [
|
75
|
+
{'$ref' => '#/definitions/resource/definitions/uuid_field'},
|
76
|
+
{'$ref' => '#/definitions/resource/definitions/email_field'}]
|
77
|
+
}
|
78
|
+
},
|
79
|
+
|
80
|
+
'properties' => {
|
81
|
+
'date_field' => {
|
82
|
+
'$ref' => '#/definitions/resource/definitions/date_field'},
|
83
|
+
'string_field' => {
|
84
|
+
'$ref' => '#/definitions/resource/definitions/string_field'},
|
85
|
+
'boolean_field' => {
|
86
|
+
'$ref' => '#/definitions/resource/definitions/boolean_field'},
|
87
|
+
'uuid_field' => {
|
88
|
+
'$ref' => '#/definitions/resource/definitions/uuid_field'},
|
89
|
+
'email_field' => {
|
90
|
+
'$ref' => '#/definitions/resource/definitions/email_field'},
|
91
|
+
},
|
92
|
+
|
93
|
+
'links' => [
|
94
|
+
{'description' => 'Show all sample resources',
|
95
|
+
'href' => '/resource',
|
96
|
+
'method' => 'GET',
|
97
|
+
'rel' => 'instances',
|
98
|
+
'title' => 'List'},
|
99
|
+
|
100
|
+
{'description' => 'Show a sample resource',
|
101
|
+
'href' => '/resource/{(%23%2Fdefinitions%2Fresource%2Fdefinitions%2Fuuid_field)}',
|
102
|
+
'method' => 'GET',
|
103
|
+
'rel' => 'self',
|
104
|
+
'title' => 'Info'},
|
105
|
+
|
106
|
+
{'description' => 'Show a sample resource',
|
107
|
+
'href' => '/resource/{(%23%2Fdefinitions%2Fresource%2Fdefinitions%2Fidentity)}',
|
108
|
+
'method' => 'GET',
|
109
|
+
'rel' => 'self',
|
110
|
+
'title' => 'Identify resource'},
|
111
|
+
|
112
|
+
{'description' => 'Create a sample resource',
|
113
|
+
'href' => '/resource',
|
114
|
+
'method' => 'POST',
|
115
|
+
'rel' => 'create',
|
116
|
+
'title' => 'Create',
|
117
|
+
'schema' => {
|
118
|
+
'properties' => {
|
119
|
+
'date_field' => {
|
120
|
+
'$ref' => '#/definitions/resource/definitions/date_field'},
|
121
|
+
'string_field' => {
|
122
|
+
'$ref' => '#/definitions/resource/definitions/string_field'},
|
123
|
+
'boolean_field' => {
|
124
|
+
'$ref' => '#/definitions/resource/definitions/boolean_field'},
|
125
|
+
'uuid_field' => {
|
126
|
+
'$ref' => '#/definitions/resource/definitions/uuid_field'},
|
127
|
+
'email_field' => {
|
128
|
+
'$ref' => '#/definitions/resource/definitions/email_field'}}}},
|
129
|
+
|
130
|
+
{'description' => 'Submit a sample resource as form data',
|
131
|
+
'encType' => 'application/x-www-form-urlencoded',
|
132
|
+
'href' => '/resource',
|
133
|
+
'method' => 'POST',
|
134
|
+
'rel' => 'submit',
|
135
|
+
'title' => 'Submit',
|
136
|
+
'schema' => {
|
137
|
+
'properties' => {
|
138
|
+
'date_field' => {
|
139
|
+
'$ref' => '#/definitions/resource/definitions/date_field'},
|
140
|
+
'string_field' => {
|
141
|
+
'$ref' => '#/definitions/resource/definitions/string_field'},
|
142
|
+
'boolean_field' => {
|
143
|
+
'$ref' => '#/definitions/resource/definitions/boolean_field'},
|
144
|
+
'uuid_field' => {
|
145
|
+
'$ref' => '#/definitions/resource/definitions/uuid_field'},
|
146
|
+
'email_field' => {
|
147
|
+
'$ref' => '#/definitions/resource/definitions/email_field'}}}},
|
148
|
+
|
149
|
+
{'description' => 'Update a sample resource',
|
150
|
+
'href' => '/resource/{(%23%2Fdefinitions%2Fresource%2Fdefinitions%2Fuuid_field)}',
|
151
|
+
'method' => 'PATCH',
|
152
|
+
'rel' => 'update',
|
153
|
+
'title' => 'Update',
|
154
|
+
'schema' => {
|
155
|
+
'properties' => {
|
156
|
+
'date_field' => {
|
157
|
+
'$ref' => '#/definitions/resource/definitions/date_field'},
|
158
|
+
'string_field' => {
|
159
|
+
'$ref' => '#/definitions/resource/definitions/string_field'},
|
160
|
+
'boolean_field' => {
|
161
|
+
'$ref' => '#/definitions/resource/definitions/boolean_field'},
|
162
|
+
'uuid_field' => {
|
163
|
+
'$ref' => '#/definitions/resource/definitions/uuid_field'},
|
164
|
+
'email_field' => {
|
165
|
+
'$ref' => '#/definitions/resource/definitions/email_field'}}}},
|
166
|
+
|
167
|
+
{'description' => 'Delete an existing sample resource at specific time',
|
168
|
+
'href' => '/resource/{(%23%2Fdefinitions%2Fresource%2Fdefinitions%2Fdate_field)}',
|
169
|
+
'method' => 'DELETE',
|
170
|
+
'rel' => 'destroy',
|
171
|
+
'title' => 'Delete'}
|
172
|
+
]
|
173
|
+
},
|
174
|
+
|
175
|
+
'another-resource' => {
|
176
|
+
'description' => 'Another sample resource to use in tests.',
|
177
|
+
'id' => 'schema/another-resource',
|
178
|
+
'$schema' => 'http://json-schema.org/draft-04/hyper-schema',
|
179
|
+
'title' => 'Another sample resource title',
|
180
|
+
'type' => ['object'],
|
181
|
+
|
182
|
+
'definitions' => {},
|
183
|
+
|
184
|
+
'properties' => {},
|
185
|
+
|
186
|
+
'links' => [
|
187
|
+
{'description' => 'Create another resource',
|
188
|
+
'href' => '/another-resource',
|
189
|
+
'method' => 'POST',
|
190
|
+
'rel' => 'self',
|
191
|
+
'title' => 'Create'},
|
192
|
+
{'description' => 'Show all sample resources',
|
193
|
+
'href' => '/another-resource',
|
194
|
+
'method' => 'GET',
|
195
|
+
'rel' => 'instances',
|
196
|
+
'title' => 'List'}
|
197
|
+
]
|
198
|
+
},
|
199
|
+
},
|
200
|
+
'properties' => {
|
201
|
+
'resource' => { '$ref' => '#/definitions/resource' },
|
202
|
+
'another-resource' => { '$ref' => '#/definitions/another-resource' }
|
203
|
+
}
|
204
|
+
}
|