Sha256: c410fd40924153ab0568d40d1ab6f49a7e71c6882a4478b03f247fe8845a189d
Contents?: true
Size: 1.96 KB
Versions: 1
Compression:
Stored size: 1.96 KB
Contents
module Contracts class Testable # Given an array-of-arrays of arguments, # gives you the product of those arguments so that # each possible combination is tried. # Example: <tt>[[1, 2], [3, 4]]</tt> would give you: # # [[1, 3], [1, 4], [2, 3], [2, 4]] def self.product(arrays) arrays.inject do |acc, x| acc.product(x) end.flatten(arrays.size - 2) end # Given a contract, tells if you it's testable def self.testable?(contract) if contract.respond_to?(:testable?) contract.testable? else contract.respond_to?(:new) && contract.method(:new).arity == 0 end end # Given a contract, returns the test data associated with that contract def self.test_data(contract) if contract.respond_to?(:testable?) contract.test_data else contract.new end end # TODO: Should work on whatever class it was invoked on, no? def self.check_all o = Object.new Object.decorated_methods.each do |name, _contracts| check(o.method(name)) end end def self.check(meth) contracts = meth.owner.decorated_methods[meth.name.to_sym][0].contracts arg_contracts = contracts[0, contracts.size - 1] return_val = contracts[-1] checkable = arg_contracts.all? do |arg_contract| Testable.testable?(arg_contract) end if checkable print "Checking #{meth.name}..." _test_data = arg_contracts.map do |arg_contract| data = Testable.test_data(arg_contract) data.is_a?(Array) ? data : [data] end test_data = Testable.product _test_data test_data.each do |args| if args.is_a? Hash # because *hash destroys the hash res = meth.call(args) else res = meth.call(*args) end Contract.valid?(res, return_val) end puts "#{test_data.size} tests run." end end end end
Version data entries
1 entries across 1 versions & 1 rubygems
Version | Path |
---|---|
contracts-0.8 | lib/contracts/testable.rb |