raml_ruby 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.travis.yml +6 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +71 -0
- data/Rakefile +1 -0
- data/fixtures/include_1.raml +7 -0
- data/fixtures/schemas/canonicalSchemas.raml +3 -0
- data/fixtures/schemas/filesystem/file.json +1 -0
- data/fixtures/schemas/filesystem/files.json +1 -0
- data/fixtures/schemas/filesystem/fileupdate.json +1 -0
- data/fixtures/schemas/filesystem/relative/test.json +1 -0
- data/lib/raml.rb +104 -0
- data/lib/raml/exceptions.rb +27 -0
- data/lib/raml/mixin/bodies.rb +32 -0
- data/lib/raml/mixin/documentable.rb +32 -0
- data/lib/raml/mixin/global.rb +20 -0
- data/lib/raml/mixin/headers.rb +22 -0
- data/lib/raml/mixin/merge.rb +24 -0
- data/lib/raml/mixin/parent.rb +54 -0
- data/lib/raml/mixin/validation.rb +49 -0
- data/lib/raml/node.rb +219 -0
- data/lib/raml/node/abstract_method.rb +61 -0
- data/lib/raml/node/abstract_resource.rb +165 -0
- data/lib/raml/node/abstract_resource_circular.rb +5 -0
- data/lib/raml/node/body.rb +94 -0
- data/lib/raml/node/documentation.rb +28 -0
- data/lib/raml/node/header.rb +4 -0
- data/lib/raml/node/method.rb +106 -0
- data/lib/raml/node/parameter/abstract_parameter.rb +251 -0
- data/lib/raml/node/parameter/base_uri_parameter.rb +6 -0
- data/lib/raml/node/parameter/form_parameter.rb +6 -0
- data/lib/raml/node/parameter/query_parameter.rb +6 -0
- data/lib/raml/node/parameter/uri_parameter.rb +7 -0
- data/lib/raml/node/parametized_reference.rb +15 -0
- data/lib/raml/node/reference.rb +4 -0
- data/lib/raml/node/resource.rb +26 -0
- data/lib/raml/node/resource_type.rb +20 -0
- data/lib/raml/node/resource_type_reference.rb +5 -0
- data/lib/raml/node/response.rb +32 -0
- data/lib/raml/node/root.rb +246 -0
- data/lib/raml/node/schema.rb +41 -0
- data/lib/raml/node/schema_reference.rb +5 -0
- data/lib/raml/node/template.rb +55 -0
- data/lib/raml/node/trait.rb +18 -0
- data/lib/raml/node/trait_reference.rb +5 -0
- data/lib/raml/parser.rb +57 -0
- data/lib/raml/parser/include.rb +25 -0
- data/lib/raml/patch/hash.rb +6 -0
- data/lib/raml/patch/module.rb +12 -0
- data/lib/raml/version.rb +3 -0
- data/raml_ruby.gemspec +35 -0
- data/raml_spec_reqs.md +276 -0
- data/templates/abstract_parameter.slim +68 -0
- data/templates/body.slim +15 -0
- data/templates/collapse.slim +10 -0
- data/templates/documentation.slim +2 -0
- data/templates/method.slim +38 -0
- data/templates/resource.slim +33 -0
- data/templates/response.slim +13 -0
- data/templates/root.slim +39 -0
- data/templates/style.sass +119 -0
- data/test/apis/box-api.raml +4224 -0
- data/test/apis/instagram-api.raml +3378 -0
- data/test/apis/stripe-api.raml +12227 -0
- data/test/apis/twilio-rest-api.raml +6618 -0
- data/test/apis/twitter-rest-api.raml +34284 -0
- data/test/raml/body_spec.rb +268 -0
- data/test/raml/documentation_spec.rb +49 -0
- data/test/raml/header_spec.rb +17 -0
- data/test/raml/include_spec.rb +40 -0
- data/test/raml/method_spec.rb +701 -0
- data/test/raml/parameter/abstract_parameter_spec.rb +564 -0
- data/test/raml/parameter/form_parameter_spec.rb +17 -0
- data/test/raml/parameter/query_parameter_spec.rb +33 -0
- data/test/raml/parameter/uri_parameter_spec.rb +44 -0
- data/test/raml/parser_spec.rb +53 -0
- data/test/raml/raml_spec.rb +32 -0
- data/test/raml/resource_spec.rb +440 -0
- data/test/raml/resource_type_spec.rb +51 -0
- data/test/raml/response_spec.rb +251 -0
- data/test/raml/root_spec.rb +655 -0
- data/test/raml/schema_spec.rb +110 -0
- data/test/raml/spec_helper.rb +11 -0
- data/test/raml/template_spec.rb +98 -0
- data/test/raml/trait_spec.rb +31 -0
- metadata +337 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe Raml::Parameter::FormParameter do
|
4
|
+
let(:root_data) { {'title' => 'x', 'baseUri' => 'http://foo.com'} }
|
5
|
+
let(:root) { Raml::Root.new root_data }
|
6
|
+
let(:name) { 'AWSAccessKeyId' }
|
7
|
+
let (:data) {
|
8
|
+
YAML.load(%q(
|
9
|
+
description: The AWS Access Key ID of the owner of the bucket who grants ...
|
10
|
+
type: string
|
11
|
+
))
|
12
|
+
}
|
13
|
+
|
14
|
+
it "should instanciate Form parameter" do
|
15
|
+
Raml::Parameter::FormParameter.new(name, data, root)
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe Raml::Parameter::QueryParameter do
|
4
|
+
let(:root_data) { {'title' => 'x', 'baseUri' => 'http://foo.com'} }
|
5
|
+
let(:root) { Raml::Root.new root_data }
|
6
|
+
let(:name) { 'page' }
|
7
|
+
let(:data) {
|
8
|
+
YAML.load(%q(
|
9
|
+
type: integer
|
10
|
+
))
|
11
|
+
}
|
12
|
+
|
13
|
+
subject { Raml::Parameter::QueryParameter.new(name, data, root) }
|
14
|
+
|
15
|
+
it "should instanciate Query parameter" do
|
16
|
+
Raml::Parameter::QueryParameter.new(name, data, root)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#document" do
|
20
|
+
let(:data) {
|
21
|
+
YAML.load(%q(
|
22
|
+
description: Specify the page that you want to retrieve
|
23
|
+
type: integer
|
24
|
+
required: true
|
25
|
+
example: 1
|
26
|
+
))
|
27
|
+
}
|
28
|
+
|
29
|
+
it "prints out documentation" do
|
30
|
+
subject.document
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe Raml::Parameter::UriParameter do
|
4
|
+
let(:root_data) { {'title' => 'x', 'baseUri' => 'http://foo.com'} }
|
5
|
+
let(:root) { Raml::Root.new root_data }
|
6
|
+
let(:name) { 'AccountSid' }
|
7
|
+
let(:data) {
|
8
|
+
YAML.load(%q(
|
9
|
+
description: |
|
10
|
+
An Account instance resource represents a single Twilio account.
|
11
|
+
type: string
|
12
|
+
))
|
13
|
+
}
|
14
|
+
|
15
|
+
subject { Raml::Parameter::UriParameter.new(name, data, root) }
|
16
|
+
|
17
|
+
describe '#new' do
|
18
|
+
it "should instanciate Uri parameter" do
|
19
|
+
Raml::Parameter::UriParameter.new(name, data, root)
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when no required attribute is given' do
|
23
|
+
let(:data) { { } }
|
24
|
+
it 'defaults to true' do
|
25
|
+
subject.required.should == true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#document" do
|
31
|
+
let(:data) {
|
32
|
+
YAML.load(%q(
|
33
|
+
description: Specify the page that you want to retrieve
|
34
|
+
type: integer
|
35
|
+
required: true
|
36
|
+
example: 1
|
37
|
+
))
|
38
|
+
}
|
39
|
+
|
40
|
+
it "prints out documentation" do
|
41
|
+
subject.document
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe Raml::Parser do
|
4
|
+
let (:data) {
|
5
|
+
%q(
|
6
|
+
#%RAML 0.8
|
7
|
+
baseUri: https://api.example.com
|
8
|
+
title: Filesystem API
|
9
|
+
version: 0.1
|
10
|
+
/files:
|
11
|
+
get:
|
12
|
+
responses:
|
13
|
+
200:
|
14
|
+
body:
|
15
|
+
application/xml:
|
16
|
+
schema: Files
|
17
|
+
)
|
18
|
+
}
|
19
|
+
|
20
|
+
describe '.parse' do
|
21
|
+
it "should parse the data" do
|
22
|
+
root = Raml::Parser.parse(data)
|
23
|
+
root.should be_a Raml::Root
|
24
|
+
root.title.should eq 'Filesystem API'
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when the RAML file has !include directives' do
|
28
|
+
it 'inserts the data into the right location and parses RAML included files' do
|
29
|
+
file = File.new 'fixtures/include_1.raml'
|
30
|
+
root = Raml::Parser.parse file.read, 'fixtures'
|
31
|
+
root.schemas.should be_a Hash
|
32
|
+
root.schemas.size.should be 4
|
33
|
+
root.schemas.keys.should contain_exactly('FileUpdate', 'Files', 'Test', 'File')
|
34
|
+
root.schemas['FileUpdate'].value.should eq 'file_update_schema'
|
35
|
+
root.schemas['Files' ].value.should eq 'files_schema'
|
36
|
+
root.schemas['Test' ].value.should eq 'test_schema'
|
37
|
+
root.schemas['File' ].value.should eq 'file_schema'
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'when the included file is not redable' do
|
41
|
+
it do
|
42
|
+
expect { Raml::Parser.parse('- !include does_not_exit') }.to raise_error Raml::CantIncludeFile
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when the !include directive is not given a file path' do
|
47
|
+
it do
|
48
|
+
expect { Raml::Parser.parse('- !include') }.to raise_error Raml::CantIncludeFile
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe Raml do
|
4
|
+
describe '#parse_file' do
|
5
|
+
let(:rest_of_doc) { "title: Some API\nbaseUri: https://app.zencoder.com/api" }
|
6
|
+
before do
|
7
|
+
stub(File).new('file.raml').stub! do |stub|
|
8
|
+
stub.readline { comment }
|
9
|
+
stub.read { rest_of_doc }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
context 'when given a valid RAML 0.8 file with a valid version comment' do
|
13
|
+
let(:comment ) { '#%RAML 0.8' }
|
14
|
+
it do
|
15
|
+
expect { Raml.parse_file 'file.raml' }.to_not raise_error
|
16
|
+
end
|
17
|
+
end
|
18
|
+
context 'when given a valid RAML 0.8 file with an invalid version comment' do
|
19
|
+
let(:comment ) { '#%RAML 0.7' }
|
20
|
+
it do
|
21
|
+
expect { Raml.parse_file 'file.raml' }.to raise_error Raml::UnsupportedRamlVersion
|
22
|
+
end
|
23
|
+
end
|
24
|
+
context 'when given a valid RAML 0.8 file with no version comment' do
|
25
|
+
let(:comment ) { 'title: Some API' }
|
26
|
+
let(:rest_of_doc) { 'version: v2' }
|
27
|
+
it do
|
28
|
+
expect { Raml.parse_file 'file.raml' }.to raise_error Raml::UnsupportedRamlVersion
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,440 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require_relative 'spec_helper'
|
3
|
+
|
4
|
+
describe Raml::Resource do
|
5
|
+
let(:name) { '/{id}' }
|
6
|
+
let(:data) {
|
7
|
+
YAML.load(%q(
|
8
|
+
uriParameters:
|
9
|
+
id:
|
10
|
+
type: integer
|
11
|
+
required: true
|
12
|
+
example: 277102
|
13
|
+
/processing_status:
|
14
|
+
get:
|
15
|
+
displayName: Processing status
|
16
|
+
description: Получить статус загрузки
|
17
|
+
responses:
|
18
|
+
200:
|
19
|
+
body:
|
20
|
+
application/json:
|
21
|
+
example: |
|
22
|
+
{
|
23
|
+
"percent": 0,
|
24
|
+
"type": "download",
|
25
|
+
"status":"initial"
|
26
|
+
}
|
27
|
+
))
|
28
|
+
}
|
29
|
+
let(:root_data) { {'title' => 'x', 'baseUri' => 'http://foo.com'} }
|
30
|
+
let(:root) { Raml::Root.new root_data }
|
31
|
+
|
32
|
+
subject { Raml::Resource.new(name, data, root) }
|
33
|
+
|
34
|
+
describe '#new' do
|
35
|
+
it "should instanciate Resource" do
|
36
|
+
subject
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when displayName is given' do
|
40
|
+
let(:data) { { 'displayName' => 'My Name', 'description' => 'foo' } }
|
41
|
+
it { expect { subject }.to_not raise_error }
|
42
|
+
it 'should store the value' do
|
43
|
+
subject.display_name.should eq data['displayName']
|
44
|
+
end
|
45
|
+
it 'uses the displayName in the documentation' do
|
46
|
+
subject.document.should include data['displayName']
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'when description is not given' do
|
51
|
+
let(:data) { {} }
|
52
|
+
it { expect { subject }.to_not raise_error }
|
53
|
+
end
|
54
|
+
context 'when description is given' do
|
55
|
+
context 'when the description property is not a string' do
|
56
|
+
let(:data) { { 'description' => 1 } }
|
57
|
+
it { expect { subject }.to raise_error Raml::InvalidProperty, /description/ }
|
58
|
+
end
|
59
|
+
context 'when the description property is a string' do
|
60
|
+
let(:data) { { 'description' => 'My Description'} }
|
61
|
+
it { expect { subject }.to_not raise_error }
|
62
|
+
it 'should store the value' do
|
63
|
+
subject.description.should eq data['description']
|
64
|
+
end
|
65
|
+
it 'uses the description in the documentation' do
|
66
|
+
subject.document.should include data['description']
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when the uriParameters parameter is given with valid parameters' do
|
72
|
+
context 'when the uriParameters property is well formed' do
|
73
|
+
it { expect { subject }.to_not raise_error }
|
74
|
+
it 'stores all as Raml::Parameter::UriParameter instances' do
|
75
|
+
expect( subject.uri_parameters.values ).to all( be_a Raml::Parameter::UriParameter )
|
76
|
+
end
|
77
|
+
end
|
78
|
+
context 'when the uriParameters property is not a map' do
|
79
|
+
let(:data) { { 'uriParameters' => 1 } }
|
80
|
+
it { expect { subject }.to raise_error Raml::InvalidProperty, /uriParameters/ }
|
81
|
+
end
|
82
|
+
context 'when the uriParameters property is not a map with non-string keys' do
|
83
|
+
let(:data) { { 'uriParameters' => { 1 => {}} } }
|
84
|
+
it { expect { subject }.to raise_error Raml::InvalidProperty, /uriParameters/ }
|
85
|
+
end
|
86
|
+
context 'when the uriParameters property is not a map with non-string keys' do
|
87
|
+
let(:data) { { 'uriParameters' => { '1' => 'x'} } }
|
88
|
+
it { expect { subject }.to raise_error Raml::InvalidProperty, /uriParameters/ }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'when nested resources are defined' do
|
93
|
+
let(:name) { '/{userId}' }
|
94
|
+
let(:data) {
|
95
|
+
YAML.load(
|
96
|
+
%q(
|
97
|
+
uriParameters:
|
98
|
+
userId:
|
99
|
+
type: integer
|
100
|
+
/followers:
|
101
|
+
displayName: Followers
|
102
|
+
/following:
|
103
|
+
displayName: Following
|
104
|
+
/keys:
|
105
|
+
/{keyId}:
|
106
|
+
uriParameters:
|
107
|
+
keyId:
|
108
|
+
type: integer
|
109
|
+
)
|
110
|
+
)
|
111
|
+
}
|
112
|
+
it { expect { subject }.to_not raise_error }
|
113
|
+
it 'stores all as Raml::Resource instances' do
|
114
|
+
expect( subject.resources.values ).to all( be_a Raml::Resource )
|
115
|
+
expect( subject.resources.keys ).to contain_exactly('/followers','/following', '/keys')
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'when a baseUriParameters property is given' do
|
120
|
+
context 'when the baseUriParameters property is well formed' do
|
121
|
+
let(:name) { '/files' }
|
122
|
+
let(:data) {
|
123
|
+
YAML.load(
|
124
|
+
%q(
|
125
|
+
displayName: Download files
|
126
|
+
baseUriParameters:
|
127
|
+
apiDomain:
|
128
|
+
enum: [ "api-content" ]
|
129
|
+
)
|
130
|
+
)
|
131
|
+
}
|
132
|
+
|
133
|
+
it { expect { subject }.to_not raise_error }
|
134
|
+
it 'stores all as Raml::Parameter::UriParameter instances' do
|
135
|
+
expect( subject.base_uri_parameters.values ).to all( be_a Raml::Parameter::BaseUriParameter )
|
136
|
+
subject.base_uri_parameters.keys.should contain_exactly('apiDomain')
|
137
|
+
end
|
138
|
+
end
|
139
|
+
context 'when the baseUriParameters property is not a map' do
|
140
|
+
before { data['baseUriParameters'] = 1 }
|
141
|
+
it { expect { subject }.to raise_error Raml::InvalidProperty, /baseUriParameters/ }
|
142
|
+
end
|
143
|
+
context 'when the baseUriParameters property is not a map with non-string keys' do
|
144
|
+
before { data['baseUriParameters'] = { 1 => {}} }
|
145
|
+
it { expect { subject }.to raise_error Raml::InvalidProperty, /baseUriParameters/ }
|
146
|
+
end
|
147
|
+
context 'when the baseUriParameters property is not a map with non-string keys' do
|
148
|
+
before { data['baseUriParameters'] = { '1' => 'x'} }
|
149
|
+
it { expect { subject }.to raise_error Raml::InvalidProperty, /baseUriParameters/ }
|
150
|
+
end
|
151
|
+
context 'when the baseUriParameters property has a key for the reserved "version" parameter' do
|
152
|
+
before { data['baseUriParameters'] = { 'version' => {}} }
|
153
|
+
it { expect { subject }.to raise_error Raml::InvalidProperty, /baseUriParameters/ }
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context 'when an type property is given' do
|
158
|
+
let(:root) {
|
159
|
+
Raml::Root.new 'title' => 'x', 'baseUri' => 'http://foo.com', 'resourceTypes' => [
|
160
|
+
{ 'collection' => {} },
|
161
|
+
{ 'member' => {} },
|
162
|
+
{ 'auditableResource' => {} }
|
163
|
+
]
|
164
|
+
}
|
165
|
+
context 'when the property is valid' do
|
166
|
+
context 'when the property is a resource type reference' do
|
167
|
+
before { data['type'] = 'collection' }
|
168
|
+
it { expect { subject }.to_not raise_error }
|
169
|
+
it 'should store the resource type reference' do
|
170
|
+
subject.type.should be_a Raml::ResourceTypeReference
|
171
|
+
subject.type.name.should == 'collection'
|
172
|
+
end
|
173
|
+
end
|
174
|
+
context 'when the property is a resource type reference with parameters' do
|
175
|
+
before { data['type'] = {'collection' => {'maxSize' => 10}} }
|
176
|
+
it { expect { subject }.to_not raise_error }
|
177
|
+
it 'should store the resource type reference' do
|
178
|
+
subject.type.should be_a Raml::ResourceTypeReference
|
179
|
+
subject.type.name.should == 'collection'
|
180
|
+
end
|
181
|
+
end
|
182
|
+
context 'when the property is a resource type definitions' do
|
183
|
+
let(:definition) {
|
184
|
+
YAML.load(%q(
|
185
|
+
usage: This resourceType should be used for any collection of items
|
186
|
+
description: The collection of <<resourcePathName>>
|
187
|
+
get:
|
188
|
+
description: Get all <<resourcePathName>>, optionally filtered
|
189
|
+
))
|
190
|
+
}
|
191
|
+
before { data['type'] = definition }
|
192
|
+
|
193
|
+
it { expect { subject }.to_not raise_error }
|
194
|
+
it 'should store the resource type' do
|
195
|
+
subject.type.should be_a Raml::ResourceType
|
196
|
+
subject.send(:instantiate_resource_type).usage.should == definition['usage']
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
context 'when the property is invalid' do
|
201
|
+
context 'when the type property is not a string or a map' do
|
202
|
+
before { data['type'] = 1 }
|
203
|
+
it { expect { subject }.to raise_error Raml::InvalidProperty, /type/ }
|
204
|
+
end
|
205
|
+
context 'when the property is a resource type name with parameters, but the params are not a map' do
|
206
|
+
before { data['type'] = { 'collection' => 1 } }
|
207
|
+
it { expect { subject }.to raise_error Raml::InvalidProperty, /type/ }
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
context 'when an is property is given' do
|
213
|
+
let(:root) {
|
214
|
+
Raml::Root.new 'title' => 'x', 'baseUri' => 'http://foo.com', 'traits' => [
|
215
|
+
{ 'secured' => {} },
|
216
|
+
{ 'paged' => {} },
|
217
|
+
{ 'rateLimited' => {} }
|
218
|
+
]
|
219
|
+
}
|
220
|
+
context 'when the property is valid' do
|
221
|
+
context 'when the property is an array of trait references' do
|
222
|
+
let(:data) { { 'is' => [ 'secured', 'paged' ] } }
|
223
|
+
it { expect { subject }.to_not raise_error }
|
224
|
+
it 'should store the trait references' do
|
225
|
+
subject.traits.should all( be_a Raml::TraitReference )
|
226
|
+
subject.traits.map(&:name).should contain_exactly('secured', 'paged')
|
227
|
+
end
|
228
|
+
end
|
229
|
+
context 'when the property is an array of trait references with parameters' do
|
230
|
+
let(:data) { {
|
231
|
+
'is' => [
|
232
|
+
{'secured' => {'tokenName' => 'access_token'}},
|
233
|
+
{'paged' => {'maxPages' => 10 }}
|
234
|
+
]
|
235
|
+
} }
|
236
|
+
it { expect { subject }.to_not raise_error }
|
237
|
+
it 'should store the trait references' do
|
238
|
+
subject.traits.should all( be_a Raml::TraitReference )
|
239
|
+
subject.traits.map(&:name).should contain_exactly('secured', 'paged')
|
240
|
+
end
|
241
|
+
end
|
242
|
+
context 'when the property is an array of trait definitions' do
|
243
|
+
let(:data) { {
|
244
|
+
'is' => [
|
245
|
+
{'queryParameters' => {'tokenName' => {'description'=>'foo'}}},
|
246
|
+
{'queryParameters' => {'numPages' => {'description'=>'bar'}}}
|
247
|
+
]
|
248
|
+
} }
|
249
|
+
it { expect { subject }.to_not raise_error }
|
250
|
+
it 'should store the traits' do
|
251
|
+
subject.traits.should all( be_a Raml::Trait )
|
252
|
+
subject.traits[0].value.should eq ({'queryParameters' => {'tokenName' => {'description'=>'foo'}}})
|
253
|
+
subject.traits[1].value.should eq ({'queryParameters' => {'numPages' => {'description'=>'bar'}}})
|
254
|
+
end
|
255
|
+
end
|
256
|
+
context 'when the property is an array of mixed trait refrences, trait refrences with parameters, and trait definitions' do
|
257
|
+
let(:data) { {
|
258
|
+
'is' => [
|
259
|
+
{'secured' => {'tokenName' => 'access_token'}},
|
260
|
+
{'queryParameters' => {'numPages' => {'description'=>'bar'}}},
|
261
|
+
'rateLimited'
|
262
|
+
]
|
263
|
+
} }
|
264
|
+
it { expect { subject }.to_not raise_error }
|
265
|
+
it 'should store the traits' do
|
266
|
+
subject.traits.select {|t| t.is_a? Raml::TraitReference }.map(&:name).should contain_exactly('secured', 'rateLimited')
|
267
|
+
subject.traits.select {|t| t.is_a? Raml::Trait }[0].value.should eq ({'queryParameters' => {'numPages' => {'description'=>'bar'}}})
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
context 'when the property is invalid' do
|
272
|
+
context 'when the property is not an array' do
|
273
|
+
let(:data) { { 'is' => 1 } }
|
274
|
+
it { expect { subject }.to raise_error Raml::InvalidProperty, /is/ }
|
275
|
+
end
|
276
|
+
context 'when the property is an array with elements other than a string or map' do
|
277
|
+
let(:data) { { 'is' => [1] } }
|
278
|
+
it { expect { subject }.to raise_error Raml::InvalidProperty, /is/ }
|
279
|
+
end
|
280
|
+
context 'when the property is an array an element that appears to be a trait name with parameters, but the params are not a map' do
|
281
|
+
let(:data) { { 'is' => [ { 'secured' => 1 } ] } }
|
282
|
+
it { expect { subject }.to raise_error Raml::InvalidProperty, /is/ }
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
context 'when the syntax tree contains optional properties' do
|
288
|
+
let(:data) {
|
289
|
+
YAML.load(%q(
|
290
|
+
uriParameters:
|
291
|
+
id:
|
292
|
+
type: integer
|
293
|
+
required: true
|
294
|
+
example: 277102
|
295
|
+
/processing_status:
|
296
|
+
get:
|
297
|
+
displayName: Processing status
|
298
|
+
description: Получить статус загрузки
|
299
|
+
responses:
|
300
|
+
200?:
|
301
|
+
body:
|
302
|
+
application/json:
|
303
|
+
example: |
|
304
|
+
{
|
305
|
+
"percent": 0,
|
306
|
+
"type": "download",
|
307
|
+
"status":"initial"
|
308
|
+
}
|
309
|
+
))
|
310
|
+
}
|
311
|
+
it { expect { subject }.to raise_error Raml::InvalidProperty, /Optional properties/ }
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
describe '#apply_resource_type' do
|
316
|
+
let(:resource_data) { {
|
317
|
+
'type' => {
|
318
|
+
'get' => { 'description' => 'resource type description', 'displayName' => 'resource type displayName' }
|
319
|
+
},
|
320
|
+
'get' => {'description' => 'method description'},
|
321
|
+
'post' => {},
|
322
|
+
'/foo' => {},
|
323
|
+
'/bar' => {}
|
324
|
+
} }
|
325
|
+
let(:resource) { Raml::Resource.new('/foo', resource_data, root) }
|
326
|
+
context 'when it has a resource type' do
|
327
|
+
it 'merges the resource type to the resource' do
|
328
|
+
resource.type.should be_a Raml::ResourceType
|
329
|
+
mock.proxy(resource).instantiate_resource_type { |instantiated_type|
|
330
|
+
mock(resource).merge(instantiated_type)
|
331
|
+
mock(resource).merge(is_a(Raml::Resource))
|
332
|
+
instantiated_type
|
333
|
+
}
|
334
|
+
resource.apply_resource_type
|
335
|
+
end
|
336
|
+
it 'applies the resource type correctly' do
|
337
|
+
resource.apply_resource_type
|
338
|
+
resource.methods['get'].description.should eq 'method description'
|
339
|
+
resource.methods['get'].display_name.should eq 'resource type displayName'
|
340
|
+
end
|
341
|
+
end
|
342
|
+
context 'when it has nested resources' do
|
343
|
+
it 'calls #apply_resource_type on the nested resources' do
|
344
|
+
resource.resources.size.should eq 2
|
345
|
+
resource.resources.values.each { |resource| mock(resource).apply_resource_type {} }
|
346
|
+
resource.apply_resource_type
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
describe '#apply_traits' do
|
352
|
+
let(:resource_data) { {
|
353
|
+
'is' => [
|
354
|
+
{ 'description' => 'trait1 description' },
|
355
|
+
{ 'description' => 'trait2 description' }
|
356
|
+
],
|
357
|
+
'get' => {},
|
358
|
+
'post' => {},
|
359
|
+
'/foo' => {},
|
360
|
+
'/bar' => {}
|
361
|
+
} }
|
362
|
+
let(:resource) { Raml::Resource.new('/foo', resource_data, root) }
|
363
|
+
it 'calls apply_traits on all its methods' do
|
364
|
+
resource.traits.size.should eq 2
|
365
|
+
resource.methods.size.should eq 2
|
366
|
+
resource.methods.values.each { |method| mock(method).apply_traits {} }
|
367
|
+
resource.apply_traits
|
368
|
+
end
|
369
|
+
it 'should call apply_trait on child resources without the resource traits' do
|
370
|
+
resource.traits.size.should eq 2
|
371
|
+
resource.resources.size.should eq 2
|
372
|
+
resource.resources.values.each { |resource| mock(resource).apply_traits {} }
|
373
|
+
resource.apply_traits
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
describe '#merge' do
|
378
|
+
let(:resource) { Raml::Resource.new('/foo', resource_data, root) }
|
379
|
+
context 'when called with something other than a ResourceType' do
|
380
|
+
let(:resource_data) { {} }
|
381
|
+
it do
|
382
|
+
expect { resource.merge(Raml::ResourceTypeReference.new('bar', root)) }.to raise_error Raml::MergeError
|
383
|
+
end
|
384
|
+
end
|
385
|
+
context 'when called with a ResourceType::Instance' do
|
386
|
+
let(:root_data) { {
|
387
|
+
'title' => 'x',
|
388
|
+
'baseUri' => 'http://foo.com',
|
389
|
+
'traits' => [ {
|
390
|
+
'secured' => { 'usage' => 'requires authentication' },
|
391
|
+
'paged' => { 'usage' => 'allows for paging' }
|
392
|
+
} ]
|
393
|
+
} }
|
394
|
+
let(:resource_type) { Raml::ResourceType.new('bar', resource_type_data, root).instantiate({}) }
|
395
|
+
let(:resource_data) { {
|
396
|
+
'is' => [ 'secured' ],
|
397
|
+
'baseUriParameters' => { 'apiDomain' => { 'enum' => ['api'] } },
|
398
|
+
'uriParameters' => { 'userId' => { 'type' => 'integer' } },
|
399
|
+
'get' => {
|
400
|
+
'queryParameters' => { 'id' => { 'type' => 'integer' } }
|
401
|
+
}
|
402
|
+
} }
|
403
|
+
let(:resource_type_data) { {
|
404
|
+
'usage' => 'resource usage',
|
405
|
+
'is' => [ 'paged' ],
|
406
|
+
'baseUriParameters' => { 'apiDomain' => { 'enum' => ['static'] } },
|
407
|
+
'uriParameters' => { 'language' => { 'default' => 'en' } },
|
408
|
+
'get' => {
|
409
|
+
'queryParameters' => { 'query' => { 'maxLength' => 100 } }
|
410
|
+
},
|
411
|
+
'post' => {
|
412
|
+
'description' => 'create a new one'
|
413
|
+
}
|
414
|
+
} }
|
415
|
+
it 'merges the resource type into the resource' do
|
416
|
+
resource.merge resource_type
|
417
|
+
resource.traits.map { |trait_ref| trait_ref.name }.should eq [ 'paged', 'secured' ]
|
418
|
+
resource.base_uri_parameters.keys.should contain_exactly('apiDomain')
|
419
|
+
resource.base_uri_parameters['apiDomain'].enum.should eq ['static']
|
420
|
+
resource.uri_parameters.keys.should contain_exactly('userId', 'language')
|
421
|
+
resource.methods.keys.should contain_exactly('get', 'post')
|
422
|
+
resource.methods['get'].query_parameters.keys.should contain_exactly('id', 'query')
|
423
|
+
end
|
424
|
+
it 'does not add the usage property to the resource' do
|
425
|
+
resource.merge resource_type
|
426
|
+
expect { resource.usage }.to raise_error NoMethodError
|
427
|
+
end
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
431
|
+
describe '#document' do
|
432
|
+
it 'returns a String' do
|
433
|
+
subject.document.should be_a String
|
434
|
+
end
|
435
|
+
it 'should render the template' do
|
436
|
+
mock(Slim::Template).new(/templates\/resource.slim\z/, is_a(Hash)).mock!.render(is_a(Raml::Node)) { '' }
|
437
|
+
subject.document
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|