raml_ruby 0.1.1
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 +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
|