From 0687c7533d4916f3bed02a69178ee54edba37fc0 Mon Sep 17 00:00:00 2001 From: Mateusz Drewniak Date: Fri, 19 Apr 2024 16:10:31 +0200 Subject: [PATCH] Add new test cases and update README --- README.md | 18 +++++++++++ spec/implementation_check_spec.rb | 53 +++++++++++-------------------- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 34efd2b..fc21bd1 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,24 @@ Will fail because of method signature mismatch: - expected arguments: (req, req) - actual arguments: (req, opt=) +Classes may define additional optional or rest arguments. + +```ruby +module Carrier + def call(number); end + + def text(number, text); end +end + +class Giffgaff + def call(number, *opts); end + + def text(number, text, opt1 = nil, opt2 = nil); end +end +``` + +This will not generate any errors since `Giffgaff` implements the required methods with correct arguments only adding new optional ones. + ### Rails Mix in `Interfaceable` before any of the application code is loaded. For example, in the initializer. For extra peace of mind, you can noop interface checking in production: diff --git a/spec/implementation_check_spec.rb b/spec/implementation_check_spec.rb index b7a4b8b..13de6d2 100644 --- a/spec/implementation_check_spec.rb +++ b/spec/implementation_check_spec.rb @@ -49,18 +49,9 @@ def foo(aaa, baz = 3, bar:, fuga: 2); end } } ) + end - interface = Module.new do - def foo(aaa, bbb); end - end - klass = Class.new do - def foo(aaa, baz); end - end - - errors = Interfaceable::ImplementationCheck.new(klass).perform([interface]) - - expect(errors).to be_empty - + it 'accepts additional optional arguments' do interface = Module.new do def foo(aaa, bbb); end end @@ -125,15 +116,9 @@ def self.foo(aaa, bar = 1); end } } ) + end - klass = Class.new do - def self.foo(aaa, bar = 1, *args); end - end - - errors = Interfaceable::ImplementationCheck.new(klass).perform([interface]) - - expect(errors).to be_empty - + it 'accepts additional *rest argument' do interface = Module.new do def self.foo(aaa, baz = 3); end end @@ -148,25 +133,9 @@ def self.foo(aaa, bar = 1, *args); end end it 'checks **opts argument' do - interface = Module.new do - def foo(aaa, baz = 3, *args, foo:); end - end - klass = Class.new do - def foo(aaa, bar = 1, *args, foo:, **opts); end - end - - errors = Interfaceable::ImplementationCheck.new(klass).perform([interface]) - - # allow the class to have additional rest parameters - expect(errors).to be_empty - interface = Module.new do def foo(aaa, baz = 3, *args, foo:, **options); end end - - errors = Interfaceable::ImplementationCheck.new(klass).perform([interface]) - expect(errors).to be_empty - klass = Class.new do def foo(aaa, bar = 1, *args, foo:); end end @@ -181,5 +150,19 @@ def foo(aaa, bar = 1, *args, foo:); end } ) end + + it 'accepts additional **opts argument' do + interface = Module.new do + def foo(aaa, baz = 3, *args, foo:); end + end + klass = Class.new do + def foo(aaa, bar = 1, *args, foo:, **opts); end + end + + errors = Interfaceable::ImplementationCheck.new(klass).perform([interface]) + + # allow the class to have additional rest parameters + expect(errors).to be_empty + end end # rubocop:enable Metrics/BlockLength