raml_ruby 0.1.1 → 0.1.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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/README.md +1 -9
  4. data/Rakefile +7 -0
  5. data/lib/raml.rb +6 -26
  6. data/lib/raml/exceptions.rb +1 -0
  7. data/lib/raml/mixin/bodies.rb +3 -3
  8. data/lib/raml/mixin/documentable.rb +3 -8
  9. data/lib/raml/mixin/global.rb +14 -10
  10. data/lib/raml/mixin/headers.rb +1 -1
  11. data/lib/raml/mixin/merge.rb +4 -4
  12. data/lib/raml/mixin/secured_by.rb +27 -0
  13. data/lib/raml/mixin/validation.rb +27 -27
  14. data/lib/raml/node.rb +22 -80
  15. data/lib/raml/node/abstract_method.rb +7 -7
  16. data/lib/raml/node/abstract_resource.rb +17 -7
  17. data/lib/raml/node/body.rb +12 -10
  18. data/lib/raml/node/documentation.rb +0 -8
  19. data/lib/raml/node/method.rb +5 -7
  20. data/lib/raml/node/parameter/abstract_parameter.rb +22 -24
  21. data/lib/raml/node/parametized_reference.rb +3 -3
  22. data/lib/raml/node/resource.rb +0 -2
  23. data/lib/raml/node/resource_type.rb +9 -9
  24. data/lib/raml/node/resource_type_reference.rb +2 -2
  25. data/lib/raml/node/response.rb +0 -2
  26. data/lib/raml/node/root.rb +66 -57
  27. data/lib/raml/node/schema.rb +3 -9
  28. data/lib/raml/node/schema_reference.rb +2 -2
  29. data/lib/raml/node/security_scheme.rb +47 -0
  30. data/lib/raml/node/security_scheme_reference.rb +5 -0
  31. data/lib/raml/node/trait.rb +8 -8
  32. data/lib/raml/node/trait_reference.rb +2 -2
  33. data/lib/raml/parser.rb +25 -16
  34. data/lib/raml/version.rb +1 -1
  35. data/raml_ruby.gemspec +3 -7
  36. data/test/apis/box-api.raml +1447 -1447
  37. data/test/apis/instagram-api.raml +48 -48
  38. data/test/apis/stripe-api.raml +4266 -4266
  39. data/test/apis/twilio-rest-api.raml +47 -47
  40. data/test/apis/twitter-rest-api.raml +1883 -1883
  41. data/test/raml/body_spec.rb +22 -39
  42. data/test/raml/documentation_spec.rb +2 -12
  43. data/test/raml/method_spec.rb +112 -93
  44. data/test/raml/parameter/abstract_parameter_spec.rb +9 -34
  45. data/test/raml/parameter/query_parameter_spec.rb +0 -15
  46. data/test/raml/parameter/uri_parameter_spec.rb +1 -16
  47. data/test/raml/resource_spec.rb +59 -41
  48. data/test/raml/resource_type_spec.rb +13 -13
  49. data/test/raml/response_spec.rb +23 -36
  50. data/test/raml/root_spec.rb +85 -18
  51. data/test/raml/security_scheme_spec.rb +71 -0
  52. data/test/raml/spec_helper.rb +2 -1
  53. data/test/raml/template_spec.rb +92 -92
  54. data/test/raml/trait_spec.rb +7 -7
  55. metadata +14 -74
  56. data/templates/abstract_parameter.slim +0 -68
  57. data/templates/body.slim +0 -15
  58. data/templates/collapse.slim +0 -10
  59. data/templates/documentation.slim +0 -2
  60. data/templates/method.slim +0 -38
  61. data/templates/resource.slim +0 -33
  62. data/templates/response.slim +0 -13
  63. data/templates/root.slim +0 -39
  64. data/templates/style.sass +0 -119
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d5b2c3c690054638bb3cdf5dd0ea4fe0cf6e5763
4
- data.tar.gz: 913d89301e7cb20ff0e6c73deb7b5104b93b4e47
3
+ metadata.gz: d78e661c19f75dc28745e0c8fb4daf4573ac2e00
4
+ data.tar.gz: 05f13dc760016c4f85e02236207ff6961eb77a21
5
5
  SHA512:
6
- metadata.gz: a2c78f5010254baab46d008805a257e78a0793486f0e339607a514d2622685c6d991550f53b463ed91b1ff03aead6ff3d5ee5077ba44880dc2c2483900b3d033
7
- data.tar.gz: 1206b2996083539351d5ece371ee8451658c7994b7c9630ae99db5019b30bdd42933f673722ad28092dbc3be34da5aad19c5e63c681317d61747267db80d82ee
6
+ metadata.gz: b36dcd3894306113f8f67944fd033b8df6d6133f95e01c98fc816cd9913c1d7784da4759beaa07c3a9bb09067f2281ae5356db0e65d9b3458322b5d1a400b686
7
+ data.tar.gz: 3ae125b1d5f0c03910050a2080bdff605314a0c8cce7d6360bf5194a88caddaee6133ae5c61e23752bf3c4260d7dae1ae686bd0018a87780689a986d0de35385
@@ -4,3 +4,5 @@ rvm:
4
4
  - "2.1.2"
5
5
  - jruby-19mode
6
6
  script: bundle exec rspec test
7
+ before_install:
8
+ - gem install bundler -v 1.11.2
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # RAML ruby
2
2
 
3
- [![Build Status](https://travis-ci.org/eliaslevy/raml_ruby.svg?branch=master)](https://travis-ci.org/eliaslevy/raml_ruby)
3
+ [![Build Status](https://travis-ci.org/coub/raml_ruby.svg?branch=master)](https://travis-ci.org/coub/raml_ruby)
4
4
 
5
5
  Implementation of a RAML parser in Ruby. It uses the stdlib YAML parser
6
6
  (Psych). It can also generate HTML documentation.
@@ -40,14 +40,6 @@ To parse the file:
40
40
 
41
41
  Raml.parse_file("path/to/your/file.raml")
42
42
 
43
- To generate HTML documentation:
44
-
45
- # write to file
46
- Raml.document("/path/to/your/file.raml", "path/to/output/file.html")
47
-
48
- # or just on screen
49
- Raml.document("/path/to/your/file.raml")
50
-
51
43
  ## To Do
52
44
 
53
45
  - Align mergin strategy of conflicting properties of resource types and traits with official Javascript and Java parsers.
data/Rakefile CHANGED
@@ -1 +1,8 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec) do |t|
5
+ t.pattern = FileList['test/raml/**/*_spec.rb']
6
+ end
7
+
8
+ task default: :spec
@@ -38,6 +38,10 @@ require_relative 'raml/node/resource_type_reference'
38
38
 
39
39
  require_relative 'raml/node/template'
40
40
 
41
+ require_relative 'raml/node/security_scheme'
42
+ require_relative 'raml/node/security_scheme_reference'
43
+ require_relative 'raml/mixin/secured_by'
44
+
41
45
  require_relative 'raml/node/abstract_method'
42
46
  require_relative 'raml/node/trait'
43
47
  require_relative 'raml/node/method'
@@ -71,34 +75,10 @@ module Raml
71
75
  def self.parse_file(filepath)
72
76
  file = File.new filepath
73
77
  raise UnsupportedRamlVersion unless file.readline =~ /\A#%RAML 0.8\s*\z/
74
-
78
+
75
79
  path = File.dirname filepath
76
80
  path = nil if path == ''
77
-
78
- Raml::Parser.parse file.read, path
79
- end
80
81
 
81
- # Parses RAML from a file and generates API documentation in HTML. If no
82
- # output filename argument is given, the HTML is returned as a string. If
83
- # an output filename argument is given, the HTML is stored to a file at
84
- # that location.
85
- #
86
- # @param filepath [String] the file path of the file containing RAML.
87
- # @param out_file [String] the file path of the file to write the documentation to. Defaults to nil.
88
- # @return [String] the HTML documentation, if out_file is nil.
89
- # @raise [Errno::ENOENT] if the file can't be found.
90
- # @raise [Errno::EACCES] if the files can't be read or written.
91
- # @raise [RamlError] if the RAML is invalid.
92
- def self.document(filepath, out_file=nil)
93
- root = parse_file filepath
94
- root.expand
95
-
96
- if out_file
97
- File.open(out_file, 'w') do |file|
98
- file.write root.document
99
- end
100
- else
101
- root.document
102
- end
82
+ Raml::Parser.parse file.read, path
103
83
  end
104
84
  end
@@ -21,6 +21,7 @@ module Raml
21
21
 
22
22
  class UnknownTraitReference < RamlError; end
23
23
  class UnknownResourceTypeReference < RamlError; end
24
+ class UnknownSecuritySchemeReference < RamlError; end
24
25
  class MergeError < RamlError; end
25
26
  class UnknownTypeOrTraitParameter < RamlError; end
26
27
  class UnknownTypeOrTraitParamFunction < RamlError; end
@@ -9,11 +9,11 @@ module Raml
9
9
 
10
10
  def self.included(base)
11
11
  base.instance_eval do
12
- non_scalar_property :body
13
- children_by :bodies, :media_type , Body
12
+ non_scalar_property :body
13
+ children_by :bodies, :media_type , Body
14
14
  end
15
15
  end
16
-
16
+
17
17
  def parse_body(value)
18
18
  if value.is_a? Hash and value.keys.all? {|k| k.is_a? String and k =~ /.+\/.+/ }
19
19
  # If all keys looks like media types, its not a default media type body.
@@ -1,5 +1,3 @@
1
- require 'kramdown'
2
-
3
1
  module Raml
4
2
  module Documentable
5
3
  # @!attribute [rw] display_name
@@ -9,9 +7,6 @@ module Raml
9
7
  # @return [String, nil] the node's description.
10
8
 
11
9
  # @private
12
- def html_description
13
- Kramdown::Document.new(description, input: :GFM).to_html
14
- end
15
10
 
16
11
  private
17
12
 
@@ -22,11 +17,11 @@ module Raml
22
17
  end
23
18
 
24
19
  def validate_display_name
25
- raise InvalidProperty, "displayName property mus be a string." unless display_name.is_a? String
20
+ raise InvalidProperty, "displayName property must be a string." unless display_name.is_a? String
26
21
  end
27
22
 
28
23
  def validate_description
29
- raise InvalidProperty, "description property mus be a string." unless description.is_a? String
24
+ raise InvalidProperty, "description property must be a string." unless description.is_a? String
30
25
  end
31
26
  end
32
- end
27
+ end
@@ -5,16 +5,20 @@ module Raml
5
5
  @parent.default_media_type
6
6
  end
7
7
 
8
- def trait_declarations
9
- @parent.trait_declarations
10
- end
8
+ def trait_declarations
9
+ @parent.trait_declarations
10
+ end
11
11
 
12
- def resource_type_declarations
13
- @parent.resource_type_declarations
14
- end
12
+ def resource_type_declarations
13
+ @parent.resource_type_declarations
14
+ end
15
15
 
16
- def schema_declarations
17
- @parent.schema_declarations
18
- end
16
+ def schema_declarations
17
+ @parent.schema_declarations
18
+ end
19
+
20
+ def security_scheme_declarations
21
+ @parent.security_scheme_declarations
22
+ end
19
23
  end
20
- end
24
+ end
@@ -9,7 +9,7 @@ module Raml
9
9
 
10
10
  def self.included(base)
11
11
  base.instance_eval do
12
- non_scalar_property :headers
12
+ non_scalar_property :headers
13
13
  children_by :headers, :name, Header
14
14
  end
15
15
  end
@@ -10,15 +10,15 @@ module Raml
10
10
  end
11
11
 
12
12
  def merge_properties(other, type)
13
- match, no_match = other.send(type).values.partition { |param| self.send(type).has_key? param.name }
13
+ match, no_match = other.send(type).values.partition { |param| self.send(type).has_key? param.name }
14
14
 
15
- match.each { |param| self.send(type)[param.name].merge param }
15
+ match.each { |param| self.send(type)[param.name].merge param }
16
16
 
17
17
  # if its an optional property, and there is no match in self, don't merge it.
18
18
  no_match.reject! { |node| node.optional }
19
19
  no_match.map! { |node| node.clone }
20
20
  no_match.each { |node| node.parent = self }
21
- @children += no_match
21
+ @children += no_match
22
22
  end
23
23
  end
24
- end
24
+ end
@@ -0,0 +1,27 @@
1
+ module Raml
2
+ # @private
3
+ module SecuredBy
4
+ def parse_secured_by(data)
5
+ validate_array :secured_by, data, [String, Hash]
6
+
7
+ data.map do |security_scheme|
8
+ if security_scheme.is_a? Hash
9
+ raise InvalidProperty, 'is property with map with more than one key' if security_scheme.size > 1
10
+ raise InvalidProperty, 'is property with map of security_scheme name but params are not a map' unless
11
+ security_scheme.values[0].is_a? Hash
12
+ SecuritySchemeReference.new( security_scheme.keys[0], security_scheme.values[0], self )
13
+ else
14
+ SecuritySchemeReference.new security_scheme, {}, self
15
+ end
16
+ end
17
+ end
18
+
19
+ def _validate_secured_by
20
+ valid_security_schemes = security_scheme_declarations.keys + ["null"]
21
+ secured_by.keys.each do |security_scheme_reference|
22
+ raise UnknownSecuritySchemeReference.new(security_scheme_reference) unless
23
+ valid_security_schemes.include?(security_scheme_reference)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,49 +1,49 @@
1
1
  module Raml
2
2
  # @private
3
- module Validation
3
+ module Validation
4
4
  def validate_property(name, value, classes)
5
5
  classes = [ classes ] unless classes.is_a? Array
6
6
  raise InvalidProperty, "#{camel_case name} property must be an #{classes_to_s classes}" unless classes.include? value.class
7
7
  end
8
8
 
9
- def validate_string(name, string)
10
- validate_property name, string, String
9
+ def validate_string(name, string)
10
+ validate_property name, string, String
11
11
  raise InvalidProperty, "#{camel_case name} property must be a non-empty string." if string.empty?
12
- end
12
+ end
13
13
 
14
- def validate_array(name, array, element_classes=nil)
14
+ def validate_array(name, array, element_classes=nil)
15
15
  raise InvalidProperty, "#{camel_case name} property must be an array" unless
16
- array.is_a? Array
16
+ array.is_a? Array
17
17
 
18
18
  if element_classes
19
- element_classes = [ element_classes ] unless element_classes.is_a? Array
20
- raise InvalidProperty, "#{camel_case name} property must be an array of #{classes_to_s element_classes}" unless
21
- array.all? { |element| element_classes.include? element.class }
19
+ element_classes = [ element_classes ] unless element_classes.is_a? Array
20
+ raise InvalidProperty, "#{camel_case name} property must be an array of #{classes_to_s element_classes}" unless
21
+ array.all? { |element| element_classes.include? element.class }
22
22
  end
23
- end
23
+ end
24
24
 
25
- def validate_hash(name, hash, key_class=nil, value_class=nil)
26
- raise InvalidProperty, "#{camel_case name} property must be a map" unless
25
+ def validate_hash(name, hash, key_class=nil, value_class=nil)
26
+ raise InvalidProperty, "#{camel_case name} property must be a map" unless
27
27
  hash.is_a? Hash
28
28
 
29
29
  if key_class
30
- if key_class.is_a? Array
31
- raise InvalidProperty, "#{camel_case name} property must be a map with #{key_class} keys" unless
32
- hash.keys.all? {|key| key_class.any? { |kc| key.is_a? kc } }
33
- else
34
- raise InvalidProperty, "#{camel_case name} property must be a map with #{key_class} keys" unless
35
- hash.keys.all? {|key| key.is_a? key_class }
36
- end
30
+ if key_class.is_a? Array
31
+ raise InvalidProperty, "#{camel_case name} property must be a map with #{key_class} keys" unless
32
+ hash.keys.all? {|key| key_class.any? { |kc| key.is_a? kc } }
33
+ else
34
+ raise InvalidProperty, "#{camel_case name} property must be a map with #{key_class} keys" unless
35
+ hash.keys.all? {|key| key.is_a? key_class }
36
+ end
37
37
  end
38
38
 
39
39
  if value_class
40
- raise InvalidProperty, "#{camel_case name} property must be a map with map values: #{hash}" unless
41
- hash.values.all? {|value| value.is_a? Hash }
40
+ raise InvalidProperty, "#{camel_case name} property must be a map with map values: #{hash}" unless
41
+ hash.values.all? {|value| value.is_a?(Hash) || value.nil? }
42
42
  end
43
- end
43
+ end
44
44
 
45
- def classes_to_s(classes)
46
- classes.join(', ').gsub(/, (\w)\z/, ' or \1')
47
- end
48
- end
49
- end
45
+ def classes_to_s(classes)
46
+ classes.join(', ').gsub(/, (\w)\z/, ' or \1')
47
+ end
48
+ end
49
+ end
@@ -1,34 +1,14 @@
1
1
  require 'active_support'
2
2
  require 'active_support/core_ext/class/attribute'
3
- require 'rouge'
4
- require 'slim'
5
3
 
6
4
  module Raml
7
5
  class Node
8
- class_attribute :doc_template, :doc_template_compiled
9
-
10
- class << self
11
- # @private
12
- def relative_path(file)
13
- File.join(
14
- *File.dirname(__FILE__).
15
- split(File::SEPARATOR).
16
- reverse.
17
- drop_while { |p| p != 'lib' }.
18
- drop(1).
19
- reverse,
20
- 'templates',
21
- file
22
- )
23
- end
24
- end
25
-
26
6
  # @!attribute [r] name
27
- # @return [String,Integer] the node name (e.g. resource path, header name, etc). Usually a
7
+ # @return [String,Integer] the node name (e.g. resource path, header name, etc). Usually a
28
8
  # String. Can be an Integer for methods.
29
9
  attr_reader :name
30
10
  # @!attribute [rw] parent
31
- # @return [Raml::Node] the node's parent.
11
+ # @return [Raml::Node] the node's parent.
32
12
  attr_accessor :parent
33
13
 
34
14
  def initialize(name, parent)
@@ -36,17 +16,6 @@ module Raml
36
16
  @parent = parent
37
17
  end
38
18
 
39
- # Returns HTML documenting the node and child nodes.
40
- # @return [String] HTML documentation.
41
- def document
42
- if doc_template
43
- self.doc_template_compiled ||= Slim::Template.new(doc_template, format: :html5, pretty: true)
44
- doc_template_compiled.render self
45
- else
46
- nil
47
- end
48
- end
49
-
50
19
  private
51
20
 
52
21
  def underscore(camel_cased_word)
@@ -61,35 +30,6 @@ module Raml
61
30
  w = underscored_word.to_s.split('_')
62
31
  (w[0...1] + w[1..-1].map(&:capitalize)).join
63
32
  end
64
-
65
- def collapse(level, title, display_name=nil, &block)
66
- @@cid ||= 0
67
- @@cid += 1
68
-
69
- @@context_class ||= Struct.new(:cid, :title, :level, :display_name, :content) do
70
- def highlight_url_params(url)
71
- url.gsub(/({[^}]+})/, '<span class="url_param">\1</span>')
72
- end
73
- end
74
-
75
- context = @@context_class.new @@cid, title, level, display_name, yield
76
-
77
- @@collapse ||= Slim::Template.new(self.class.relative_path('collapse.slim'), format: :html5, pretty: true)
78
- @@collapse.render context
79
- end
80
-
81
- def highlight_url_params(url)
82
- url.gsub(/({[^}]+})/, '<span class="url_param">\1</span>')
83
- end
84
-
85
- def highlight(source, mimetype=nil)
86
- opts = { source: source }
87
- opts[:mimetype] = mimetype if mimetype
88
-
89
- formatter = Rouge::Formatters::HTML.new css_class: 'highlight'
90
- lexer = Rouge::Lexer.guess(opts).new
91
- formatter.format lexer.lex source
92
- end
93
33
  end
94
34
 
95
35
  class ValueNode < Node
@@ -139,14 +79,14 @@ module Raml
139
79
  # @private
140
80
  def non_scalar_properties; self.class.non_scalar_properties; end
141
81
  # @private
142
- def _regexp_property ; self.class._regexp_property ; end
82
+ def _regexp_property ; self.class._regexp_property ; end
143
83
 
144
84
  # @!attribute [rw] optional
145
85
  # @return [Boolean] whether the property is optional. Only valid
146
86
  # for decendant nodes a {Trait::Instance} or {ResourceType::Instance}.
147
87
  # Indicated by a trailing "?" on the property name in the RAML source.
148
88
  attr_accessor :optional
149
-
89
+
150
90
  def initialize(name, properties, parent)
151
91
  if name.is_a? String and name.end_with? '?'
152
92
  allow_optional? parent
@@ -176,26 +116,28 @@ module Raml
176
116
  maybe_exec :validate_name
177
117
  maybe_exec :validate_parent
178
118
 
179
- properties.each do |prop_name, prop_value|
180
- prop_name = prop_name.to_s
181
- under_prop_name = underscore prop_name
119
+ if !properties.nil?
120
+ properties.each do |prop_name, prop_value|
121
+ prop_name = prop_name.to_s
122
+ under_prop_name = underscore prop_name
182
123
 
183
- if scalar_properties.include? under_prop_name
184
- send "#{under_prop_name}=", prop_value
185
- maybe_exec "validate_#{under_prop_name}"
124
+ if scalar_properties.include? under_prop_name
125
+ send "#{under_prop_name}=", prop_value
126
+ maybe_exec "validate_#{under_prop_name}"
186
127
 
187
- elsif non_scalar_properties.include? under_prop_name
188
- parsed = send "parse_#{under_prop_name}", prop_value
189
- parsed = [ parsed ] unless parsed.is_a? Array
190
- @children += parsed
128
+ elsif non_scalar_properties.include? under_prop_name
129
+ parsed = send "parse_#{under_prop_name}", prop_value
130
+ parsed = [ parsed ] unless parsed.is_a? Array
131
+ @children += parsed
191
132
 
192
- elsif _regexp_property and _regexp_property[0].match prop_name
193
- parsed = self.instance_exec(prop_name, prop_value, &_regexp_property[1])
194
- parsed = [ parsed ] unless parsed.is_a? Array
195
- @children += parsed
133
+ elsif _regexp_property and _regexp_property[0].match prop_name
134
+ parsed = self.instance_exec(prop_name, prop_value, &_regexp_property[1])
135
+ parsed = [ parsed ] unless parsed.is_a? Array
136
+ @children += parsed
196
137
 
197
- else
198
- raise UnknownProperty, "#{prop_name} is an unknown property with value of #{prop_value}."
138
+ else
139
+ raise UnknownProperty, "#{prop_name} is an unknown property with value of #{prop_value}."
140
+ end
199
141
  end
200
142
  end
201
143