|
| 1 | +require 'rspec/openapi/components_updater' |
| 2 | +require 'rspec/openapi/default_schema' |
| 3 | +require 'rspec/openapi/record_builder' |
| 4 | +require 'rspec/openapi/schema_builder' |
| 5 | +require 'rspec/openapi/schema_file' |
| 6 | +require 'rspec/openapi/schema_merger' |
| 7 | +require 'rspec/openapi/schema_cleaner' |
| 8 | + |
| 9 | +module RSpec |
| 10 | + module OpenAPI |
| 11 | + module Minitest |
| 12 | + class Example < Struct.new(:context, :description, :metadata) ; end |
| 13 | + |
| 14 | + module TestPatch |
| 15 | + def self.prepended(base) |
| 16 | + base.extend(ClassMethods) |
| 17 | + end |
| 18 | + |
| 19 | + def run(*args) |
| 20 | + result = super |
| 21 | + if ENV['OPENAPI'] && self.class.openapi? |
| 22 | + path = RSpec::OpenAPI.path.yield_self { |p| p.is_a?(Proc) ? p.call(example) : p } |
| 23 | + example = Example.new(self, name, {}) |
| 24 | + record = RSpec::OpenAPI::RecordBuilder.build(self, example: example) |
| 25 | + RSpec::OpenAPI.path_records[path] << record if record |
| 26 | + end |
| 27 | + result |
| 28 | + end |
| 29 | + |
| 30 | + def inspect |
| 31 | + self.class.to_s |
| 32 | + end |
| 33 | + |
| 34 | + module ClassMethods |
| 35 | + def openapi? |
| 36 | + @openapi |
| 37 | + end |
| 38 | + |
| 39 | + def openapi! |
| 40 | + @openapi = true |
| 41 | + end |
| 42 | + end |
| 43 | + end |
| 44 | + end |
| 45 | + end |
| 46 | +end |
| 47 | + |
| 48 | +Minitest::Test.prepend RSpec::OpenAPI::Minitest::TestPatch |
| 49 | + |
| 50 | +Minitest.after_run do |
| 51 | + if ENV['OPENAPI'] |
| 52 | + title = File.basename(Dir.pwd) |
| 53 | + RSpec::OpenAPI.path_records.each do |path, records| |
| 54 | + RSpec::OpenAPI::SchemaFile.new(path).edit do |spec| |
| 55 | + schema = RSpec::OpenAPI::DefaultSchema.build(title) |
| 56 | + schema[:info].merge!(RSpec::OpenAPI.info) |
| 57 | + RSpec::OpenAPI::SchemaMerger.merge!(spec, schema) |
| 58 | + new_from_zero = {} |
| 59 | + records.each do |record| |
| 60 | + begin |
| 61 | + record_schema = RSpec::OpenAPI::SchemaBuilder.build(record) |
| 62 | + RSpec::OpenAPI::SchemaMerger.merge!(spec, record_schema) |
| 63 | + RSpec::OpenAPI::SchemaMerger.merge!(new_from_zero, record_schema) |
| 64 | + rescue StandardError, NotImplementedError => e # e.g. SchemaBuilder raises a NotImplementedError |
| 65 | + RSpec::OpenAPI.error_records[e] = record # Avoid failing the build |
| 66 | + end |
| 67 | + end |
| 68 | + RSpec::OpenAPI::SchemaCleaner.cleanup!(spec, new_from_zero) |
| 69 | + RSpec::OpenAPI::ComponentsUpdater.update!(spec, new_from_zero) |
| 70 | + end |
| 71 | + end |
| 72 | + if RSpec::OpenAPI.error_records.any? |
| 73 | + error_message = <<~EOS |
| 74 | + RSpec::OpenAPI got errors building #{RSpec::OpenAPI.error_records.size} requests |
| 75 | +
|
| 76 | + #{RSpec::OpenAPI.error_records.map {|e, record| "#{e.inspect}: #{record.inspect}" }.join("\n")} |
| 77 | + EOS |
| 78 | + puts error_message |
| 79 | + end |
| 80 | + end |
| 81 | +end |
0 commit comments