riot 0.12.1 → 0.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +10 -0
- data/.yardopts +6 -0
- data/CHANGELOG +58 -46
- data/Gemfile +4 -0
- data/README.markdown +322 -85
- data/Rakefile +3 -38
- data/lib/riot.rb +74 -11
- data/lib/riot/assertion.rb +32 -1
- data/lib/riot/assertion_macro.rb +57 -10
- data/lib/riot/assertion_macros/any.rb +4 -2
- data/lib/riot/assertion_macros/assigns.rb +18 -4
- data/lib/riot/assertion_macros/empty.rb +2 -0
- data/lib/riot/assertion_macros/equals.rb +4 -0
- data/lib/riot/assertion_macros/equivalent_to.rb +5 -1
- data/lib/riot/assertion_macros/exists.rb +4 -2
- data/lib/riot/assertion_macros/includes.rb +5 -1
- data/lib/riot/assertion_macros/kind_of.rb +5 -1
- data/lib/riot/assertion_macros/matches.rb +5 -1
- data/lib/riot/assertion_macros/nil.rb +3 -1
- data/lib/riot/assertion_macros/not_borat.rb +6 -0
- data/lib/riot/assertion_macros/raises.rb +13 -7
- data/lib/riot/assertion_macros/respond_to.rb +5 -1
- data/lib/riot/assertion_macros/same_elements.rb +6 -2
- data/lib/riot/assertion_macros/size.rb +5 -1
- data/lib/riot/context.rb +58 -10
- data/lib/riot/context_helpers.rb +20 -4
- data/lib/riot/context_options.rb +14 -4
- data/lib/riot/message.rb +87 -6
- data/lib/riot/middleware.rb +69 -4
- data/lib/riot/reporter.rb +71 -110
- data/lib/riot/reporter/dot_matrix.rb +49 -0
- data/lib/riot/reporter/io.rb +85 -0
- data/lib/riot/reporter/pretty_dot_matrix.rb +38 -0
- data/lib/riot/reporter/silent.rb +18 -0
- data/lib/riot/reporter/story.rb +52 -0
- data/lib/riot/rr.rb +28 -4
- data/lib/riot/runnable.rb +53 -0
- data/lib/riot/situation.rb +45 -0
- data/lib/riot/version.rb +4 -0
- data/riot.gemspec +14 -155
- data/test/core/assertion_macros/any_test.rb +10 -10
- data/test/core/assertion_macros/assigns_test.rb +7 -7
- data/test/core/assertion_macros/equivalent_to_test.rb +3 -3
- data/test/core/assertion_macros/exists_test.rb +4 -4
- data/test/core/assertion_macros/includes_test.rb +2 -2
- data/test/core/assertion_macros/kind_of_test.rb +3 -3
- data/test/core/assertion_macros/matches_test.rb +2 -2
- data/test/core/assertion_macros/nil_test.rb +2 -2
- data/test/core/assertion_macros/raises_test.rb +10 -10
- data/test/core/assertion_macros/respond_to_test.rb +2 -2
- data/test/core/assertion_macros/same_elements_test.rb +4 -4
- data/test/core/assertion_macros/size_test.rb +6 -6
- data/test/core/context/asserts_with_arguments_test.rb +12 -0
- data/test/core/context/using_describe_in_a_test.rb +1 -1
- data/test/core/report_test.rb +9 -5
- data/test/core/runnable/message_test.rb +10 -6
- data/test/teststrap.rb +0 -6
- metadata +20 -33
- data/TODO.markdown +0 -14
- data/VERSION +0 -1
- data/test.watchr +0 -70
- data/test/benchmark/colorize.rb +0 -39
@@ -0,0 +1,49 @@
|
|
1
|
+
module Riot
|
2
|
+
|
3
|
+
# Outputs in the dot-notion almost everyone should be familiar with, "." implies pass, "F" implues a
|
4
|
+
# failure, and "E" implies an error. If ansi-coloring is available, it is used. Error and failure messages
|
5
|
+
# are buffered for output until the end.
|
6
|
+
class DotMatrixReporter < IOReporter
|
7
|
+
# Creates a new DotMatrixReporter and initializes the failure/error details buffer.
|
8
|
+
# @param (see Riot::IOReporter#initialize)
|
9
|
+
def initialize(writer=STDOUT)
|
10
|
+
super
|
11
|
+
@details = []
|
12
|
+
end
|
13
|
+
|
14
|
+
# Prints a ".". Prints in green if possible.
|
15
|
+
#
|
16
|
+
# @param (see Riot::Reporter#pass)
|
17
|
+
def pass(description, message)
|
18
|
+
print green(".")
|
19
|
+
end
|
20
|
+
|
21
|
+
# Prints a "F" and saves the failure details (including line number and file) for the end.
|
22
|
+
# Prints in yellow if possible.
|
23
|
+
#
|
24
|
+
# @param (see Riot::Reporter#fail)
|
25
|
+
def fail(description, message, line, file)
|
26
|
+
print yellow("F")
|
27
|
+
@details << "FAILURE - #{test_detail(description, message)} #{line_info(line, file)}".strip
|
28
|
+
end
|
29
|
+
|
30
|
+
# Prints a "E" and saves the error details (including backtrace) for the end. Prints in red if possible.
|
31
|
+
#
|
32
|
+
# @param (see Riot::Reporter#error)
|
33
|
+
def error(description, e)
|
34
|
+
print red("E")
|
35
|
+
@details << "ERROR - #{test_detail(description, format_error(e))}"
|
36
|
+
end
|
37
|
+
|
38
|
+
# (see Riot::Reporter#results)
|
39
|
+
def results(time_taken)
|
40
|
+
puts "\n#{@details.join("\n\n")}" unless @details.empty?
|
41
|
+
super
|
42
|
+
end
|
43
|
+
private
|
44
|
+
def test_detail(description, message)
|
45
|
+
"#{current_context.detailed_description} #{description} => #{message}"
|
46
|
+
end
|
47
|
+
end # DotMatrixReporter
|
48
|
+
|
49
|
+
end # Riot
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Riot
|
2
|
+
|
3
|
+
# An IOReporter is one that expects to use an IO object to output results to. Thus, whatever is available
|
4
|
+
# by an instance of an IO object should be available to whatever is given to this reporter to use.
|
5
|
+
#
|
6
|
+
# This is an abstract class. You should use some other or define your own sub-class that knows how to
|
7
|
+
# handle +pass+, +fail+, and +error+.
|
8
|
+
class IOReporter < Reporter
|
9
|
+
# Creates a new IOReporter. You can give it your own IO writer or it will default to +STDOUT+.
|
10
|
+
#
|
11
|
+
# @param [IO] writer the writer to use for results
|
12
|
+
def initialize(writer=STDOUT)
|
13
|
+
super()
|
14
|
+
@writer = writer
|
15
|
+
end
|
16
|
+
|
17
|
+
# (see Riot::Reporter#results)
|
18
|
+
def results(time_taken)
|
19
|
+
values = [passes, failures, errors, ("%0.6f" % time_taken)]
|
20
|
+
puts "\n%d passes, %d failures, %d errors in %s seconds" % values
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
# Helper that knows how to write output to the writer with a newline.
|
25
|
+
#
|
26
|
+
# @param [String] message the message to be printed
|
27
|
+
def puts(message) @writer.puts(message); end
|
28
|
+
|
29
|
+
# Helper that knows how to write output to the writer without a newline.
|
30
|
+
#
|
31
|
+
# @param [String] message the message to be printed
|
32
|
+
def print(message) @writer.print(message); end
|
33
|
+
|
34
|
+
# Takes a line number, the file it corresponds to, and generates a formatted string for use in failure
|
35
|
+
# responses.
|
36
|
+
#
|
37
|
+
# @param [Number] line the line number of the failure
|
38
|
+
# @param [String] file the name of the file the failure was in
|
39
|
+
# @return [String] formatted failure line
|
40
|
+
def line_info(line, file)
|
41
|
+
line ? "(on line #{line} in #{file})" : ""
|
42
|
+
end
|
43
|
+
|
44
|
+
# Generates a message for assertions that error out. However, in the additional stacktrace, any mentions
|
45
|
+
# of Riot and Rake framework methods calls are removed. Makes for a more readable error response.
|
46
|
+
#
|
47
|
+
# @param [Exception] e the exception to generate the backtrace from
|
48
|
+
# @return [String] the error response message
|
49
|
+
def format_error(e)
|
50
|
+
format = []
|
51
|
+
format << " #{e.class.name} occurred"
|
52
|
+
format << "#{e.to_s}"
|
53
|
+
filter_backtrace(e.backtrace) { |line| format << " at #{line}" }
|
54
|
+
|
55
|
+
format.join("\n")
|
56
|
+
end
|
57
|
+
|
58
|
+
# Filters Riot and Rake method calls from an exception backtrace.
|
59
|
+
#
|
60
|
+
# @param [Array] backtrace an exception's backtrace
|
61
|
+
# @param [lambda] &line_handler called each time a good line is found
|
62
|
+
def filter_backtrace(backtrace, &line_handler)
|
63
|
+
cleansed, bad = [], true
|
64
|
+
|
65
|
+
# goal is to filter all the riot stuff/rake before the first non riot thing
|
66
|
+
backtrace.reverse_each do |bt|
|
67
|
+
# make sure we are still in the bad part
|
68
|
+
bad = (bt =~ /\/lib\/riot/ || bt =~ /rake_test_loader/) if bad
|
69
|
+
yield bt unless bad
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Color output
|
74
|
+
def red(str); with_color(31, str); end
|
75
|
+
def yellow(str); with_color(33, str); end
|
76
|
+
def green(str); with_color(32, str); end
|
77
|
+
|
78
|
+
# for color reference:
|
79
|
+
# http://www.pixelbeat.org/docs/terminal_colours/
|
80
|
+
def with_color(code,str)
|
81
|
+
"\e[#{code}m#{str}\e[0m"
|
82
|
+
end
|
83
|
+
end # IOReporter
|
84
|
+
|
85
|
+
end # Riot
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Riot
|
2
|
+
|
3
|
+
# This is essentially just DotMatrix with the legacy DotMatrix formatting, slightly better.
|
4
|
+
# Failure and Error outputs are color labeled and are formatted neatly and
|
5
|
+
# concisely under each associated label.
|
6
|
+
# example:
|
7
|
+
# ........FE....
|
8
|
+
# FAILURE
|
9
|
+
# A failure would have a message like this => expected 1, not 0
|
10
|
+
# (on line 26 in test/core/blah.rb)
|
11
|
+
# ERROR
|
12
|
+
# A reporter asserts this errors => Exception occured
|
13
|
+
# at test/core/report_test.rb:24:in `block (2 levels) in <top (required)>'
|
14
|
+
#
|
15
|
+
class PrettyDotMatrixReporter < DotMatrixReporter
|
16
|
+
|
17
|
+
# Prints a yellow F and formats the Fail messages a bit better
|
18
|
+
# than the default DotMatrixReporter
|
19
|
+
def fail(description, message, line, file)
|
20
|
+
print yellow('F')
|
21
|
+
@details << "#{yellow("FAILURE")}\n #{test_detail(description, message)}\n #{line_info(line, file)}".strip
|
22
|
+
end
|
23
|
+
|
24
|
+
# Prints out an red E and formats the fail message better
|
25
|
+
def error(description, e)
|
26
|
+
print red('E')
|
27
|
+
@details << "#{red("ERROR")}\n #{test_detail(description,"#{e} occured")}\n #{simple_error(e)}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def simple_error(e)
|
31
|
+
format = []
|
32
|
+
filter_backtrace(e.backtrace) { |line| format << "at #{line}" }
|
33
|
+
|
34
|
+
format.join("\n")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Riot
|
2
|
+
|
3
|
+
# Basically, the Null Object pattern; nothing is output from this reporter.
|
4
|
+
class SilentReporter < Reporter
|
5
|
+
# (see Riot::Reporter#pass)
|
6
|
+
def pass(description, message); end
|
7
|
+
|
8
|
+
# (see Riot::Reporter#fail)
|
9
|
+
def fail(description, message, line, file); end
|
10
|
+
|
11
|
+
# (see Riot::Reporter#error)
|
12
|
+
def error(description, e); end
|
13
|
+
|
14
|
+
# (see Riot::Reporter#results)
|
15
|
+
def results(time_taken); end
|
16
|
+
end # SilentReporter
|
17
|
+
|
18
|
+
end # Riot
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Riot
|
2
|
+
|
3
|
+
# For each context that is started and assertion that is run, its description is printed to the console
|
4
|
+
# on its own line. Regarding assertions, if ansi-colors are available then passing assertions are printed
|
5
|
+
# in green, failing in yellow, and errors in red. Note that backtraces are not reported for errors; see
|
6
|
+
# {Riot::VerboseStoryReporter}.
|
7
|
+
class StoryReporter < IOReporter
|
8
|
+
# Prints the descrition of the context on its own line
|
9
|
+
#
|
10
|
+
# @param (see Riot::Reporter#describe_context)
|
11
|
+
def describe_context(context)
|
12
|
+
super
|
13
|
+
puts context.detailed_description
|
14
|
+
end
|
15
|
+
|
16
|
+
# Prints the description of the assertion. Prints in green if possible.
|
17
|
+
#
|
18
|
+
# @param (see Riot::Reporter#pass)
|
19
|
+
def pass(description, message)
|
20
|
+
puts " + " + green("#{description} #{message}".strip)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Prints the description of the assertion and the line number of the failure. Prints in yellow if
|
24
|
+
# possible.
|
25
|
+
#
|
26
|
+
# @param (see Riot::Reporter#fail)
|
27
|
+
def fail(description, message, line, file)
|
28
|
+
puts " - " + yellow("#{description}: #{message} #{line_info(line, file)}".strip)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Prints the description of the assertion and the exception message. Prints in red if
|
32
|
+
# possible.
|
33
|
+
#
|
34
|
+
# @param (see Riot::Reporter#error)
|
35
|
+
def error(description, e)
|
36
|
+
puts " ! " + red("#{description}: #{e.message}")
|
37
|
+
end
|
38
|
+
end # StoryReporter
|
39
|
+
|
40
|
+
# Same as {Riot::StoryReporter} except that backtraces are printed for assertions with errors
|
41
|
+
class VerboseStoryReporter < StoryReporter
|
42
|
+
# Prints the description of the assertion and the exception backtrace. Prints in red if
|
43
|
+
# possible.
|
44
|
+
#
|
45
|
+
# @param (see Riot::Reporter#error)
|
46
|
+
def error(description, e)
|
47
|
+
super
|
48
|
+
puts red(format_error(e))
|
49
|
+
end
|
50
|
+
end # VerboseStoryReporter
|
51
|
+
|
52
|
+
end # Riot
|
data/lib/riot/rr.rb
CHANGED
@@ -1,13 +1,29 @@
|
|
1
1
|
require 'rr'
|
2
2
|
|
3
3
|
module Riot
|
4
|
+
# Enables inherent RR support in Riot. When required in, all contexts and assertions are adapted to have
|
5
|
+
# RR support.
|
4
6
|
module RR
|
5
7
|
|
8
|
+
# Basically, provides a {Riot::Situation} that has been adapted to RR. This means that any of the
|
9
|
+
# RR methods that would typically be used: +mock+, +stub+, +verify+, etc. will be available to any
|
10
|
+
# setup, yeardown, helper, hookup, or assertion.
|
6
11
|
class Situation < Riot::Situation
|
7
12
|
include ::RR::Adapters::RRMethods
|
8
13
|
end # Situation
|
9
14
|
|
15
|
+
# Binds the {Riot::Assertion} to RR so that successes and failures found by RR are inherently handled
|
16
|
+
# during an assertion evaluation. In effect, if RR suggests failure during validation, the assertion
|
17
|
+
# will fail and report these failures.
|
10
18
|
class Assertion < Riot::Assertion
|
19
|
+
# Adds RR support to {Riot::Assertion#run}. The basic flow is to:
|
20
|
+
# * run the test as normal
|
21
|
+
# * ask RR to verify mock results
|
22
|
+
# * report any errors or return the result of the assertion as normal
|
23
|
+
# * reset RR so that the next assertion in the context can be verified cleanly.
|
24
|
+
#
|
25
|
+
# @param (see Riot::Assertion#run)
|
26
|
+
# @return (see Riot::Assertion#run)
|
11
27
|
def run(situation)
|
12
28
|
result = super
|
13
29
|
situation.verify
|
@@ -19,14 +35,22 @@ module Riot
|
|
19
35
|
end
|
20
36
|
end # Assertion
|
21
37
|
|
22
|
-
|
23
|
-
|
38
|
+
# Redefines the classes {Riot::Context} will use when creating new assertions and situations to be the
|
39
|
+
# ones provided RR support. See {Riot::RR::Assertion} and {Riot::RR::Situation}.
|
40
|
+
module ContextClassOverrides
|
41
|
+
# (see Riot::ContextClassOverrides#assertion_class)
|
24
42
|
def assertion_class; Riot::RR::Assertion; end
|
43
|
+
|
44
|
+
# (see Riot::ContextClassOverrides#situation_class)
|
25
45
|
def situation_class; Riot::RR::Situation; end
|
26
|
-
end #
|
46
|
+
end # ContextClassOverrides
|
27
47
|
|
48
|
+
# A convenience method for telling {Riot::RR::ContextClassOverrides} to mix itself into {Riot::Context}.
|
49
|
+
# Thus, enabling RR support in Riot.
|
50
|
+
#
|
51
|
+
# @param [Class] context_class the class representing the Context to bind to
|
28
52
|
def self.enable(context_class)
|
29
|
-
context_class.instance_eval { include Riot::RR::
|
53
|
+
context_class.instance_eval { include Riot::RR::ContextClassOverrides }
|
30
54
|
end
|
31
55
|
|
32
56
|
end # RR
|
data/lib/riot/runnable.rb
CHANGED
@@ -1,30 +1,83 @@
|
|
1
1
|
module Riot
|
2
|
+
# A runnable block is pretty much an anonymous block decorator. It's goal is to accept a block, a
|
3
|
+
# description for what the block is intended to be for, and provide a +run+ method expects a
|
4
|
+
# {Riot::Situation} instance. Any time a {Riot::Situation} is provided to +run+, a {Riot::RunnableBlock}
|
5
|
+
# promises to evaluate itself against the situation in some way.
|
6
|
+
#
|
7
|
+
# Intent is to sub-class {Riot::RunnableBlock} with specific mechanisms for contorting the
|
8
|
+
# {Riot::Situation}.
|
2
9
|
class RunnableBlock
|
10
|
+
|
11
|
+
# The decorated block.
|
3
12
|
attr_reader :definition
|
13
|
+
|
14
|
+
# Creates a new RunnableBlock.
|
15
|
+
#
|
16
|
+
# @param [String] description a description of what this block is for
|
17
|
+
# @param [lambda] &definition the block to decorate
|
4
18
|
def initialize(description, &definition)
|
5
19
|
@description, @definition = description, definition || proc { false }
|
6
20
|
end
|
7
21
|
|
22
|
+
# Given a {Riot::Situation}, eval the provided block against it and then return a status tuple.
|
23
|
+
#
|
24
|
+
# @param [Riot::Situation] situation An instance of a {Riot::Situation}
|
25
|
+
# @return [Array<Symbol[, String]>] array containing at least an evaluation state
|
26
|
+
def run(situation)
|
27
|
+
raise "Define your own run"
|
28
|
+
end
|
29
|
+
|
30
|
+
# String representation of this block, which is basically the description.
|
31
|
+
#
|
32
|
+
# @return [String]
|
8
33
|
def to_s; @description; end
|
9
34
|
end # RunnableBlock
|
10
35
|
|
36
|
+
# Used to decorate a setup, hookup, a teardown or anything else that is about context administration.
|
11
37
|
class Setup < RunnableBlock
|
12
38
|
def initialize(&definition)
|
13
39
|
super("setup", &definition)
|
14
40
|
end
|
15
41
|
|
42
|
+
# Calls {Riot::Situation#setup} with the predefined block at {Riot::Context} run-time. Though this is
|
43
|
+
# like every other kind of {Riot::RunnableBlock}, +run+ will not return a meaningful state, which means
|
44
|
+
# the reporter will likely not report anything.
|
45
|
+
#
|
46
|
+
# @param [Riot::Situation] situation the situation for the current {Riot::Context} run
|
47
|
+
# @return [Array<Symbol>] array containing the evaluation state
|
16
48
|
def run(situation)
|
17
49
|
situation.setup(&definition)
|
18
50
|
[:setup]
|
19
51
|
end
|
20
52
|
end # Setup
|
21
53
|
|
54
|
+
# Used to decorate a helper. A helper generally ends up being a glorified method that can be referenced
|
55
|
+
# from within a setup, teardown, hookup, other helpers, assertion blocks, and assertion macro blocks;
|
56
|
+
# basically anywhere the {Riot::Situation} instance is available.
|
57
|
+
#
|
58
|
+
# context "Making dinner" do
|
59
|
+
# helper(:easy_bake) do |thing|
|
60
|
+
# EasyBake.new(thing, :ingredients => [:ketchup, :chocolate, :syrup])
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# setup do
|
64
|
+
# easy_bake(:meatloaf)
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# asserts(:food_poisoning_probabilty).equals(0.947)
|
68
|
+
# end # Making dinner
|
22
69
|
class Helper < RunnableBlock
|
23
70
|
def initialize(name, &definition)
|
24
71
|
super("helper #{name}", &definition)
|
25
72
|
@name = name
|
26
73
|
end
|
27
74
|
|
75
|
+
# Calls {Riot::Situation#helper} with the predefined helper name and block at {Riot::Context} run-time.
|
76
|
+
# Though this is like every other kind of {Riot::RunnableBlock}, +run+ will not return a meaningful
|
77
|
+
# state, which means the reporter will likely not report anything.
|
78
|
+
#
|
79
|
+
# @param [Riot::Situation] situation the situation for the current {Riot::Context} run
|
80
|
+
# @return [Array<Symbol>] array containing the evaluation state
|
28
81
|
def run(situation)
|
29
82
|
situation.helper(@name, &definition)
|
30
83
|
[:helper]
|
data/lib/riot/situation.rb
CHANGED
@@ -1,17 +1,62 @@
|
|
1
1
|
module Riot
|
2
|
+
# A {Riot::Situation} is virtually a stack frame for a single context run. The intent is for all blocks to
|
3
|
+
# be evaluated against an instance of a Situation. Given the following superfluous context:
|
4
|
+
#
|
5
|
+
# context "Foo" do # block-1
|
6
|
+
#
|
7
|
+
# setup do # block-2
|
8
|
+
# {:bar => "baz"}
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# asserts "its hash" do # block-3
|
12
|
+
# topic
|
13
|
+
# end.equals do # block-4
|
14
|
+
# {:bar => "baz"}
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# end # Foo
|
18
|
+
#
|
19
|
+
# In this example, block-1 will be evaluated against a {Riot::Context} instance. Whereas block-2, block-3,
|
20
|
+
# and block-4 will all be evaluated against the same Situation instance. Situation instances (situations)
|
21
|
+
# are bound to a single context run; they are not shared across context runs, regardless of their position
|
22
|
+
# in the test tree structure.
|
23
|
+
#
|
24
|
+
# What is gained from doing it this way is:
|
25
|
+
# * variables, methods, etc. set in one situation do not contaminate any others
|
26
|
+
# * variables, methods, etc. defined during a context run do not stick with the context itself
|
27
|
+
# * which means that testing state is independent of the test definitions themselves
|
2
28
|
class Situation
|
29
|
+
|
30
|
+
# Returns the currrently tracked value of +topic+
|
31
|
+
#
|
32
|
+
# @return [Object] whatever the topic is currently set to
|
3
33
|
def topic
|
4
34
|
@_topic
|
5
35
|
end
|
6
36
|
|
37
|
+
# This is where a setup block is actually evaluated and the +topic+ tracked.
|
38
|
+
#
|
39
|
+
# @param [lambda] &block a setup block
|
40
|
+
# @return [Object] the current topic value
|
7
41
|
def setup(&block)
|
8
42
|
@_topic = self.instance_eval(&block)
|
9
43
|
end
|
10
44
|
|
45
|
+
# This is where a defined helper is born. A method is defined against the current instance of +self+.
|
46
|
+
# This method will not be defined on any other instances of Situation created afterwards.
|
47
|
+
#
|
48
|
+
# @param [Symbol, String] name the name of the helper being defined
|
49
|
+
# @param [lambda] &block the code to execute whennever the helper is called
|
11
50
|
def helper(name, &block)
|
12
51
|
(class << self; self; end).send(:define_method, name, &block)
|
13
52
|
end
|
14
53
|
|
54
|
+
# Anonymously evaluates any block given to it against the current instance of +self+. This is how
|
55
|
+
# {Riot::Assertion assertion} and {Riot::AssertionMAcro assertion macro} blocks are evaluated,
|
56
|
+
# for instance.
|
57
|
+
#
|
58
|
+
# @param [lambda] &block the block to evaluate against +self+
|
59
|
+
# @return [Object] whatever the block would have returned
|
15
60
|
def evaluate(&block)
|
16
61
|
self.instance_eval(&block)
|
17
62
|
end
|