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.
376 377 378 379 380 381 |
# File 'lib/handshake.rb', line 376 def initialize(method_name) @method_name = method_name @preconditions, @postconditions = [], [] @accepts, @returns = [], [] @block_contract = nil end |
Instance Attribute Details
#block_contract ⇒ Object (readonly)
Returns the value of attribute block_contract.
374 375 376 |
# File 'lib/handshake.rb', line 374 def block_contract @block_contract end |
#postconditions ⇒ Object
:nodoc:
373 374 375 |
# File 'lib/handshake.rb', line 373 def postconditions @postconditions end |
#preconditions ⇒ Object
:nodoc:
373 374 375 |
# File 'lib/handshake.rb', line 373 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.
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 |
# File 'lib/handshake.rb', line 437 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
383 384 385 386 387 388 |
# File 'lib/handshake.rb', line 383 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.
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 |
# File 'lib/handshake.rb', line 418 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.
401 402 403 |
# File 'lib/handshake.rb', line 401 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.
408 409 410 |
# File 'lib/handshake.rb', line 408 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.
392 393 394 395 396 |
# File 'lib/handshake.rb', line 392 def defined? [ preconditions, postconditions, accepts, returns ].any? do |ary| not ary.empty? end end |
#expects_block? ⇒ Boolean
453 454 455 |
# File 'lib/handshake.rb', line 453 def expects_block? not @block_contract.nil? end |