diff --git a/lib/rspec_api_documentation/views/api_blueprint_index.rb b/lib/rspec_api_documentation/views/api_blueprint_index.rb index ef42c1fa..a5b157d3 100644 --- a/lib/rspec_api_documentation/views/api_blueprint_index.rb +++ b/lib/rspec_api_documentation/views/api_blueprint_index.rb @@ -67,6 +67,11 @@ def format_route(example) # properties_description: "required, string" # } def fields(property_name, examples) + possible_parameters_values = examples.map do |example| + parameters = example.metadata[:extended_parameters] || [] + next parameters.map { |parameter| [parameter[:name], parameter[:value]] }.to_h + end + examples .map { |example| example.metadata[property_name] } .flatten @@ -79,7 +84,19 @@ def fields(property_name, examples) else properties << 'optional' end - properties << property[:type] if property[:type] + + if property.key?(:type) + properties << property[:type] if property[:type] + else + possible_values = possible_parameters_values.map { |parameters| parameters[property[:name]] } + possible_types = possible_values.map { |value| guess_type(value) } + + possible_types.uniq! + possible_types.compact! + + properties.concat(possible_types) + end + if properties.count > 0 property[:properties_description] = properties.join(", ") else @@ -96,6 +113,21 @@ def fields(property_name, examples) end end + def guess_type(value) + case value + when TrueClass then :boolean + when FalseClass then :boolean + when Array then :array + when Integer then :integer + when Float then :number + when String then :string + when Rack::Test::UploadedFile then :file + when NilClass then nil + else + puts "Warning: unknown type of value #{value}" + end + end + # When no `description` was specified for a parameter, the DSL class # is making `description = "#{scope} #{name}"`, which is bad because it # assumes that all formats want this behavior. To avoid changing there diff --git a/spec/views/api_blueprint_index_spec.rb b/spec/views/api_blueprint_index_spec.rb index 1d526597..a1ce7c1e 100644 --- a/spec/views/api_blueprint_index_spec.rb +++ b/spec/views/api_blueprint_index_spec.rb @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- require 'spec_helper' +require 'rack/test' require 'rspec_api_documentation/dsl' describe RspecApiDocumentation::Views::ApiBlueprintIndex do @@ -164,4 +165,52 @@ end end end + + describe '#guess_type' do + let(:index) { RspecApiDocumentation::Index.new } + let(:order_route) { subject.sections[0][:routes][0] } + + resource "Order" do + route '/orders', 'Order' do + post "orders" do + parameter :desc, required: true + parameter :price, required: true + + let(:desc) { "A test order" } + let(:price) { 13 } + + let(:config) { RspecApiDocumentation::Configuration.new } + + before do + expect(client).to receive(:post) + do_request + + index.examples << RspecApiDocumentation::Example.new(client.example, config) + end + + it "should guess the parameter type" do + order_examples = order_route[:http_methods].map { |http_method| http_method[:examples] }.flatten + expect(order_examples.size).to eq 1 + expect(order_route[:route]).to eq "/orders" + expect(order_route[:route_name]).to eq "Order" + expect(order_route[:has_parameters?]).to eq true + expect(order_route[:parameters]).to eq [ + { + required: true, + name: "desc", + description: nil, + properties_description: "required, string" + }, + { + required: true, + name: "price", + description: nil, + properties_description: "required, integer" + } + ] + end + end + end + end + end end