raml-rb 0.0.2

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.
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