lib/rspec/rails/api/open_api_renderer.rb in rspec-rails-api-0.4.0 vs lib/rspec/rails/api/open_api_renderer.rb in rspec-rails-api-0.5.0

- old
+ new

@@ -4,11 +4,11 @@ require 'active_support' module RSpec module Rails module Api - # Class to render metadatas. + # Class to render metadata. # Example: # ```rb # renderer = RSpec::Rails::Api::OpenApiRenderer.new # renderer.merge_context(example_context) # renderer.write_files @@ -33,29 +33,30 @@ # @param context [Hash] Metadata hash # @param dump_metadata [Boolean] Saves the raw metadata in `tmp/rra_metadata.yaml` for debugging # # @return [void def merge_context(context, dump_metadata: false) - @metadata[:resources].deep_merge! context[:resources] - @metadata[:entities].deep_merge! context[:entities] + @metadata[:resources].deep_merge! context.respond_to?(:resources) ? context.resources : context[:resources] + @metadata[:entities].deep_merge! context.respond_to?(:entities) ? context.entities : context[:entities] # Save context for debug and fixtures - File.write ::Rails.root.join('tmp', 'rra_metadata.yaml'), context.to_yaml if dump_metadata + File.write ::Rails.root.join('tmp', 'rra_metadata.yaml'), @metadata.to_yaml if dump_metadata end ## # Write OpenAPI files # # @param path [String, nil] Where to save the files. Defaults to `/tmp/rspec_api_rails.*` when unset # @param only [[Symbol]] Formats to save the file to. Allowed values are `:yaml` and `:json` # # @return [void] def write_files(path = nil, only: %i[yaml json]) + return unless write_file? RSpec.world.filtered_examples + path ||= ::Rails.root.join('tmp', 'rspec_api_rails') file_types = %i[yaml json] - only.each do |type| next unless file_types.include? type File.write "#{path}.#{type}", prepare_metadata.send("to_#{type}") end @@ -64,11 +65,11 @@ ## # Extracts metadata from context to generate an OpenAPI structure # # @return [Hash] The OpenAPI structure def prepare_metadata - extract_metadatas + extract_metadata # Example: https://github.com/OAI/OpenAPI-Specification/blob/master/examples/v3.0/petstore-expanded.yaml hash = { openapi: '3.0.0', info: @api_infos, servers: @api_servers, @@ -105,15 +106,27 @@ @api_license[:url] = url if url end private + def write_file?(examples) + acceptance_examples = examples.values.flatten.filter do |e| + e.metadata[:type] == :acceptance + end + unless acceptance_examples.none?(&:exception) + puts "\n\e[00;31mSome acceptance tests failed. OpenApi specification file was not updated.\n\e[00m" + return false + end + + true + end + ## # Extracts metadata for rendering # # @return [void] - def extract_metadatas + def extract_metadata extract_from_resources api_infos api_servers end @@ -188,14 +201,12 @@ type: PARAM_TYPES[field.type][:type], } property[:format] = PARAM_TYPES[field.type][:format] if PARAM_TYPES[field.type][:format] schema[:properties][name] = property # Primitives support - if PRIMITIVES.include? field.attributes - property[:items] = - { type: field.attributes.to_s.split('_').last.to_sym } - end + property[:items] = { type: field.attributes } if PRIMITIVES.include? field.attributes + required.push name unless field.required == false end schema[:required] = required unless required.size.zero? @@ -280,11 +291,11 @@ # @param ref [String] Reference # @param examples [Hash] Example # # @return [void] def process_request_body(schema: nil, ref: nil, examples: {}) - Utils.deep_set @api_components, "schemas.#{ref}", schema + Utils.deep_set @api_components, ['schemas', ref], schema { # description: '', required: true, content: { 'application/json' => { @@ -319,10 +330,10 @@ end def response_schema(expectations) if expectations[:many] items = if PRIMITIVES.include?(expectations[:many]) - { type: expectations[:many].to_s.split('_').last } + { type: expectations[:many] } else { '$ref' => "#/components/schemas/#{expectations[:many]}" } end { type: 'array', items: items } elsif expectations[:one]