Class: Handshake::MethodContract
- Inherits:
-
ProcContract
- Object
- ProcContract
- Handshake::MethodContract
- Defined in:
- lib/handshake.rb
Overview
Class representing method contracts. Not for external use.
Instance Attribute Summary collapse
-
#block_contract ⇒ Object
readonly
Returns the value of attribute block_contract.
-
#postconditions ⇒ Object
:nodoc:.
-
#preconditions ⇒ Object
:nodoc:.
Attributes inherited from ProcContract
Instance Method Summary collapse
-
#accepts=(args) ⇒ Object
If the last argument is a Block, handle it as a special case.
- #check_accepts!(*args, &block) ⇒ Object
-
#check_conditions!(o, args, conditions) ⇒ Object
Checks the given conditions against the object, passing the given args into the block.
-
#check_post!(o, *args) ⇒ Object
Checks the postconditions of this contract against the given object and return values.
-
#check_pre!(o, *args) ⇒ Object
Checks the preconditions of this contract against the given object and arugment values.
-
#defined? ⇒ Boolean
Returns true only if this MethodContract has been set up to check for one or more contract conditions.
- #expects_block? ⇒ Boolean
-
#initialize(method_name) ⇒ MethodContract
constructor
A new instance of MethodContract.
Methods inherited from ProcContract
#accepts_varargs?, #check_returns!, #signature=
Constructor Details
#initialize(method_name) ⇒ MethodContract
Returns a new instance of MethodContract.
395 396 397 398 399 |
# File 'lib/handshake.rb', line 395 def initialize(method_name) @method_name = method_name @preconditions, @postconditions = [], [] @accepts, @returns = [], [] end |
Instance Attribute Details
#block_contract ⇒ Object (readonly)
Returns the value of attribute block_contract.
393 394 395 |
# File 'lib/handshake.rb', line 393 def block_contract @block_contract end |
#postconditions ⇒ Object
:nodoc:
392 393 394 |
# File 'lib/handshake.rb', line 392 def postconditions @postconditions end |
#preconditions ⇒ Object
:nodoc:
392 393 394 |
# File 'lib/handshake.rb', line 392 def preconditions @preconditions end |
Instance Method Details
#accepts=(args) ⇒ Object
If the last argument is a Block, handle it as a special case. We do this to ensure that there’s no conflict with any real arguments which may accept Procs.
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 |
# File 'lib/handshake.rb', line 455 def accepts=(args) if args.last == Block # Transform into a ProcContract args.pop @block_contract = ProcContract.new @block_contract.accepts = ClauseMethods::ANYTHING @block_contract.returns = ClauseMethods::ANYTHING elsif args.last.is_a?(ProcContract) @block_contract = args.pop end if args.find_all {|o| o.is_a? Array}.length > 1 raise ContractError, "Cannot define more than one expected variable argument" end super(args) end |
#check_accepts!(*args, &block) ⇒ Object
401 402 403 404 405 406 |
# File 'lib/handshake.rb', line 401 def check_accepts!(*args, &block) super(*args, &block) if expects_block? check_equivalence!(block, Proc) end end |
#check_conditions!(o, args, conditions) ⇒ Object
Checks the given conditions against the object, passing the given args into the block. Throws :contract if any fail or if an exception is raised. Because of the need to evaluate the condition in the context of the object itself, a temporary method called bound_condition_passes?
is defined on the object, using the block associated with the condition. TODO Is there a better way to evaluate an arbitary block in a particular binding? There must be.
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 |
# File 'lib/handshake.rb', line 436 def check_conditions!(o, args, conditions) conditions.each do |condition| o.class.instance_eval do define_method(:bound_condition_passes?, &(condition.block)) end begin o.bound_condition_passes?(*args) rescue Test::Unit::AssertionFailedError => afe throw :contract, AssertionFailed.new(afe.) rescue Exception => e throw :contract, e end o.class.send(:remove_method, :bound_condition_passes?) end end |
#check_post!(o, *args) ⇒ Object
Checks the postconditions of this contract against the given object and return values. Any assertions thrown are re-raised as Handshake::AssertionViolation errors.
419 420 421 |
# File 'lib/handshake.rb', line 419 def check_post!(o, *args) check_conditions!(o, args, @postconditions) end |
#check_pre!(o, *args) ⇒ Object
Checks the preconditions of this contract against the given object and arugment values. Any assertions thrown are re-raised as Handshake::AssertionFailed errors.
426 427 428 |
# File 'lib/handshake.rb', line 426 def check_pre!(o, *args) check_conditions!(o, args, @preconditions) end |
#defined? ⇒ Boolean
Returns true only if this MethodContract has been set up to check for one or more contract conditions.
410 411 412 413 414 |
# File 'lib/handshake.rb', line 410 def defined? [ preconditions, postconditions, accepts, returns ].any? do |ary| not ary.empty? end end |
#expects_block? ⇒ Boolean
471 472 473 |
# File 'lib/handshake.rb', line 471 def expects_block? not @block_contract.nil? end |