raml_ruby 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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