module Context
Represents a test context that can contain nested tests and other contexts.
Definitions
attr_accessor :identity
Signature
-
attribute
Identity, nil The identity of this context.
attr_accessor :description
Signature
-
attribute
String, nil The description of this context.
attr_accessor :children
Signature
-
attribute
Hash The child contexts and tests.
def self.extended(base)
Called when this module is extended.
Signature
-
parameter
baseClass The class being extended.
Implementation
def self.extended(base)
base.children = Hash.new
end
def add(child)
Add a child context or test to this context.
Signature
-
parameter
childObject The child to add.
Implementation
def add(child)
@children[child.identity] = child
end
def empty?
Signature
-
returns
Boolean Whether this context has no children.
Implementation
def empty?
@children.nil? || @children.empty?
end
def leaf?
Signature
-
returns
Boolean Always returns false, as contexts are not leaf nodes.
Implementation
def leaf?
false
end
def print(output)
Print a representation of this context.
Signature
-
parameter
outputOutput The output target.
Implementation
def print(output)
output.write("context ", :context, self.description, :reset)
end
def full_name
Signature
-
returns
String The full name of this context.
Implementation
def full_name
output = Output::Buffered.new
print(output)
return output.string
end
def call(assertions)
Execute all child contexts and tests.
Signature
-
parameter
assertionsAssertions The assertions instance to use.
Implementation
def call(assertions)
return if self.empty?
assertions.nested(self) do |assertions|
self.children.each do |identity, child|
child.call(assertions)
end
end
end
def each(&block)
Iterate over all leaf nodes (test cases) in this context.
Signature
-
yields
{|test| ...} Each test case.
Implementation
def each(&block)
self.children.each do |identity, child|
if child.leaf?
yield child
else
child.each(&block)
end
end
end
def before(&hook)
Include a before hook to the context class, that invokes the given block before running each test.
Before hooks are usually invoked in the order they are defined, i.e. the first defined hook is invoked first.
Signature
-
yields
{...} The block to execute before each test.
Implementation
def before(&hook)
wrapper = Module.new
wrapper.define_method(:before) do
super()
instance_exec(&hook)
end
self.include(wrapper)
end
def after(&hook)
Include an after hook to the context class, that invokes the given block after running each test.
After hooks are usually invoked in the reverse order they are defined, i.e. the last defined hook is invoked first.
Signature
-
yields
{|error| ...} The block to execute after each test. An
errorargument is passed if the test failed with an exception.
Implementation
def after(&hook)
wrapper = Module.new
wrapper.define_method(:after) do |error|
instance_exec(error, &hook)
rescue => error
raise
ensure
super(error)
end
self.include(wrapper)
end
def around(&block)
Add an around hook to the context class.
Around hooks are called in the reverse order they are defined.
The top level around implementation invokes before and after hooks.
Signature
-
yields
{|&block| ...} The block to execute around each test.
Implementation
def around(&block)
wrapper = Module.new
wrapper.define_method(:around, &block)
self.include(wrapper)
end
def describe(subject, **options, &block)
Define a new test group describing a subject.
Signature
-
parameter
subjectObject The subject to describe (class, module, or feature).
-
parameter
optionsHash Additional options.
-
yields
{...} Optional block containing nested tests.
Implementation
def describe(subject, **options, &block)
add Describe.build(self, subject, **options, &block)
end
def file(path)
Load a test file as a child context.
Signature
-
parameter
pathString The path to the test file.
Implementation
def file(path)
add File.build(self, path)
end
def include_context(shared, *arguments, **options)
Include a shared context into the current context, along with any arguments or options.
Signature
-
parameter
sharedSus::Shared The shared context to include.
-
parameter
argumentsArray The arguments to pass to the shared context.
-
parameter
optionsHash The options to pass to the shared context.
Implementation
def include_context(shared, *arguments, **options)
self.class_exec(*arguments, **options, &shared.block)
end
def it(...)
Define a new test case.
Signature
-
parameter
descriptionString The description of the test.
-
parameter
optionsHash Additional options.
-
yields
{...} The test code.
Implementation
def it(...)
add It.build(self, ...)
end
def it_behaves_like(shared, *arguments, **options, &block)
Define a test context that behaves like a shared context.
Signature
-
parameter
sharedShared The shared context to use.
-
parameter
argumentsArray Optional arguments to pass to the shared context.
-
parameter
optionsHash Additional options.
-
yields
{...} Optional block to execute before the shared context.
Implementation
def it_behaves_like(shared, *arguments, **options, &block)
add ItBehavesLike.build(self, shared, arguments, **options, &block)
end
def let(name, &block)
Define a lazy variable that is evaluated when first accessed.
Signature
-
parameter
nameSymbol The name of the variable.
-
yields
{...} The block that computes the variable value.
Implementation
def let(name, &block)
instance_variable = :"@#{name}"
self.define_method(name) do
if self.instance_variable_defined?(instance_variable)
return self.instance_variable_get(instance_variable)
else
self.instance_variable_set(instance_variable, self.instance_exec(&block))
end
end
end
def with(subject = nil, unique: true, **variables, &block)
Define a new test context with specific conditions or variables.
Signature
-
parameter
subjectString | Nil Optional subject description. If nil, uses variables.inspect.
-
parameter
uniqueBoolean Whether the identity should be unique.
-
parameter
variablesHash Variables to make available in the context.
-
yields
{...} Optional block containing nested tests.
Implementation
def with(subject = nil, unique: true, **variables, &block)
subject ||= variables.inspect
add With.build(self, subject, variables, unique: unique, &block)
end