Skip to content

Commit

Permalink
Sort HTTP methods, response status codes, and contents lexicographica…
Browse files Browse the repository at this point in the history
…lly (#163)
  • Loading branch information
exoego committed Dec 14, 2023
1 parent 1d3dccc commit 4d021af
Show file tree
Hide file tree
Showing 6 changed files with 330 additions and 303 deletions.
1 change: 1 addition & 0 deletions lib/rspec/openapi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
require 'rspec/openapi/schema_file'
require 'rspec/openapi/schema_merger'
require 'rspec/openapi/schema_cleaner'
require 'rspec/openapi/schema_sorter'

require 'rspec/openapi/minitest_hooks' if Object.const_defined?('Minitest')
require 'rspec/openapi/rspec_hooks' if ENV['OPENAPI'] && Object.const_defined?('RSpec')
Expand Down
2 changes: 1 addition & 1 deletion lib/rspec/openapi/result_recorder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def record_results!
RSpec::OpenAPI::SchemaCleaner.cleanup!(spec, new_from_zero)
RSpec::OpenAPI::ComponentsUpdater.update!(spec, new_from_zero)
RSpec::OpenAPI::SchemaCleaner.cleanup_empty_required_array!(spec)
RSpec::OpenAPI::SchemaCleaner.sort_paths!(spec)
RSpec::OpenAPI::SchemaSorter.deep_sort!(spec)
end
end
end
Expand Down
7 changes: 0 additions & 7 deletions lib/rspec/openapi/schema_cleaner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,6 @@ def cleanup_empty_required_array!(base)
end
end

# Sort "paths" lexicographically to make the order more predictable
#
# @param [Hash] #
def sort_paths!(spec)
spec['paths'] = spec['paths']&.entries&.sort_by! { |path, _| path }.to_h
end

private

def cleanup_array!(base, spec, selector, fields_for_identity = [])
Expand Down
35 changes: 35 additions & 0 deletions lib/rspec/openapi/schema_sorter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# frozen_string_literal: true

class << RSpec::OpenAPI::SchemaSorter = Object.new
# Sort some unpredictably ordered properties in a lexicographical manner to make the order more predictable.
#
# @param [Hash|Array]
def deep_sort!(spec)
# paths
deep_sort_by_selector!(spec, 'paths')

# methods
deep_sort_by_selector!(spec, 'paths.*')

# response status code
deep_sort_by_selector!(spec, 'paths.*.*.responses')

# content-type
deep_sort_by_selector!(spec, 'paths.*.*.responses.*.content')
end

private

# @param [Hash] base
# @param [String] selector
def deep_sort_by_selector!(base, selector)
RSpec::OpenAPI::HashHelper.matched_paths(base, selector).each do |paths|
deep_sort_hash!(base.dig(*paths))
end
end

def deep_sort_hash!(hash)
sorted = hash.entries.sort_by { |k, _| k }.to_h
hash.replace(sorted)
end
end
Loading

0 comments on commit 4d021af

Please sign in to comment.