class Speck

All library files are required at the bottom, because in this unique case we need `Speck` defined before we can use it to `Speck` anything.

Constants

NinjaVar

This instance variable will be set on target objects to point to the specks for that object

VERSION

Attributes

stack[RW]

The current `Speck` execution stack

@see current

unbound[RW]

All specks not bound to an environment

block[RW]

The block to be executed

checks[RW]

The checks involved in the current `Speck`

children[RW]

`Speck`s which consider this `Speck` to be their environment

environment[RW]

The `environment` of a `Speck` is another `Speck`, describing some sort of parent. The environment of a `Speck` describing an `UnboundMethod`, for instance, would most likely be a `Speck` describing a `Module` or `Class` on which that method is defined

target[RW]

The `target` of a speck is usually the object which it is intended to describe (and test) the functionality of (Usually, this will be an instance of `Class`, `Module`, `Method` for “class” methods, or `UnboundMethod` for instance methods)

Public Class Methods

current() click to toggle source

Returns the top `Speck` on the execution stack (the one currently in the process of executing)

When your `Speck`s are being run, there is a `stack` of `Speck` objects, consisting of the current nesting list of `Speck`s being run.

# File lib/speck.rb, line 26
def current
  stack.last
end
for(object) click to toggle source

Retreives the `Speck`s defiend for a given object, or, if none are defined, creates a new (empty) `Speck` for it.

It’s worth noting that `Module#instance_method` returns a new `UnboundMethod` object every time you call it, even for the same method… so you can’t retreive Specks assigned to `UnboundMethods` via `Module#instance_method` with this method.

# File lib/speck.rb, line 38
def for object
  specks = Speck::on object
  specks << Speck.new(object) if specks.empty?
  return specks
end
new(*environment, &block) click to toggle source

Creates a new `Speck`.

# File lib/speck.rb, line 107
def initialize *environment, &block
  self.target = environment.pop
  
  environment = environment.inject do |prev, curr|
    raise Exception::EnvironmentConflict if Speck::for(curr).first.environment and Speck::for(curr).first.environment != Speck::for(prev).first
    Speck::for(curr).first.environment = Speck::for(prev).first
    curr
  end
  
  self.environment = environment ? Speck::for(environment).first : Speck.current
  @block = block || lambda {}
end
on(object) click to toggle source

Functions like `Speck::for`, without creating a new `Speck` if none are defined.

@see `Speck::for`

# File lib/speck.rb, line 49
def on object
  object.instance_variable_get(NinjaVar) ||
    object.instance_variable_set(NinjaVar, Array.new)
end

Public Instance Methods

environment=(object) click to toggle source
# File lib/speck.rb, line 76
def environment= object
  (@environment ? @environment.children : Speck.unbound).delete self
  
  speck = object.is_a?(Speck) || object.nil? ?
    object : Speck::for(object).first
  @environment = speck
  
  (@environment ? @environment.children : Speck.unbound) << self
end
execute() click to toggle source

Executes the `Speck`.

# File lib/speck.rb, line 122
def execute
  Speck.stack << self
  @block.call
  Speck.stack.pop
end
target=(object) click to toggle source
# File lib/speck.rb, line 97
def target= object
  Speck::on(@target).delete self if @target and Speck::on(@target).include? self
  
  @target = object
  
  Speck::on(@target) << self if @target
end