Skip to content

Instantly share code, notes, and snippets.

@thiagoa
Created December 23, 2022 19:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thiagoa/02f812c858849dc6014469808f166863 to your computer and use it in GitHub Desktop.
Save thiagoa/02f812c858849dc6014469808f166863 to your computer and use it in GitHub Desktop.
RSpec.shared_examples_for "check interface against canonical" do |canonical_interface, classes_to_check|
classes_to_check.each do |class_to_check|
example "#{class_to_check} conforms to the required interface", :aggregate_failures do
interface_methods = canonical_interface.public_instance_methods(false)
methods_to_check = class_to_check.public_instance_methods(false)
diff = interface_methods - methods_to_check
expect(diff).to be_empty, (<<~MESSAGE).split("\n").join(" ")
Expected #{class_to_check} to be polymorphic with
interface #{canonical_interface}, however the
following methods were missing: #{diff}
MESSAGE
present_methods = interface_methods & methods_to_check
present_methods.each do |method|
expected_arity = canonical_interface.instance_method(method).arity
actual_arity = class_to_check.instance_method(method).arity
if actual_arity > -1 && expected_arity > -1
expect(actual_arity).to eq(expected_arity), (<<~MESSAGE).split("\n").join(" ")
Expected #{class_to_check}##{method.name} to have same arity
as interface #{canonical_interface}##{method.name}
#{expected_arity}, but it was #{actual_arity}.
MESSAGE
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment