raml-rb 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.rspec +3 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +20 -0
  7. data/Rakefile +9 -0
  8. data/lib/raml/body.rb +10 -0
  9. data/lib/raml/documentation.rb +5 -0
  10. data/lib/raml/errors/unknown_attribute_error.rb +4 -0
  11. data/lib/raml/method.rb +13 -0
  12. data/lib/raml/parser/body.rb +38 -0
  13. data/lib/raml/parser/documentation.rb +37 -0
  14. data/lib/raml/parser/method.rb +83 -0
  15. data/lib/raml/parser/query_parameter.rb +39 -0
  16. data/lib/raml/parser/resource.rb +60 -0
  17. data/lib/raml/parser/response.rb +42 -0
  18. data/lib/raml/parser/root.rb +73 -0
  19. data/lib/raml/parser/util.rb +31 -0
  20. data/lib/raml/parser.rb +30 -0
  21. data/lib/raml/query_parameter.rb +10 -0
  22. data/lib/raml/resource.rb +16 -0
  23. data/lib/raml/response.rb +11 -0
  24. data/lib/raml/root.rb +15 -0
  25. data/lib/raml/version.rb +3 -0
  26. data/lib/raml-rb.rb +1 -0
  27. data/lib/raml.rb +12 -0
  28. data/raml-rb.gemspec +24 -0
  29. data/spec/fixtures/all-the-things.raml +54 -0
  30. data/spec/fixtures/basic.raml +41 -0
  31. data/spec/lib/raml/body_spec.rb +24 -0
  32. data/spec/lib/raml/documentation_spec.rb +19 -0
  33. data/spec/lib/raml/method_spec.rb +17 -0
  34. data/spec/lib/raml/parser/body_spec.rb +21 -0
  35. data/spec/lib/raml/parser/documentation_spec.rb +15 -0
  36. data/spec/lib/raml/parser/method_spec.rb +35 -0
  37. data/spec/lib/raml/parser/query_parameter_spec.rb +23 -0
  38. data/spec/lib/raml/parser/resource_spec.rb +49 -0
  39. data/spec/lib/raml/parser/response_spec.rb +30 -0
  40. data/spec/lib/raml/parser/root_spec.rb +35 -0
  41. data/spec/lib/raml/parser.rb +49 -0
  42. data/spec/lib/raml/query_parameter_spec.rb +40 -0
  43. data/spec/lib/raml/resource_spec.rb +36 -0
  44. data/spec/lib/raml/response_spec.rb +25 -0
  45. data/spec/lib/raml/root_spec.rb +36 -0
  46. data/spec/spec_helper.rb +14 -0
  47. metadata +164 -0
@@ -0,0 +1,54 @@
1
+ #%RAML 0.8
2
+
3
+ title: World Music API
4
+ baseUri: http://example.api.com/{version}
5
+ version: v1
6
+ documentation:
7
+ - title: RAML Baml
8
+ content: |
9
+ - Project: [source code](https://github.com/jpb/raml-rb)
10
+ traits:
11
+ - paged:
12
+ queryParameters:
13
+ pages:
14
+ description: The number of pages to return
15
+ type: number
16
+ - secured: !include http://raml-example.com/secured.yml
17
+ /songs:
18
+ is: [ paged, secured ]
19
+ get:
20
+ queryParameters:
21
+ genre:
22
+ description: filter the songs by genre
23
+ post:
24
+ /{songId}:
25
+ get:
26
+ responses:
27
+ 200:
28
+ body:
29
+ text/xml:
30
+ schema: |
31
+ <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
32
+ <xs:element name="api-request">
33
+ <xs:complexType>
34
+ <xs:sequence>
35
+ <xs:element type="xs:string" name="title"/>
36
+ <xs:element type="xs:string" name="artist"/>
37
+ </xs:sequence>
38
+ </xs:complexType>
39
+ </xs:element>
40
+ </xs:schema>
41
+ application/json:
42
+ schema: |
43
+ { "$schema": "http://json-schema.org/schema",
44
+ "type": "object",
45
+ "description": "A canonical song",
46
+ "properties": {
47
+ "title": { "type": "string" },
48
+ "artist": { "type": "string" }
49
+ },
50
+ "required": [ "title", "artist" ]
51
+ }
52
+ delete:
53
+ description: |
54
+ This method will *delete* an **individual song**
@@ -0,0 +1,41 @@
1
+ #%RAML 0.8
2
+
3
+ title: World Music API
4
+ baseUri: http://example.api.com/{version}
5
+ version: v1
6
+ traits:
7
+ - paged:
8
+ queryParameters:
9
+ pages:
10
+ description: The number of pages to return
11
+ type: number
12
+ - secured: !include http://raml-example.com/secured.yml
13
+ - notApplied:
14
+ fake: value
15
+ /songs:
16
+ is: [ paged, secured ]
17
+ get:
18
+ queryParameters:
19
+ genre:
20
+ description: filter the songs by genre
21
+ post:
22
+ /{songId}:
23
+ get:
24
+ responses:
25
+ 200:
26
+ body:
27
+ application/json:
28
+ schema: |
29
+ { "$schema": "http://json-schema.org/schema",
30
+ "type": "object",
31
+ "description": "A canonical song",
32
+ "properties": {
33
+ "title": { "type": "string" },
34
+ "artist": { "type": "string" }
35
+ },
36
+ "required": [ "title", "artist" ]
37
+ }
38
+ application/xml:
39
+ delete:
40
+ description: |
41
+ This method will *delete* an **individual song**
@@ -0,0 +1,24 @@
1
+ require 'raml/body'
2
+
3
+ describe Raml::Body do
4
+
5
+ describe '.new' do
6
+ subject { Raml::Body.new('the type') }
7
+ its(:type) { should == 'the type' }
8
+ end
9
+
10
+ describe '#type' do
11
+ let(:body) { Raml::Body.new('the type') }
12
+ before { body.type = 'type' }
13
+ subject { body.type }
14
+ it { should == 'type' }
15
+ end
16
+
17
+ describe '#schema' do
18
+ let(:body) { Raml::Body.new('the type') }
19
+ before { body.schema = 'schema' }
20
+ subject { body.schema }
21
+ it { should == 'schema' }
22
+ end
23
+
24
+ end
@@ -0,0 +1,19 @@
1
+ require 'raml/documentation'
2
+
3
+ describe Raml::Documentation do
4
+
5
+ describe '#title' do
6
+ let(:documentation) { Raml::Documentation.new }
7
+ before { documentation.title = 'the title' }
8
+ subject { documentation.title }
9
+ it { should == 'the title' }
10
+ end
11
+
12
+ describe '#content' do
13
+ let(:documentation) { Raml::Documentation.new }
14
+ before { documentation.content = 'the content' }
15
+ subject { documentation.content }
16
+ it { should == 'the content' }
17
+ end
18
+
19
+ end
@@ -0,0 +1,17 @@
1
+ require 'raml/method'
2
+
3
+ describe Raml::Method do
4
+
5
+ describe '.new' do
6
+ subject { Raml::Method.new('delete') }
7
+ its(:method) { should == 'delete' }
8
+ end
9
+
10
+ describe '#title' do
11
+ let(:documentation) { Raml::Documentation.new }
12
+ before { documentation.title = 'the title' }
13
+ subject { documentation.title }
14
+ it { should == 'the title' }
15
+ end
16
+
17
+ end
@@ -0,0 +1,21 @@
1
+ require 'raml/parser/body'
2
+
3
+ describe Raml::Parser::Body do
4
+ let(:instance) { Raml::Parser::Body.new }
5
+ let(:type) { 'application/json' }
6
+ let(:attribute) { { 'schema' => 'dogs' } }
7
+
8
+ describe '#parse' do
9
+ subject { instance.parse(type, attribute) }
10
+
11
+ it { should be_kind_of Raml::Body }
12
+ its(:schema) { should == 'dogs' }
13
+ end
14
+
15
+ describe '#body' do
16
+ before { instance.parse(type, attribute) }
17
+ subject { instance.body }
18
+ it { should be_kind_of Raml::Body }
19
+ end
20
+
21
+ end
@@ -0,0 +1,15 @@
1
+ require 'raml/parser/documentation'
2
+
3
+ describe Raml::Parser::Documentation do
4
+
5
+ describe '#parse' do
6
+ let(:attribute) { { 'title' => 'The title', 'content' => 'The content' } }
7
+ let(:trait_names) { nil }
8
+ subject { Raml::Parser::Documentation.new.parse(attribute) }
9
+
10
+ it { should be_kind_of Raml::Documentation }
11
+ its(:title) { should == 'The title' }
12
+ its(:content) { should == 'The content' }
13
+ end
14
+
15
+ end
@@ -0,0 +1,35 @@
1
+ require 'raml/parser/method'
2
+
3
+ describe Raml::Parser::Method do
4
+
5
+ describe '#parse' do
6
+ let(:attributes) { { 'description' => 'The description', 'headers' => [{ 'key' => 'value' }], 'responses' => ['cats'], 'query_parameters' => ['dogs'] } }
7
+ let(:parent) { double(traits: { 'cats' => { 'description' => 'Trait description', 'headers' => { 'trait_key' => 'trait_value' } } }, trait_names: nil) }
8
+ before do
9
+ Raml::Parser::Response.any_instance.stub(:parse).and_return('cats')
10
+ Raml::Parser::QueryParameter.any_instance.stub(:parse).and_return('dogs')
11
+ end
12
+ subject { Raml::Parser::Method.new(parent).parse('get', attributes) }
13
+
14
+ it { should be_kind_of Raml::Method }
15
+ its(:method) { should == 'get' }
16
+ its(:description) { should == 'The description' }
17
+ its(:headers) { should == [ { 'key' => 'value' } ] }
18
+ its(:responses) { should == ['cats'] }
19
+ its(:query_parameters) { should == ['dogs'] }
20
+
21
+ context 'with trait' do
22
+ let(:attributes) { { 'is' => [ 'cats' ], 'responses' => ['cats'], 'query_parameters' => ['dogs'] } }
23
+ its(:description) { should == 'Trait description' }
24
+ its(:headers) { [ { 'trait_key' => 'trait_value' } ] }
25
+ end
26
+
27
+ context 'override trait attributes' do
28
+ let(:attributes) { { 'is' => [ 'cats' ], 'description' => 'The description', 'headers' => [{ 'key' => 'value' }], 'responses' => ['cats'], 'query_parameters' => ['dogs'] } }
29
+ its(:description) { should == 'The description' }
30
+ its(:headers) { should == [ { 'key' => 'value' } ] }
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,23 @@
1
+ require 'raml/parser/query_parameter'
2
+
3
+ describe Raml::Parser::QueryParameter do
4
+ let(:instance) { Raml::Parser::QueryParameter.new }
5
+ let(:type) { 'application/json' }
6
+ let(:attribute) { { 'description' => 'dogs', 'type' => 'cats', 'example' => 'birds' } }
7
+
8
+ describe '#parse' do
9
+ subject { instance.parse(type, attribute) }
10
+
11
+ it { should be_kind_of Raml::QueryParameter }
12
+ its(:description) { should == 'dogs' }
13
+ its(:type) { should == 'cats' }
14
+ its(:example) { should == 'birds' }
15
+ end
16
+
17
+ describe '#query_parameter' do
18
+ before { instance.parse(type, attribute) }
19
+ subject { instance.query_parameter }
20
+ it { should be_kind_of Raml::QueryParameter }
21
+ end
22
+
23
+ end
@@ -0,0 +1,49 @@
1
+ require 'raml/parser/resource'
2
+
3
+ describe Raml::Parser::Resource do
4
+
5
+ let(:parent) { double(resource_types: { 'cats' => { 'post' => {} } }) }
6
+ let(:resources) { double('<<'.to_sym => nil) }
7
+ let(:parent_node) { double(resources: resources) }
8
+ let(:instance) { Raml::Parser::Resource.new(parent) }
9
+ let(:uri_partial) { '/cats' }
10
+ let(:attributes) { { } }
11
+
12
+ describe '#parse' do
13
+ subject { instance.parse(parent_node, uri_partial, attributes) }
14
+ it { should be_kind_of Raml::Resource }
15
+
16
+ context 'resource' do
17
+ before { subject }
18
+ let(:attributes) { { '/bar' => {} } }
19
+ it 'should create a method' do
20
+ resources.should have_received('<<').with(kind_of(Raml::Resource))
21
+ end
22
+ end
23
+
24
+ %w[get put post delete].each do |method|
25
+ context method do
26
+ let(:attributes) { { method => 'method attributess' } }
27
+ it 'should call through to method parser' do
28
+ expect_any_instance_of(Raml::Parser::Method).to receive(:parse).with(method, 'method attributess').once
29
+ instance.parse(parent_node, uri_partial, attributes)
30
+ end
31
+ end
32
+ end
33
+
34
+ context 'resource type' do
35
+ let(:attributes) { { 'type' => 'cats' } }
36
+ it 'should call through to method parser' do
37
+ expect_any_instance_of(Raml::Parser::Method).to receive(:parse).with('post', {}).once
38
+ instance.parse(parent_node, uri_partial, attributes)
39
+ end
40
+ end
41
+ end
42
+
43
+ describe '#resource' do
44
+ before { instance.parse(parent_node, uri_partial, attributes) }
45
+ subject { instance.resource }
46
+ it { should be_kind_of Raml::Resource }
47
+ end
48
+
49
+ end
@@ -0,0 +1,30 @@
1
+ require 'raml/parser/response'
2
+
3
+ describe Raml::Parser::Response do
4
+ let(:instance) { Raml::Parser::Response.new }
5
+ let(:code) { 201 }
6
+ let(:attribute) { { 'body' => { 'cats' => {} } } }
7
+
8
+ describe '#parse' do
9
+ subject { instance.parse(code, attribute) }
10
+
11
+ before do
12
+ Raml::Parser::Body.any_instance.stub(:parse)
13
+ end
14
+
15
+ it { should be_kind_of Raml::Response }
16
+ its(:code) { should == 201 }
17
+ it 'should call through to body' do
18
+ expect_any_instance_of(Raml::Parser::Body).to receive(:parse).with('cats', {}).once
19
+ subject
20
+ end
21
+ end
22
+
23
+ describe '#response' do
24
+ before { instance.parse(code, attribute) }
25
+ subject { instance.response }
26
+ it { should be_kind_of Raml::Response }
27
+ end
28
+
29
+ end
30
+
@@ -0,0 +1,35 @@
1
+ require 'raml/parser/root'
2
+ require 'yaml'
3
+
4
+ describe Raml::Parser::Root do
5
+
6
+ describe '#parse' do
7
+ let(:raml) { YAML.load File.read('spec/fixtures/basic.raml') }
8
+ subject { Raml::Parser::Root.new.parse(raml) }
9
+
10
+ it { should be_kind_of Raml::Root }
11
+ its(:base_uri) { should == 'http://example.api.com/{version}' }
12
+ its(:uri) { should == 'http://example.api.com/v1' }
13
+ its(:version) { should == 'v1' }
14
+ its('resources.count') { should == 2 }
15
+ its('resources.first.methods.count') { should == 2 }
16
+ its('resources.first.methods.first.responses.count') { should == 1 }
17
+ its('resources.first.methods.first.query_parameters.count') { should == 0 }
18
+ its('documentation.count') { should == 0 }
19
+
20
+ context 'trait-inherited attributes' do
21
+ subject { Raml::Parser::Root.new.parse(raml).resources.fetch(1).methods.first.query_parameters.first }
22
+ its(:name) { should == 'pages' }
23
+ its(:description) { should == 'The number of pages to return' }
24
+ its(:type) { should == 'number' }
25
+ end
26
+
27
+ context 'non trait-inherited attributes' do
28
+ subject { Raml::Parser::Root.new.parse(raml).resources.fetch(1).methods.first.query_parameters.last }
29
+ its(:name) { should == 'genre' }
30
+ its(:description) { should == 'filter the songs by genre' }
31
+ its(:type) { should == nil }
32
+ end
33
+ end
34
+
35
+ end
@@ -0,0 +1,49 @@
1
+ require 'raml/parser'
2
+ require 'yaml'
3
+
4
+ describe Raml::Parser do
5
+
6
+ describe '#parse' do
7
+ let(:raml) { File.read('spec/fixtures/basic.raml') }
8
+ before do
9
+ subject.stub(:parse)
10
+ Raml::Parser.new.parse(raml)
11
+ end
12
+ subject { Raml::Parser::Root.any_instance }
13
+
14
+ it { should have_received(:stub).with(YAML.load(raml)) }
15
+ end
16
+
17
+ describe '.parse' do
18
+ let(:raml) { File.read('spec/fixtures/basic.raml') }
19
+ before do
20
+ subject.stub(:parse)
21
+ Raml::Parser.parse(raml)
22
+ end
23
+ subject { Raml::Parser.any_instance }
24
+
25
+ it { should have_received(:parse).with(raml) }
26
+ end
27
+
28
+ describe '.parse_file' do
29
+ let(:raml) { File.read('spec/fixtures/basic.raml') }
30
+ before do
31
+ subject.stub(:parse)
32
+ Raml::Parser.parse_file('spec/fixtures/basic.raml')
33
+ end
34
+ subject { Raml::Parser.any_instance }
35
+
36
+ it { should have_received(:parse).with(raml) }
37
+ end
38
+
39
+ describe '.parse_file' do
40
+ before do
41
+ subject.stub(:parse_file)
42
+ Raml::Parser.parse_file('path/to/file.raml')
43
+ end
44
+ subject { Raml::Parser.any_instance }
45
+
46
+ it { should have_received(:parse_file).with('path/to/file.raml') }
47
+ end
48
+
49
+ end
@@ -0,0 +1,40 @@
1
+ require 'raml/query_parameter'
2
+
3
+ describe Raml::QueryParameter do
4
+
5
+ describe '.new' do
6
+ let(:query_parameter) { Raml::QueryParameter.new('name') }
7
+ subject { query_parameter.name }
8
+ it { should == 'name' }
9
+ end
10
+
11
+ describe '#name' do
12
+ let(:query_parameter) { Raml::QueryParameter.new('name') }
13
+ before { query_parameter.name = 'the name' }
14
+ subject { query_parameter.name }
15
+ it { should == 'the name' }
16
+ end
17
+
18
+ describe '#description' do
19
+ let(:query_parameter) { Raml::QueryParameter.new('name') }
20
+ before { query_parameter.description = 'the description' }
21
+ subject { query_parameter.description }
22
+ it { should == 'the description' }
23
+ end
24
+
25
+ describe '#type' do
26
+ let(:query_parameter) { Raml::QueryParameter.new('name') }
27
+ before { query_parameter.type = 'the type' }
28
+ subject { query_parameter.type }
29
+ it { should == 'the type' }
30
+ end
31
+
32
+ describe '#example' do
33
+ let(:query_parameter) { Raml::QueryParameter.new('name') }
34
+ before { query_parameter.example = 'the example' }
35
+ subject { query_parameter.example }
36
+ it { should == 'the example' }
37
+ end
38
+
39
+ end
40
+
@@ -0,0 +1,36 @@
1
+ require 'raml/resource'
2
+
3
+ describe Raml::Resource do
4
+
5
+ describe '.new' do
6
+ let(:parent) { double(uri: 'http://www.example.com') }
7
+ subject { Raml::Resource.new(parent, '/cats') }
8
+ its(:parent) { should == parent }
9
+ its(:uri_partial) { should == '/cats' }
10
+ its(:methods) { should == [] }
11
+ end
12
+
13
+ describe '#uri' do
14
+ let(:parent) { double(uri: 'http://www.example.com') }
15
+ let(:uri_partial) { '/cats' }
16
+ subject { Raml::Resource.new(parent, uri_partial).uri }
17
+ it { should == 'http://www.example.com/cats' }
18
+
19
+ context 'partial no slash' do
20
+ let(:uri_partial) { 'cats' }
21
+ it { should == 'http://www.example.com/cats' }
22
+ end
23
+
24
+ context 'base trailing slash' do
25
+ let(:parent) { double(uri: 'http://www.example.com') }
26
+ it { should == 'http://www.example.com/cats' }
27
+
28
+ context 'partial no slash' do
29
+ let(:uri_partial) { 'cats' }
30
+ it { should == 'http://www.example.com/cats' }
31
+ end
32
+ end
33
+ end
34
+
35
+ end
36
+
@@ -0,0 +1,25 @@
1
+ require 'raml/response'
2
+
3
+ describe Raml::Response do
4
+
5
+ describe '.new' do
6
+ subject { Raml::Response.new(201) }
7
+ its(:code) { should == 201 }
8
+ its(:bodies) { should == [] }
9
+ end
10
+
11
+ describe '#code' do
12
+ let(:response) { Raml::Response.new(201) }
13
+ before { response.code = 'the code' }
14
+ subject { response.code }
15
+ it { should == 'the code' }
16
+ end
17
+
18
+ describe '#bodies' do
19
+ let(:response) { Raml::Response.new(201) }
20
+ before { response.bodies = 'the bodies' }
21
+ subject { response.bodies }
22
+ it { should == 'the bodies' }
23
+ end
24
+
25
+ end
@@ -0,0 +1,36 @@
1
+ require 'raml/root'
2
+
3
+ describe Raml::Root do
4
+
5
+ describe '#resources' do
6
+ subject { Raml::Root.new.resources }
7
+ it { should be_kind_of Array }
8
+ end
9
+
10
+ describe '#documentation' do
11
+ subject { Raml::Root.new.documentation }
12
+ it { should be_kind_of Array }
13
+ end
14
+
15
+ describe '#uri' do
16
+ let(:root) { Raml::Root.new }
17
+ before { root.base_uri = 'http://example.com' }
18
+ subject { root.uri }
19
+ it { should == 'http://example.com' }
20
+ end
21
+
22
+ describe '#title' do
23
+ let(:root) { Raml::Root.new }
24
+ before { root.title = 'My RAML' }
25
+ subject { root.title }
26
+ it { should == 'My RAML' }
27
+ end
28
+
29
+ describe '#version' do
30
+ let(:root) { Raml::Root.new }
31
+ before { root.version = '1.0' }
32
+ subject { root.version }
33
+ it { should == '1.0' }
34
+ end
35
+
36
+ end
@@ -0,0 +1,14 @@
1
+ require 'rspec/its'
2
+
3
+ RSpec.configure do |config|
4
+
5
+ config.expect_with :rspec do |expectations|
6
+ expectations.syntax = [:should, :expect]
7
+ end
8
+
9
+ config.mock_with :rspec do |mocks|
10
+ mocks.syntax = [:expect, :should]
11
+ mocks.verify_partial_doubles = true
12
+ end
13
+
14
+ end