Class: Contracts::Testable

Inherits:
Object
  • Object
show all
Defined in:
lib/contracts/testable.rb

Class Method Summary collapse

Class Method Details

.check(meth) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/contracts/testable.rb', line 41

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

.check_allObject

TODO Should work on whatever class it was invoked on, no?



34
35
36
37
38
39
# File 'lib/contracts/testable.rb', line 34

def self.check_all
  o = Object.new
  Object.decorated_methods.each do |name, contracts|
    check(o.method(name))
  end
end

.product(arrays) ⇒ Object

Given an array-of-arrays of arguments, gives you the product of those arguments so that each possible combination is tried. Example: [[1, 2], [3, 4]] would give you:

[[1, 3], [1, 4], [2, 3], [2, 4]]


9
10
11
12
13
# File 'lib/contracts/testable.rb', line 9

def self.product(arrays)
  arrays.inject { |acc, x|
    acc.product(x)
  }.flatten(arrays.size - 2)
end

.test_data(contract) ⇒ Object

Given a contract, returns the test data associated with that contract



25
26
27
28
29
30
31
# File 'lib/contracts/testable.rb', line 25

def self.test_data(contract)
  if contract.respond_to?(:testable?)
    contract.test_data
  else
    contract.new
  end
end

.testable?(contract) ⇒ Boolean

Given a contract, tells if you it’s testable

Returns:

  • (Boolean)


16
17
18
19
20
21
22
# File 'lib/contracts/testable.rb', line 16

def self.testable?(contract)
  if contract.respond_to?(:testable?)
    contract.testable?
  else
    contract.respond_to?(:new) && contract.method(:new).arity == 0
  end
end