swaggable 0.4.0
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 +2 -0
- data/Gemfile +14 -0
- data/LICENSE.txt +20 -0
- data/README.md +123 -0
- data/Rakefile +13 -0
- data/assets/json-schema-draft-04.json +150 -0
- data/assets/swagger-2.0-schema.json +1495 -0
- data/lib/swaggable.rb +14 -0
- data/lib/swaggable/api_definition.rb +52 -0
- data/lib/swaggable/endpoint_definition.rb +54 -0
- data/lib/swaggable/grape_adapter.rb +84 -0
- data/lib/swaggable/parameter_definition.rb +50 -0
- data/lib/swaggable/rack_app.rb +30 -0
- data/lib/swaggable/response_definition.rb +16 -0
- data/lib/swaggable/swagger_2_serializer.rb +92 -0
- data/lib/swaggable/swagger_2_validator.rb +28 -0
- data/lib/swaggable/tag_definition.rb +27 -0
- data/lib/swaggable/version.rb +3 -0
- data/spec/assets/valid-swagger-2.0.json +1 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/swaggable/api_definition_spec.rb +169 -0
- data/spec/swaggable/endpoint_definition_spec.rb +77 -0
- data/spec/swaggable/grape_adapter_spec.rb +198 -0
- data/spec/swaggable/integration_spec.rb +100 -0
- data/spec/swaggable/parameter_definition_spec.rb +64 -0
- data/spec/swaggable/rack_app_spec.rb +49 -0
- data/spec/swaggable/response_definition_spec.rb +17 -0
- data/spec/swaggable/swagger_2_serializer_spec.rb +208 -0
- data/spec/swaggable/swagger_2_validator_spec.rb +26 -0
- data/spec/swaggable/tag_definition_spec.rb +48 -0
- data/spec/swaggable_spec.rb +7 -0
- data/swaggable.gemspec +29 -0
- metadata +161 -0
    
        data/lib/swaggable.rb
    ADDED
    
    | @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            require 'swaggable/version'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Swaggable
         | 
| 4 | 
            +
              autoload :ApiDefinition, 'swaggable/api_definition'
         | 
| 5 | 
            +
              autoload :EndpointDefinition, 'swaggable/endpoint_definition'
         | 
| 6 | 
            +
              autoload :ParameterDefinition, 'swaggable/parameter_definition'
         | 
| 7 | 
            +
              autoload :TagDefinition, 'swaggable/tag_definition'
         | 
| 8 | 
            +
              autoload :ResponseDefinition, 'swaggable/response_definition'
         | 
| 9 | 
            +
              autoload :RackApp, 'swaggable/rack_app'
         | 
| 10 | 
            +
              autoload :GrapeAdapter, 'swaggable/grape_adapter'
         | 
| 11 | 
            +
              autoload :Swagger2Serializer, 'swaggable/swagger_2_serializer'
         | 
| 12 | 
            +
              autoload :Swagger2Validator, 'swaggable/swagger_2_validator'
         | 
| 13 | 
            +
              autoload :EndpointIndex, 'swaggable/endpoint_index'
         | 
| 14 | 
            +
            end
         | 
| @@ -0,0 +1,52 @@ | |
| 1 | 
            +
            require 'forwarding_dsl'
         | 
| 2 | 
            +
            require 'mini_object'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module Swaggable
         | 
| 5 | 
            +
              class ApiDefinition
         | 
| 6 | 
            +
                include ForwardingDsl::Getsetter
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                getsetter(
         | 
| 9 | 
            +
                  :version,
         | 
| 10 | 
            +
                  :title,
         | 
| 11 | 
            +
                  :description,
         | 
| 12 | 
            +
                  :base_path,
         | 
| 13 | 
            +
                )
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def initialize &block
         | 
| 16 | 
            +
                  configure(&block) if block_given?
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def endpoints &block
         | 
| 20 | 
            +
                  ForwardingDsl.run(
         | 
| 21 | 
            +
                    @endpoints ||= build_endpoints, 
         | 
| 22 | 
            +
                    &block
         | 
| 23 | 
            +
                  )
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def tags
         | 
| 27 | 
            +
                  (endpoints.map(&:tags).reduce(:merge) || []).dup.freeze
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def self.from_grape_api grape
         | 
| 31 | 
            +
                  grape_adapter.import(grape, new)
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def self.grape_adapter
         | 
| 35 | 
            +
                  @grape_adapter ||= Swaggable::GrapeAdapter.new
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                def configure &block
         | 
| 39 | 
            +
                  ForwardingDsl.run(self, &block)
         | 
| 40 | 
            +
                  self
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                private
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                def build_endpoints
         | 
| 46 | 
            +
                  MiniObject::IndexedList.new.tap do |l|
         | 
| 47 | 
            +
                    l.build { EndpointDefinition.new }
         | 
| 48 | 
            +
                    l.key {|e| "#{e.verb.to_s.upcase} #{e.path}" }
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
            end
         | 
| @@ -0,0 +1,54 @@ | |
| 1 | 
            +
            require 'forwarding_dsl'
         | 
| 2 | 
            +
            require 'mini_object'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module Swaggable
         | 
| 5 | 
            +
              class EndpointDefinition
         | 
| 6 | 
            +
                include ForwardingDsl::Getsetter
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                getsetter(
         | 
| 9 | 
            +
                  :path,
         | 
| 10 | 
            +
                  :verb,
         | 
| 11 | 
            +
                  :description,
         | 
| 12 | 
            +
                  :summary,
         | 
| 13 | 
            +
                )
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def initialize args = {}, &block
         | 
| 16 | 
            +
                  args.each {|k, v| self.send("#{k}=", v) }
         | 
| 17 | 
            +
                  configure(&block) if block_given?
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def tags
         | 
| 21 | 
            +
                  @tags ||= MiniObject::IndexedList.new.tap do |l|
         | 
| 22 | 
            +
                    l.build { TagDefinition.new }
         | 
| 23 | 
            +
                    l.key {|e| e.name }
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def parameters
         | 
| 28 | 
            +
                  @parameters ||= MiniObject::IndexedList.new.tap do |l|
         | 
| 29 | 
            +
                    l.build { ParameterDefinition.new }
         | 
| 30 | 
            +
                    l.key {|e| e.name }
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def responses
         | 
| 35 | 
            +
                  @responses ||= MiniObject::IndexedList.new.tap do |l|
         | 
| 36 | 
            +
                    l.build { ResponseDefinition.new }
         | 
| 37 | 
            +
                    l.key {|e| e.status }
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                def consumes
         | 
| 42 | 
            +
                  @consumes ||= []
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                def produces
         | 
| 46 | 
            +
                  @produces ||= []
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                def configure &block
         | 
| 50 | 
            +
                  ForwardingDsl.run(self, &block)
         | 
| 51 | 
            +
                  self
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
            end
         | 
| @@ -0,0 +1,84 @@ | |
| 1 | 
            +
            module Swaggable
         | 
| 2 | 
            +
              class GrapeAdapter
         | 
| 3 | 
            +
                def import grape, api
         | 
| 4 | 
            +
                  api.version = grape.version
         | 
| 5 | 
            +
                  api.title = grape.name
         | 
| 6 | 
            +
                  api.base_path = '/'
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  grape.routes.each do |grape_endpoint|
         | 
| 9 | 
            +
                    api.endpoints.add_new do |api_endpoint|
         | 
| 10 | 
            +
                      import_endpoint grape_endpoint, api_endpoint, grape
         | 
| 11 | 
            +
                    end
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  api
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                private
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def extract_path grape_endpoint, grape
         | 
| 20 | 
            +
                  path = grape_endpoint.route_path
         | 
| 21 | 
            +
                  path = remove_format_from_path(path)
         | 
| 22 | 
            +
                  path = substitute_version_in_path(path, grape)
         | 
| 23 | 
            +
                  substitute_parameters_in_path(path, grape_endpoint)
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def remove_format_from_path path
         | 
| 27 | 
            +
                  path.gsub(/\(\/{0,1}\.:format\)$/,'')
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def substitute_version_in_path path, grape
         | 
| 31 | 
            +
                  prefix = "/#{grape.prefix.to_s}".gsub(/^\/\//,'/')
         | 
| 32 | 
            +
                  prefix = '' if prefix == '/'
         | 
| 33 | 
            +
                  path.gsub(/^#{Regexp.escape prefix}\/:version/,"#{prefix}/#{grape.version}")
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def substitute_parameters_in_path path, grape_endpoint
         | 
| 37 | 
            +
                  path = path.dup
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  grape_endpoint.route_compiled.names.each do |name|
         | 
| 40 | 
            +
                    path.gsub!(/:#{name}/, "{#{name}}")
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  path
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                def parameter_from name, options, grape_endpoint
         | 
| 47 | 
            +
                  Swaggable::ParameterDefinition.new do |p|
         | 
| 48 | 
            +
                    options = {} if options == ''
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                    p.name = name
         | 
| 51 | 
            +
                    p.type = options[:type].downcase.to_sym if options[:type]
         | 
| 52 | 
            +
                    p.required = options[:required]
         | 
| 53 | 
            +
                    p.description = options[:desc]
         | 
| 54 | 
            +
                    p.location = if grape_endpoint.route_compiled.names.include? name
         | 
| 55 | 
            +
                                   :path 
         | 
| 56 | 
            +
                                 else
         | 
| 57 | 
            +
                                   :query
         | 
| 58 | 
            +
                                 end
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                def import_endpoint grape_endpoint, api_endpoint, grape
         | 
| 63 | 
            +
                  api_endpoint.verb = grape_endpoint.route_method.downcase
         | 
| 64 | 
            +
                  api_endpoint.summary = grape_endpoint.route_description
         | 
| 65 | 
            +
                  api_endpoint.produces << "application/#{grape.format}" if grape.format
         | 
| 66 | 
            +
                  api_endpoint.path = extract_path(grape_endpoint, grape)
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                  api_endpoint.tags.add_new do |t|
         | 
| 69 | 
            +
                    t.name = grape.name
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  grape_endpoint.route_params.each do |name, options|
         | 
| 73 | 
            +
                    api_endpoint.parameters << parameter_from(name, options, grape_endpoint)
         | 
| 74 | 
            +
                  end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                  (grape_endpoint.route_http_codes || []).each do |status, desc, entity|
         | 
| 77 | 
            +
                    api_endpoint.responses.add_new do |r|
         | 
| 78 | 
            +
                      r.status = status
         | 
| 79 | 
            +
                      r.description = desc
         | 
| 80 | 
            +
                    end
         | 
| 81 | 
            +
                  end
         | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
              end
         | 
| 84 | 
            +
            end
         | 
| @@ -0,0 +1,50 @@ | |
| 1 | 
            +
            require 'mini_object'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Swaggable
         | 
| 4 | 
            +
              class ParameterDefinition
         | 
| 5 | 
            +
                include ForwardingDsl::Getsetter
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                getsetter(
         | 
| 8 | 
            +
                  :name,
         | 
| 9 | 
            +
                  :description,
         | 
| 10 | 
            +
                  :location,
         | 
| 11 | 
            +
                  :required,
         | 
| 12 | 
            +
                  :type,
         | 
| 13 | 
            +
                )
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def initialize args = {}
         | 
| 16 | 
            +
                  args.each {|k, v| self.send("#{k}=", v) }
         | 
| 17 | 
            +
                  yield self if block_given?
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def required?
         | 
| 21 | 
            +
                  !!required
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def location= location
         | 
| 25 | 
            +
                  unless valid_locations.include? location
         | 
| 26 | 
            +
                    raise ArgumentError.new("#{location} is not one of the valid locations: #{valid_locations.join(", ")}")
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  @location = location
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                def type= type
         | 
| 33 | 
            +
                  unless valid_types.include? type
         | 
| 34 | 
            +
                    raise ArgumentError.new("#{type} is not one of the valid types: #{valid_types.join(", ")}")
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  @type = type
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                private
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def valid_locations
         | 
| 43 | 
            +
                  [:path, :query, :header, :body, :form, nil]
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                def valid_types
         | 
| 47 | 
            +
                  [:string, :number, :integer, :boolean, :array, :file, nil]
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
            end
         | 
| @@ -0,0 +1,30 @@ | |
| 1 | 
            +
            require 'json'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module  Swaggable
         | 
| 4 | 
            +
              class RackApp
         | 
| 5 | 
            +
                attr_accessor(
         | 
| 6 | 
            +
                  :api_definition,
         | 
| 7 | 
            +
                  :serializer,
         | 
| 8 | 
            +
                )
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def initialize args = {}
         | 
| 11 | 
            +
                  args.each {|k,v| send "#{k}=", v }
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def call env
         | 
| 15 | 
            +
                  [
         | 
| 16 | 
            +
                    200,
         | 
| 17 | 
            +
                    {'Content-Type' => 'application/json'},
         | 
| 18 | 
            +
                    [serializer.serialize(api_definition).to_json]
         | 
| 19 | 
            +
                  ]
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                def serializer
         | 
| 23 | 
            +
                  @serializer ||= Swagger2Serializer.new
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def validate!
         | 
| 27 | 
            +
                  serializer.validate! api_definition
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
            end
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            require 'forwarding_dsl'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Swaggable
         | 
| 4 | 
            +
              class ResponseDefinition
         | 
| 5 | 
            +
                include ForwardingDsl::Getsetter
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                getsetter :status
         | 
| 8 | 
            +
                getsetter :description
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def initialize args = {}
         | 
| 11 | 
            +
                  args.each {|k, v| self.send("#{k}=", v) }
         | 
| 12 | 
            +
                  yield self if block_given?
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
            end
         | 
| 16 | 
            +
             | 
| @@ -0,0 +1,92 @@ | |
| 1 | 
            +
            module Swaggable
         | 
| 2 | 
            +
              # Generates a Swagger 2 hash from an {ApiDefinition}.
         | 
| 3 | 
            +
              #
         | 
| 4 | 
            +
              # @example Basic usage
         | 
| 5 | 
            +
              #   serializer = Swagger2Serializer.new
         | 
| 6 | 
            +
              #   api_definition = ApiDefinition.new
         | 
| 7 | 
            +
              #   serializer.serialize(api_definition)
         | 
| 8 | 
            +
              #   # => {:swagger=>"2.0", :basePath=>nil, :info=>{:title=>nil, :description=>nil, :version=>nil}, :tags=>[], :paths=>{}}
         | 
| 9 | 
            +
              #
         | 
| 10 | 
            +
              class Swagger2Serializer
         | 
| 11 | 
            +
                attr_accessor :tag_serializer
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                # Main method that given an {ApiDefinition} will return a hash to serialize
         | 
| 14 | 
            +
                def serialize api
         | 
| 15 | 
            +
                  {
         | 
| 16 | 
            +
                    swagger: '2.0',
         | 
| 17 | 
            +
                    basePath: api.base_path,
         | 
| 18 | 
            +
                    info: serialize_info(api),
         | 
| 19 | 
            +
                    tags: api.tags.map{|t| serialize_tag t },
         | 
| 20 | 
            +
                    paths: serialize_endpoints(api.endpoints),
         | 
| 21 | 
            +
                  }
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def serialize_info api
         | 
| 25 | 
            +
                  {
         | 
| 26 | 
            +
                    title: api.title.to_s,
         | 
| 27 | 
            +
                    version: (api.version || '0.0.0'),
         | 
| 28 | 
            +
                  }.
         | 
| 29 | 
            +
                  tap do |h|
         | 
| 30 | 
            +
                    h[:description] = api.description if api.description
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def serialize_tag tag
         | 
| 35 | 
            +
                  {
         | 
| 36 | 
            +
                    name: tag.name,
         | 
| 37 | 
            +
                  }.
         | 
| 38 | 
            +
                  tap do |e|
         | 
| 39 | 
            +
                    e[:description] = tag.description if tag.description
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                def serialize_endpoints endpoints
         | 
| 44 | 
            +
                  endpoints.inject({}) do |out, endpoint|
         | 
| 45 | 
            +
                    out[endpoint.path] ||= {}
         | 
| 46 | 
            +
                    out[endpoint.path][endpoint.verb] = serialize_endpoint(endpoint)
         | 
| 47 | 
            +
                    out
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                def serialize_endpoint endpoint
         | 
| 52 | 
            +
                  {
         | 
| 53 | 
            +
                    tags: endpoint.tags.map(&:name),
         | 
| 54 | 
            +
                    consumes: endpoint.consumes,
         | 
| 55 | 
            +
                    produces: endpoint.produces,
         | 
| 56 | 
            +
                    parameters: endpoint.parameters.map{|p| serialize_parameter p },
         | 
| 57 | 
            +
                    responses: serialize_responses(endpoint.responses),
         | 
| 58 | 
            +
                  }.
         | 
| 59 | 
            +
                  tap do |e|
         | 
| 60 | 
            +
                    e[:summary] = endpoint.summary if endpoint.summary
         | 
| 61 | 
            +
                    e[:description] = endpoint.description if endpoint.description
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                def serialize_parameter parameter
         | 
| 66 | 
            +
                  p = {
         | 
| 67 | 
            +
                    in: parameter.location.to_s,
         | 
| 68 | 
            +
                    name: parameter.name,
         | 
| 69 | 
            +
                    required: parameter.required?,
         | 
| 70 | 
            +
                  }
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  p[:type] = parameter.type || 'string'
         | 
| 73 | 
            +
                  p[:description] = parameter.description if parameter.description
         | 
| 74 | 
            +
                  p
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                def serialize_responses responses
         | 
| 78 | 
            +
                  if responses.any?
         | 
| 79 | 
            +
                    responses.inject({}) do |acc, r|
         | 
| 80 | 
            +
                      acc[r.status] = {description: r.description}
         | 
| 81 | 
            +
                      acc
         | 
| 82 | 
            +
                    end
         | 
| 83 | 
            +
                  else
         | 
| 84 | 
            +
                    {200 => {description: 'Success'}}
         | 
| 85 | 
            +
                  end
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                def validate! api
         | 
| 89 | 
            +
                  Swagger2Validator.validate! serialize(api)
         | 
| 90 | 
            +
                end
         | 
| 91 | 
            +
              end
         | 
| 92 | 
            +
            end
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            require 'json-schema'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Swaggable
         | 
| 4 | 
            +
              class Swagger2Validator
         | 
| 5 | 
            +
                def self.validate! swagger
         | 
| 6 | 
            +
                  preload_draft4
         | 
| 7 | 
            +
                  JSON::Validator.validate!(schema, swagger)
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                private
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def self.schema
         | 
| 13 | 
            +
                  @schema = assets_dir + '/swagger-2.0-schema.json'
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def self.draft4
         | 
| 17 | 
            +
                  @draft4 = assets_dir + '/json-schema-draft-04.json'
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def self.assets_dir
         | 
| 21 | 
            +
                  File.dirname(__FILE__) + '/../../assets'
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def self.preload_draft4
         | 
| 25 | 
            +
                  @draft4_preloaded ||= JSON::Validator.validate!(draft4, {})
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
            end
         | 
| @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            require 'forwarding_dsl'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Swaggable
         | 
| 4 | 
            +
              class TagDefinition
         | 
| 5 | 
            +
                include ForwardingDsl::Getsetter
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                getsetter(
         | 
| 8 | 
            +
                  :name,
         | 
| 9 | 
            +
                  :description,
         | 
| 10 | 
            +
                )
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def initialize args = {}
         | 
| 13 | 
            +
                  args.each {|k, v| self.send("#{k}=", v) }
         | 
| 14 | 
            +
                  yield self if block_given?
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def == other
         | 
| 18 | 
            +
                  self.name == other.name if other.respond_to?(:name)
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
                alias eql? ==
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                def hash
         | 
| 23 | 
            +
                  name.hash
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
| 27 | 
            +
             |