Skip to content

Commit

Permalink
increases code coverage (#570)
Browse files Browse the repository at this point in the history
- removbes dead code
- adds changelog entry
- corrects coveralls bagde
  • Loading branch information
peter scholz authored and LeFnord committed Jan 15, 2017
1 parent 0ffec4d commit ab12328
Show file tree
Hide file tree
Showing 17 changed files with 308 additions and 98 deletions.
1 change: 0 additions & 1 deletion .rspec
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
--format documentation
--color
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ after_success:
- coveralls

matrix:
fast_finish: true
include:
- rvm: 2.4.0
script:
Expand All @@ -34,11 +35,9 @@ matrix:
- rvm: 2.3.3
- rvm: 2.2.6
- rvm: ruby-head
- rvm: jruby-9.1.6.0
- rvm: jruby-head
- rvm: rbx-2
allow_failures:
- rvm: ruby-head
- rvm: jruby-9.1.6.0
- rvm: jruby-head
- rvm: rbx-2
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

* [#567](https://github.com/ruby-grape/grape-swagger/pull/567): Issue#566: removes markdown - [@LeFnord](https://github.com/LeFnord).
* [#568](https://github.com/ruby-grape/grape-swagger/pull/568): Adds code coverage w/ coveralls - [@LeFnord](https://github.com/LeFnord).
* [#570](https://github.com/ruby-grape/grape-swagger/pull/570): Removes dead code -> increases code coverage - [@LeFnord](https://github.com/LeFnord).

* Your contribution here.

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[![Gem Version](https://badge.fury.io/rb/grape-swagger.svg)](http://badge.fury.io/rb/grape-swagger)
[![Build Status](https://travis-ci.org/ruby-grape/grape-swagger.svg?branch=master)](https://travis-ci.org/ruby-grape/grape-swagger)
[![Coverage Status](https://coveralls.io/repos/github/ruby-grape/grape-swagger/badge.svg)](https://coveralls.io/github/ruby-grape/grape-swagger)
[![Coverage Status](https://coveralls.io/repos/github/ruby-grape/grape-swagger/badge.svg?branch=master)](https://coveralls.io/github/ruby-grape/grape-swagger?branch=master)
[![Dependency Status](https://gemnasium.com/ruby-grape/grape-swagger.svg)](https://gemnasium.com/ruby-grape/grape-swagger)
[![Code Climate](https://codeclimate.com/github/ruby-grape/grape-swagger.svg)](https://codeclimate.com/github/ruby-grape/grape-swagger)

Expand Down
88 changes: 20 additions & 68 deletions lib/grape-swagger.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,8 @@ def combine_routes(app, doc_klass)

def combine_namespaces(app)
app.endpoints.each do |endpoint|
ns = if endpoint.respond_to?(:namespace_stackable)
endpoint.namespace_stackable(:namespace).last
else
endpoint.settings.stack.last[:namespace]
end
ns = endpoint.namespace_stackable(:namespace).last

# use the full namespace here (not the latest level only)
# and strip leading slash
mount_path = (endpoint.namespace_stackable(:mount_path) || []).join('/')
Expand All @@ -93,7 +90,7 @@ def combine_namespaces(app)

def combine_namespace_routes(namespaces)
# iterate over each single namespace
namespaces.each do |name, namespace|
namespaces.each do |name, _|
# get the parent route for the namespace
parent_route_name = extract_parent_route(name)
parent_route = @target_class.combined_routes[parent_route_name]
Expand All @@ -102,55 +99,28 @@ def combine_namespace_routes(namespaces)
!route_path_start_with?(route, name) || !route_instance_variable_equals?(route, name)
end

if namespace.options.key?(:swagger) && namespace.options[:swagger][:nested] == false
# Namespace shall appear as standalone resource, use specified name or use normalized path as name
identifier = if namespace.options[:swagger].key?(:name)
name.tr(' ', '-')
else
name.tr('_', '-').gsub(/\//, '_')
end
@target_class.combined_namespace_identifiers[identifier] = name
@target_class.combined_namespace_routes[identifier] = namespace_routes

# # get all nested namespaces below the current namespace
sub_namespaces = standalone_sub_namespaces(name, namespaces)
sub_routes = sub_routes_from(parent_route, sub_namespaces)
@target_class.combined_namespace_routes[identifier].push(*sub_routes)
else
# default case when not explicitly specified or nested == true
standalone_namespaces = namespaces.reject do |_, ns|
!ns.options.key?(:swagger) ||
!ns.options[:swagger].key?(:nested) ||
ns.options[:swagger][:nested] != false
end

parent_standalone_namespaces = standalone_namespaces.reject { |ns_name, _| !name.start_with?(ns_name) }
# add only to the main route
# if the namespace is not within any other namespace appearing as standalone resource
if parent_standalone_namespaces.empty?
# default option, append namespace methods to parent route
parent_route = @target_class.combined_namespace_routes.key?(parent_route_name)
@target_class.combined_namespace_routes[parent_route_name] = [] unless parent_route
@target_class.combined_namespace_routes[parent_route_name].push(*namespace_routes)
end
# default case when not explicitly specified or nested == true
standalone_namespaces = namespaces.reject do |_, ns|
!ns.options.key?(:swagger) ||
!ns.options[:swagger].key?(:nested) ||
ns.options[:swagger][:nested] != false
end

parent_standalone_namespaces = standalone_namespaces.reject { |ns_name, _| !name.start_with?(ns_name) }
# add only to the main route
# if the namespace is not within any other namespace appearing as standalone resource
# rubocop:disable Style/Next
if parent_standalone_namespaces.empty?
# default option, append namespace methods to parent route
parent_route = @target_class.combined_namespace_routes.key?(parent_route_name)
@target_class.combined_namespace_routes[parent_route_name] = [] unless parent_route
@target_class.combined_namespace_routes[parent_route_name].push(*namespace_routes)
end
end
end

def extract_parent_route(name)
route_name = name.match(%r{^/?([^/]*).*$})[1]
return route_name unless route_name.include? ':'
name.match(/\/[a-z]+/)[0].delete('/')
end

def sub_routes_from(parent_route, sub_namespaces)
sub_ns_paths = sub_namespaces.collect { |ns_name, _| ["/#{ns_name}", "/:version/#{ns_name}"] }
sub_routes = parent_route.reject do |route|
parent_namespace = route_instance_variable(route)
!sub_ns_paths.assoc(parent_namespace) && !sub_ns_paths.rassoc(parent_namespace)
end

sub_routes
name.match(%r{^/?([^/]*).*$})[1]
end

def route_instance_variable(route)
Expand All @@ -169,24 +139,6 @@ def route_path_start_with?(route, name)
route.path.start_with?(route_prefix, route_versioned_prefix)
end

def standalone_sub_namespaces(name, namespaces)
# assign all nested namespace routes to this resource, too
# (unless they are assigned to another standalone namespace themselves)
sub_namespaces = {}
# fetch all namespaces that are children of the current namespace
namespaces.each { |ns_name, ns| sub_namespaces[ns_name] = ns if ns_name.start_with?(name) && ns_name != name }
# remove the sub namespaces if they are assigned to another standalone namespace themselves
sub_namespaces.each do |sub_name, sub_ns|
# skip if sub_ns is standalone, too
next unless sub_ns.options.key?(:swagger) && sub_ns.options[:swagger][:nested] == false
# remove all namespaces that are nested below this standalone sub_ns
sub_namespaces.each do |sub_sub_name, _|
sub_namespaces.delete(sub_sub_name) if sub_sub_name.start_with?(sub_name)
end
end
sub_namespaces
end

def create_documentation_class
Class.new(Grape::API) do
extend GrapeSwagger::DocMethods
Expand Down
4 changes: 0 additions & 4 deletions lib/grape-swagger/doc_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@

module GrapeSwagger
module DocMethods
def name
@@class_name
end

def hide_documentation_path
@@hide_documentation_path
end
Expand Down
9 changes: 2 additions & 7 deletions lib/grape-swagger/doc_methods/parse_params.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,10 @@ def param_type(value_type)

def parse_enum_or_range_values(values)
case values
when Proc
parse_enum_or_range_values(values.call)
when Range
parse_range_values(values) if values.first.is_a?(Integer)
when Proc
values_result = values.call
if values_result.is_a?(Range) && values_result.first.is_a?(Integer)
parse_range_values(values_result)
else
{ enum: values_result }
end
else
{ enum: values } if values
end
Expand Down
23 changes: 18 additions & 5 deletions lib/grape-swagger/doc_methods/tag_name_description.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,27 @@ class TagNameDescription
class << self
def build(paths)
paths.values.each_with_object([]) do |path, memo|
path.values.first[:tags].each do |tag|
memo << {
name: tag,
description: "Operations about #{tag.pluralize}"
}
tags = path.values.first[:tags]

case tags
when String
memo << build_memo(tags)
when Array
path.values.first[:tags].each do |tag|
memo << build_memo(tag)
end
end
end.uniq
end

private

def build_memo(tag)
{
name: tag,
description: "Operations about #{tag.pluralize}"
}
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/grape-swagger/endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def content_types_for(target_class)

if content_types.empty?
formats = [target_class.format, target_class.default_format].compact.uniq
formats = Grape::Formatter::Base.formatters({}).keys if formats.empty?
formats = Grape::Formatter.formatters({}).keys if formats.empty?
content_types = Grape::ContentTypes::CONTENT_TYPES.select do |content_type, _mime_type|
formats.include? content_type
end.values
Expand Down
6 changes: 5 additions & 1 deletion lib/grape-swagger/rake/oapi_tasks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ def fetch
store – save as JSON file, default: false (optional)
resource - if given only for that it would be generated (optional)'
task fetch: :environment do
# :nocov:
make_request

save_to_file? ? File.write(file, @oapi) : $stdout.print(@oapi)
# :nocov:
end
end

Expand All @@ -47,6 +49,7 @@ def validate
params (usage: key=value):
resource - if given only for that it would be generated (optional)'
task validate: :environment do
# :nocov:
ENV['store'] = 'true'
::Rake::Task['oapi:fetch'].invoke
exit if error?
Expand All @@ -55,14 +58,15 @@ def validate

$stdout.puts 'install swagger-cli with `npm install swagger-cli -g`' if output.nil?
FileUtils.rm(file)
# :nocov:
end
end

# helper methods
#
def make_request
get url_for
last_response

@oapi = JSON.pretty_generate(
JSON.parse(
last_response.body, symolize_names: true
Expand Down
43 changes: 42 additions & 1 deletion spec/lib/endpoint_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
require 'spec_helper'

describe Grape::Endpoint do
subject { described_class.new(Grape::Util::InheritableSetting.new, path: '/', method: :get) }
subject do
described_class.new(Grape::Util::InheritableSetting.new, path: '/', method: :get)
end

describe '#param_type_is_array?' do
it 'returns true if the value passed represents an array' do
Expand All @@ -15,4 +17,43 @@
expect(subject.send(:param_type_is_array?, '[String, Integer]')).to be_falsey
end
end

describe '.content_types_for' do
describe 'defined on target_class' do
let(:own_json) { 'text/own-json' }
let(:own_xml) { 'text/own-xml' }
let(:content_types) do
{
own_json: own_json,
own_xml: own_xml
}
end
let(:target_class) { OpenStruct.new(content_types: content_types) }

let(:object) { subject.content_types_for(target_class) }
specify do
expect(object).to eql [own_json, own_xml]
end
end

describe 'not defined' do
describe 'format given' do
let(:format) { :json }
let(:target_class) { OpenStruct.new(format: format) }
let(:object) { subject.content_types_for(target_class) }
specify do
expect(object).to eql ['application/json']
end

describe 'format not given' do
let(:target_class) { OpenStruct.new }
let(:object) { subject.content_types_for(target_class) }

specify do
expect(object).to eql %w(application/xml application/json text/plain)
end
end
end
end
end
end
42 changes: 42 additions & 0 deletions spec/lib/extensions_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,48 @@
require 'spec_helper'

describe GrapeSwagger::DocMethods::Extensions do
describe '#find_definition' do
subject { described_class }

let(:method) { :get }
let(:status) { 200 }

before { allow(subject).to receive(:method).and_return(method) }

describe 'no response for status' do
let(:path) { { get: { responses: {} } } }

specify do
definition = subject.find_definition(status, path)
expect(definition).to be_nil
end
end

describe 'response found' do
let(:model) { 'Item' }

describe 'ref given' do
let(:path) do
{ get: { responses: { 200 => { schema: { '$ref' => "#/definitions/#{model}" } } } } }
end
specify do
definition = subject.find_definition(status, path)
expect(definition).to eql model
end
end

describe 'items given' do
let(:path) do
{ get: { responses: { 200 => { schema: { 'items' => { '$ref' => "#/definitions/#{model}" } } } } } }
end
specify do
definition = subject.find_definition(status, path)
expect(definition).to eql model
end
end
end
end

describe '#extended? and extension' do
subject { described_class }
describe 'return false (default)' do
Expand Down
Loading

0 comments on commit ab12328

Please sign in to comment.