Skip to content

Commit 17ef978

Browse files
committed
Merge pull request #153 from waterlink/feature/152/recognize_module_as_class_contract
Recognize module as a class contract
2 parents e227cda + 128b19a commit 17ef978

File tree

3 files changed

+72
-1
lines changed

3 files changed

+72
-1
lines changed

Diff for: lib/contracts.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ def self.make_validator(contract)
249249
# e.g. Fixnum, Num
250250
if contract.respond_to? :valid?
251251
lambda { |arg| contract.valid?(arg) }
252-
elsif klass == Class
252+
elsif klass == Class || klass == Module
253253
lambda { |arg| arg.is_a?(contract) }
254254
else
255255
lambda { |arg| contract == arg }

Diff for: spec/contracts_spec.rb

+32
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,38 @@ def self.greeting(name)
567567
end
568568
end
569569

570+
describe "module contracts" do
571+
it "passes for instance of class including module" do
572+
expect(
573+
ModuleContractExample.hello(ModuleContractExample::AClassWithModule.new)
574+
).to eq(:world)
575+
end
576+
577+
it "passes for instance of class including inherited module" do
578+
expect(
579+
ModuleContractExample.hello(ModuleContractExample::AClassWithInheritedModule.new)
580+
).to eq(:world)
581+
end
582+
583+
it "does not pass for instance of class not including module" do
584+
expect do
585+
ModuleContractExample.hello(ModuleContractExample::AClassWithoutModule.new)
586+
end.to raise_error(ContractError, /Expected: ModuleContractExample::AModule/)
587+
end
588+
589+
it "does not pass for instance of class including another module" do
590+
expect do
591+
ModuleContractExample.hello(ModuleContractExample::AClassWithAnotherModule.new)
592+
end.to raise_error(ContractError, /Expected: ModuleContractExample::AModule/)
593+
end
594+
595+
it "passes for instance of class including both modules" do
596+
expect(
597+
ModuleContractExample.hello(ModuleContractExample::AClassWithBothModules.new)
598+
).to eq(:world)
599+
end
600+
end
601+
570602
describe "Contracts to_s formatting in expected" do
571603
def not_s(match)
572604
Regexp.new "[^\"\']#{match}[^\"\']"

Diff for: spec/fixtures/fixtures.rb

+39
Original file line numberDiff line numberDiff line change
@@ -588,3 +588,42 @@ def something(a, b)
588588
nil
589589
end
590590
end
591+
592+
module ModuleContractExample
593+
include Contracts
594+
595+
module AModule
596+
end
597+
598+
module AnotherModule
599+
end
600+
601+
module InheritedModule
602+
include AModule
603+
end
604+
605+
class AClassWithModule
606+
include AModule
607+
end
608+
609+
class AClassWithoutModule
610+
end
611+
612+
class AClassWithAnotherModule
613+
include AnotherModule
614+
end
615+
616+
class AClassWithInheritedModule
617+
include InheritedModule
618+
end
619+
620+
class AClassWithBothModules
621+
include AModule
622+
include AnotherModule
623+
end
624+
625+
Contract AModule => Symbol
626+
def self.hello(thing)
627+
:world
628+
end
629+
end

0 commit comments

Comments
 (0)