riot 0.12.3 → 0.12.4
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/CHANGELOG +5 -0
- data/Rakefile +0 -2
- data/lib/riot.rb +32 -12
- data/lib/riot/assertion_macro.rb +4 -3
- data/lib/riot/assertion_macros/raises_kind_of.rb +76 -0
- data/lib/riot/reporter/dot_matrix.rb +2 -2
- data/lib/riot/reporter/io.rb +11 -3
- data/lib/riot/version.rb +1 -1
- data/riot.gemspec +1 -1
- data/test/core/assertion_macros/raises_kind_of_test.rb +89 -0
- data/test/core/reports/basic_reporter_test.rb +66 -0
- data/test/core/reports/dot_matrix_reporter_test.rb +50 -0
- data/test/core/reports/story_reporter_test.rb +61 -0
- data/test/teststrap.rb +1 -0
- metadata +26 -5
- data/test/core/report_test.rb +0 -158
data/CHANGELOG
CHANGED
data/Rakefile
CHANGED
data/lib/riot.rb
CHANGED
@@ -34,42 +34,54 @@ module Riot
|
|
34
34
|
#
|
35
35
|
# @return [Riot::Reporter] the reporter that was used
|
36
36
|
def self.run
|
37
|
-
the_reporter = reporter.new
|
37
|
+
the_reporter = reporter.new(Riot.reporter_options)
|
38
38
|
the_reporter.summarize do
|
39
39
|
root_contexts.each { |ctx| ctx.run(the_reporter) }
|
40
40
|
end unless root_contexts.empty?
|
41
41
|
the_reporter
|
42
42
|
end
|
43
43
|
|
44
|
+
# Options that configure how Riot will run.
|
45
|
+
#
|
46
|
+
# @return [Hash] the options that tell Riot how to run
|
47
|
+
def self.options
|
48
|
+
@options ||= {
|
49
|
+
:silent => false,
|
50
|
+
:alone => false,
|
51
|
+
:reporter => Riot::StoryReporter,
|
52
|
+
:reporter_options => {:plain => false}
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
44
56
|
# This means you don't want to see any output from Riot. A "quiet riot".
|
45
57
|
def self.silently!
|
46
|
-
|
58
|
+
Riot.options[:silent] = true
|
47
59
|
end
|
48
60
|
|
49
61
|
# Reponds to whether Riot is reporting silently.
|
50
62
|
#
|
51
63
|
# @return [Boolean]
|
52
64
|
def self.silently?
|
53
|
-
|
65
|
+
Riot.options[:silent] == true
|
54
66
|
end
|
55
67
|
|
56
68
|
# This means you don't want Riot to run tests for you. You will execute Riot.run manually.
|
57
69
|
def self.alone!
|
58
|
-
|
70
|
+
Riot.options[:alone] = true
|
59
71
|
end
|
60
72
|
|
61
73
|
# Responds to whether Riot will run +at_exit+ (false) or manually (true).
|
62
74
|
#
|
63
75
|
# @return [Boolean]
|
64
76
|
def self.alone?
|
65
|
-
|
77
|
+
Riot.options[:alone] == true
|
66
78
|
end
|
67
79
|
|
68
80
|
# Allows the reporter class to be changed. Do this before tests are started.
|
69
81
|
#
|
70
82
|
# @param [Class] reporter_class the Class that represents a {Riot::Reporter}
|
71
83
|
def self.reporter=(reporter_class)
|
72
|
-
|
84
|
+
Riot.options[:reporter] = reporter_class
|
73
85
|
end
|
74
86
|
|
75
87
|
# Returns the class for the reporter that is currently selected. If no reporter was explicitly selected,
|
@@ -77,11 +89,14 @@ module Riot
|
|
77
89
|
#
|
78
90
|
# @return [Class] the Class that represents a {Riot::Reporter}
|
79
91
|
def self.reporter
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
92
|
+
Riot.silently? ? Riot::SilentReporter : Riot.options[:reporter]
|
93
|
+
end
|
94
|
+
|
95
|
+
# Returns the options that will be passed to the Reporter when it is created.
|
96
|
+
#
|
97
|
+
# @return [Hash] the Hash of current options
|
98
|
+
def self.reporter_options
|
99
|
+
Riot.options[:reporter_options]
|
85
100
|
end
|
86
101
|
|
87
102
|
# @todo make this a flag that DotMatrix and Story respect and cause them to print errors/failures
|
@@ -100,6 +115,11 @@ module Riot
|
|
100
115
|
Riot.reporter = Riot::PrettyDotMatrixReporter
|
101
116
|
end
|
102
117
|
|
118
|
+
# Tells Riot to turn color off in the output
|
119
|
+
def self.plain!
|
120
|
+
Riot.reporter_options[:plain] = true
|
121
|
+
end
|
122
|
+
|
103
123
|
# Making sure to account for Riot being run as part of a larger rake task (or something similar).
|
104
124
|
# If a child process exited with a failing status, probably don't want to run Riot tests; just exit
|
105
125
|
# with the child status.
|
@@ -109,7 +129,6 @@ module Riot
|
|
109
129
|
exit(status || run.success?)
|
110
130
|
end
|
111
131
|
end
|
112
|
-
|
113
132
|
end # Riot
|
114
133
|
|
115
134
|
# A little bit of monkey-patch so we can have +context+ available anywhere.
|
@@ -130,3 +149,4 @@ class Array
|
|
130
149
|
last.is_a?(::Hash) ? pop : {}
|
131
150
|
end
|
132
151
|
end
|
152
|
+
|
data/lib/riot/assertion_macro.rb
CHANGED
@@ -10,7 +10,7 @@ module Riot
|
|
10
10
|
#
|
11
11
|
# asserts(:comments).empty?
|
12
12
|
# denies(:comments).empty?
|
13
|
-
#
|
13
|
+
#
|
14
14
|
# == Writing your own macros
|
15
15
|
#
|
16
16
|
# Macros are added by subclassing {AssertionMacro}. For example, here's
|
@@ -18,7 +18,7 @@ module Riot
|
|
18
18
|
#
|
19
19
|
# class EmptyMacro < AssertionMacro
|
20
20
|
# register :empty
|
21
|
-
#
|
21
|
+
#
|
22
22
|
# def evaluate(actual)
|
23
23
|
# actual.length == 0 ? pass : fail(expected_message(actual).to_be_empty)
|
24
24
|
# end
|
@@ -70,7 +70,7 @@ module Riot
|
|
70
70
|
# @return [Array[Symbol, String]]
|
71
71
|
def pass(message=nil) [:pass, message.to_s]; end
|
72
72
|
|
73
|
-
# Returns a status tuple indicating the assertion failed and where it failed it if that can be
|
73
|
+
# Returns a status tuple indicating the assertion failed and where it failed it if that can be
|
74
74
|
# determined.
|
75
75
|
#
|
76
76
|
# @param [String] message the message to report with
|
@@ -136,6 +136,7 @@ require 'riot/assertion_macros/matches'
|
|
136
136
|
require 'riot/assertion_macros/nil'
|
137
137
|
require 'riot/assertion_macros/not_borat'
|
138
138
|
require 'riot/assertion_macros/raises'
|
139
|
+
require 'riot/assertion_macros/raises_kind_of'
|
139
140
|
require 'riot/assertion_macros/respond_to'
|
140
141
|
require 'riot/assertion_macros/same_elements'
|
141
142
|
require 'riot/assertion_macros/size'
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Riot
|
2
|
+
# Asserts that the test raises the expected exception, or one of its
|
3
|
+
# subclasses. Thus, the following assertions pass:
|
4
|
+
# asserts("test") { raise My::Exception }.raises(My::Exception)
|
5
|
+
# should("test") { raise My::Exception }.raises(My::Exception.superclass)
|
6
|
+
# The following, however, fails:
|
7
|
+
# asserts("test") { raise My::Exception.superclass }.raises(My::Exception)
|
8
|
+
#
|
9
|
+
# You can also check to see if the provided message equals or matches your
|
10
|
+
# expectations. The message from the actual raised exception will be converted
|
11
|
+
# to a string before any comparison is executed.
|
12
|
+
# asserts("test") { raise My::Exception, "Foo" }.raises(My::Exception, "Foo")
|
13
|
+
# asserts("test") { raise My::Exception, "Foo Bar" }.raises(My::Exception, /Bar/)
|
14
|
+
#
|
15
|
+
# You can use the negative form to assert that no exception is raised at all:
|
16
|
+
# denies("test") {
|
17
|
+
# # do stuff
|
18
|
+
# }.raises_kind_of Exception
|
19
|
+
#
|
20
|
+
# It can be used to check that a particular class of exception is not raised,
|
21
|
+
# in which case you should be aware that raising another kind of exception
|
22
|
+
# will *not* produce a failure.
|
23
|
+
# denies("test") { raises ArgumentError }.raises_kind_of ArgumentError # fails
|
24
|
+
# denies("test") { raises Class.new(ArgumentError) }.raises_kind_of ArgumentError # fails
|
25
|
+
# denies("test") { raises "this doesn't work" }.raises_kind_of ArgumentError # passes
|
26
|
+
class RaisesKindOfMacro < AssertionMacro
|
27
|
+
register :raises_kind_of
|
28
|
+
expects_exception!
|
29
|
+
|
30
|
+
# (see Riot::AssertionMacro#evaluate)
|
31
|
+
# @param [Class] expected_class the expected Exception class
|
32
|
+
# @param [String, nil] expected_message an optional exception message or message partial
|
33
|
+
def evaluate(actual_exception, expected_class, expected_message=nil)
|
34
|
+
actual_message = actual_exception && actual_exception.message
|
35
|
+
|
36
|
+
if !actual_exception
|
37
|
+
fail new_message.expected_to_raise_kind_of(expected_class).but.raised_nothing
|
38
|
+
elsif !actual_exception.is_a?(expected_class)
|
39
|
+
fail new_message.expected_to_raise_kind_of(expected_class).not(actual_exception.class)
|
40
|
+
elsif expected_message && !(actual_message.to_s =~ %r[#{expected_message}])
|
41
|
+
fail expected_message(expected_message).for_message.not(actual_message)
|
42
|
+
else
|
43
|
+
message = new_message.raises_kind_of(expected_class)
|
44
|
+
pass(expected_message ? message.with_message(expected_message) : message)
|
45
|
+
end
|
46
|
+
end # evaluate
|
47
|
+
|
48
|
+
# (see Riot::AssertionMacro#devaluate)
|
49
|
+
# @param [Class] expected_class the unexpected Exception class
|
50
|
+
# @param [String, nil] expected_message an optional exception message or message partial
|
51
|
+
def devaluate(actual_exception, expected_class, expected_message=nil)
|
52
|
+
actual_message = actual_exception && actual_exception.message
|
53
|
+
|
54
|
+
if !actual_exception
|
55
|
+
pass new_message.raises_kind_of(expected_class)
|
56
|
+
elsif !actual_exception.is_a?(expected_class)
|
57
|
+
if expected_message && !(actual_message.to_s =~ %r[#{expected_message}])
|
58
|
+
pass new_message.raises_kind_of(expected_class).
|
59
|
+
with_message(expected_message)
|
60
|
+
else
|
61
|
+
pass new_message.raises_kind_of(expected_class)
|
62
|
+
end
|
63
|
+
else
|
64
|
+
message = new_message.expected_to_not_raise_kind_of(expected_class)
|
65
|
+
|
66
|
+
if expected_message
|
67
|
+
fail message.with_message(expected_message).but.
|
68
|
+
raised(actual_exception.class).
|
69
|
+
with_message(actual_exception.message)
|
70
|
+
else
|
71
|
+
fail message
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end # devaluate
|
75
|
+
end # RaisesMacro
|
76
|
+
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module Riot
|
2
2
|
|
3
|
-
# Outputs in the dot-notion almost everyone should be familiar with, "." implies pass, "F"
|
3
|
+
# Outputs in the dot-notion almost everyone should be familiar with, "." implies pass, "F" implies a
|
4
4
|
# failure, and "E" implies an error. If ansi-coloring is available, it is used. Error and failure messages
|
5
5
|
# are buffered for output until the end.
|
6
6
|
class DotMatrixReporter < IOReporter
|
7
7
|
# Creates a new DotMatrixReporter and initializes the failure/error details buffer.
|
8
8
|
# @param (see Riot::IOReporter#initialize)
|
9
|
-
def initialize(
|
9
|
+
def initialize(*args)
|
10
10
|
super
|
11
11
|
@details = []
|
12
12
|
end
|
data/lib/riot/reporter/io.rb
CHANGED
@@ -6,12 +6,16 @@ module Riot
|
|
6
6
|
# This is an abstract class. You should use some other or define your own sub-class that knows how to
|
7
7
|
# handle +pass+, +fail+, and +error+.
|
8
8
|
class IOReporter < Reporter
|
9
|
+
|
9
10
|
# Creates a new IOReporter. You can give it your own IO writer or it will default to +STDOUT+.
|
11
|
+
# If you want to specifically turn colorization off in the output, pass the +plain+ option.
|
10
12
|
#
|
11
13
|
# @param [IO] writer the writer to use for results
|
12
|
-
|
14
|
+
# @param [Hash] options options for reporter
|
15
|
+
def initialize(*args)
|
13
16
|
super()
|
14
|
-
@
|
17
|
+
@options = (args.last.kind_of?(Hash) ? args.pop : {})
|
18
|
+
@writer = (args.shift || STDOUT)
|
15
19
|
end
|
16
20
|
|
17
21
|
# (see Riot::Reporter#results)
|
@@ -75,10 +79,14 @@ module Riot
|
|
75
79
|
def yellow(str); with_color(33, str); end
|
76
80
|
def green(str); with_color(32, str); end
|
77
81
|
|
82
|
+
def plain?
|
83
|
+
(@options[:plain] || @options["plain"])
|
84
|
+
end
|
85
|
+
|
78
86
|
# for color reference:
|
79
87
|
# http://www.pixelbeat.org/docs/terminal_colours/
|
80
88
|
def with_color(code,str)
|
81
|
-
"\e[#{code}m#{str}\e[0m"
|
89
|
+
plain? ? str : "\e[#{code}m#{str}\e[0m"
|
82
90
|
end
|
83
91
|
end # IOReporter
|
84
92
|
|
data/lib/riot/version.rb
CHANGED
data/riot.gemspec
CHANGED
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'teststrap'
|
2
|
+
|
3
|
+
class Whoops < Exception; end
|
4
|
+
class SubWhoops < Whoops; end
|
5
|
+
|
6
|
+
context "A raises_kind_of assertion macro" do
|
7
|
+
helper(:asserts_raises) { |o| Riot::Assertion.new("foo") { raise Whoops, o } }
|
8
|
+
|
9
|
+
assertion_test_passes("when expected exception is raised",
|
10
|
+
"raises kind of Whoops") do
|
11
|
+
asserts_raises(nil).raises_kind_of(Whoops)
|
12
|
+
end
|
13
|
+
|
14
|
+
assertion_test_fails("when a superclass of the expected exception is raised",
|
15
|
+
"expected to raise kind of SubWhoops, not Whoops") do
|
16
|
+
asserts_raises(nil).raises_kind_of(SubWhoops)
|
17
|
+
end
|
18
|
+
|
19
|
+
assertion_test_passes("when a subclass of the expected exception is raised",
|
20
|
+
"raises kind of Exception") do
|
21
|
+
asserts_raises(nil).raises_kind_of(Exception)
|
22
|
+
end
|
23
|
+
|
24
|
+
assertion_test_fails("when nothing was raised",
|
25
|
+
"expected to raise kind of Whoops, but raised nothing") do
|
26
|
+
assertion = Riot::Assertion.new("foo") { "barf" }.raises_kind_of(Whoops)
|
27
|
+
end
|
28
|
+
|
29
|
+
assertion_test_passes("when provided message equals expected message",
|
30
|
+
%Q{raises kind of Whoops with message "Mom"}) do
|
31
|
+
asserts_raises('Mom').raises_kind_of(Whoops, 'Mom')
|
32
|
+
end
|
33
|
+
|
34
|
+
assertion_test_fails("when messages aren't equal",
|
35
|
+
%Q{expected "Mom" for message, not "Dad"}) do
|
36
|
+
asserts_raises('Dad').raises_kind_of(Whoops, 'Mom')
|
37
|
+
end
|
38
|
+
|
39
|
+
assertion_test_passes("when provided message matches expected message",
|
40
|
+
%Q{raises kind of Whoops with message /Mom/}) do
|
41
|
+
asserts_raises('Mom').raises_kind_of(Whoops, /Mom/)
|
42
|
+
end
|
43
|
+
|
44
|
+
assertion_test_fails("when messages don't match",
|
45
|
+
%Q{expected /Mom/ for message, not "Dad"}) do
|
46
|
+
asserts_raises('Dad').raises_kind_of(Whoops, /Mom/)
|
47
|
+
end
|
48
|
+
end # A raises_kind_of assertion macro
|
49
|
+
|
50
|
+
context "A negative raises_kind_of assertion macro" do
|
51
|
+
helper(:deny_raises) { |o| Riot::Assertion.new("foo", true) { raise Whoops, o } }
|
52
|
+
|
53
|
+
assertion_test_fails("when expected exception is raised",
|
54
|
+
"expected to not raise kind of Whoops") do
|
55
|
+
deny_raises(nil).raises_kind_of(Whoops)
|
56
|
+
end
|
57
|
+
|
58
|
+
assertion_test_fails("when a subclass of the expected exception is raised",
|
59
|
+
"expected to not raise kind of Whoops") do
|
60
|
+
Riot::Assertion.new("foo", true) { raise SubWhoops }.raises_kind_of(Whoops)
|
61
|
+
end
|
62
|
+
|
63
|
+
assertion_test_passes("when unexpected exception is raised",
|
64
|
+
"raises kind of SubWhoops") do
|
65
|
+
deny_raises(nil).raises_kind_of(SubWhoops)
|
66
|
+
end
|
67
|
+
|
68
|
+
assertion_test_passes("when nothing was raised", "raises kind of Whoops") do
|
69
|
+
Riot::Assertion.new("foo", true) { "barf" }.raises_kind_of(Whoops)
|
70
|
+
end
|
71
|
+
|
72
|
+
assertion_test_fails("when provided message equals expected message",
|
73
|
+
'expected to not raise kind of Whoops with message "Mom", but raised Whoops with message "Mom"') do
|
74
|
+
deny_raises('Mom').raises_kind_of(Whoops, 'Mom')
|
75
|
+
end
|
76
|
+
|
77
|
+
assertion_test_passes("when messages and exception aren't equal",
|
78
|
+
'raises kind of ArgumentError with message "Dad"') do
|
79
|
+
deny_raises('Mom').raises_kind_of(ArgumentError, 'Dad')
|
80
|
+
end
|
81
|
+
|
82
|
+
assertion_test_fails("when provided message matches expected message", 'expected to not raise kind of Whoops with message /Mom/, but raised Whoops with message "Mom"') do
|
83
|
+
deny_raises('Mom').raises_kind_of(Whoops, /Mom/)
|
84
|
+
end
|
85
|
+
|
86
|
+
assertion_test_fails("when messages don't match", "expected to not raise kind of Whoops with message /Mom/, but raised Whoops with message \"Dad\"") do
|
87
|
+
deny_raises('Dad').raises_kind_of(Whoops, /Mom/)
|
88
|
+
end
|
89
|
+
end # A raises_kind_of assertion macro
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'teststrap'
|
2
|
+
|
3
|
+
context "A reporter" do
|
4
|
+
setup do
|
5
|
+
Class.new(Riot::Reporter) do
|
6
|
+
def pass(d, message) "passed(#{d}, #{message.inspect})"; end
|
7
|
+
def fail(d, message, line, file) "failed(#{d}, #{message} on line #{line} in file #{file})"; end
|
8
|
+
def error(d, e) "errored(#{d}, #{e})"; end
|
9
|
+
def results(time); end
|
10
|
+
end.new
|
11
|
+
end
|
12
|
+
|
13
|
+
# pass
|
14
|
+
|
15
|
+
asserts("pass count increase when :pass sent to #report") do
|
16
|
+
topic.report("", [:pass])
|
17
|
+
topic.passes
|
18
|
+
end.equals(1)
|
19
|
+
|
20
|
+
asserts("description sent to #pass") do
|
21
|
+
topic.report("hi mom", [:pass])
|
22
|
+
end.equals("passed(hi mom, nil)")
|
23
|
+
|
24
|
+
# fail
|
25
|
+
|
26
|
+
asserts("fail count increase when :fail sent to #report") do
|
27
|
+
topic.report("", [:fail, ""])
|
28
|
+
topic.failures
|
29
|
+
end.equals(1)
|
30
|
+
|
31
|
+
asserts("description, message, line and file sent to #fail") do
|
32
|
+
topic.report("hi mom", [:fail, "how are you", 4, "foo"])
|
33
|
+
end.equals("failed(hi mom, how are you on line 4 in file foo)")
|
34
|
+
|
35
|
+
# error
|
36
|
+
|
37
|
+
asserts("error count increase when :error sent to #report") do
|
38
|
+
topic.report("", [:error, ""])
|
39
|
+
topic.errors
|
40
|
+
end.equals(1)
|
41
|
+
|
42
|
+
asserts("description sent to #error") do
|
43
|
+
topic.report("break it down", [:error, "error time"])
|
44
|
+
end.equals("errored(break it down, error time)")
|
45
|
+
|
46
|
+
context "instance" do
|
47
|
+
setup { Riot::Reporter.new }
|
48
|
+
should("return self invoking new") { topic.new }.equals { topic }
|
49
|
+
end
|
50
|
+
|
51
|
+
context "with no errors or failures" do
|
52
|
+
hookup { topic.report("foo", [:pass, nil]) }
|
53
|
+
asserts(:success?)
|
54
|
+
end
|
55
|
+
|
56
|
+
context "with failures and no errors" do
|
57
|
+
hookup { topic.report("foo", [:fail, "blah"]) }
|
58
|
+
asserts(:success?).equals(false)
|
59
|
+
end
|
60
|
+
|
61
|
+
context "with errors and no failures" do
|
62
|
+
hookup { topic.report("foo", [:error, Exception.new("boogers")]) }
|
63
|
+
asserts(:success?).equals(false)
|
64
|
+
end
|
65
|
+
end # A reporter
|
66
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'teststrap'
|
2
|
+
|
3
|
+
context "DotMatrixReporter" do
|
4
|
+
setup do
|
5
|
+
@out = StringIO.new
|
6
|
+
Riot::DotMatrixReporter.new(@out)
|
7
|
+
end
|
8
|
+
|
9
|
+
context "with a passing test" do
|
10
|
+
setup do
|
11
|
+
context = Riot::Context.new('whatever') do
|
12
|
+
asserts('true') { true }
|
13
|
+
end
|
14
|
+
context.run(topic)
|
15
|
+
@out.string
|
16
|
+
end
|
17
|
+
asserts_topic('puts a dot').matches('.')
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'with a failing test' do
|
21
|
+
setup do
|
22
|
+
Riot::Context.new('whatever') do
|
23
|
+
asserts('nope!') { false }
|
24
|
+
end.run(topic)
|
25
|
+
topic.results(100)
|
26
|
+
@out.string
|
27
|
+
end
|
28
|
+
|
29
|
+
asserts_topic('puts an F').matches('F')
|
30
|
+
asserts_topic("puts the full context + assertion name").matches('whatever asserts nope!')
|
31
|
+
asserts_topic("puts the failure reason").matches(/Expected .* but got false instead/)
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with an error test' do
|
35
|
+
setup do
|
36
|
+
Riot::Context.new('whatever') do
|
37
|
+
asserts('bang') { raise "BOOM" }
|
38
|
+
end.run(topic)
|
39
|
+
topic.results(100)
|
40
|
+
@out.string
|
41
|
+
end
|
42
|
+
|
43
|
+
asserts_topic('puts an E').matches('E')
|
44
|
+
asserts_topic('puts the full context + assertion name').matches('whatever asserts bang')
|
45
|
+
asserts_topic('puts the exception message').matches('BOOM')
|
46
|
+
# <file path>:<one or more number><two newlines><anything till end of line><newline> is the last thing in the stack trace
|
47
|
+
asserts_topic('puts the filtered exception backtrace').matches(/#{__FILE__}:\d+:[^\n]*\n\n.*$\n\z/)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'teststrap'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
context "StoryReporter" do
|
5
|
+
setup do
|
6
|
+
@out = StringIO.new
|
7
|
+
Riot::StoryReporter.new(@out)
|
8
|
+
end
|
9
|
+
|
10
|
+
asserts("success message is stripped if nil") do
|
11
|
+
topic.pass("foo", nil)
|
12
|
+
@out.string
|
13
|
+
end.matches(/\+ \e\[32mfoo\e\[0m\n/)
|
14
|
+
|
15
|
+
asserts("failure message excludes line info if none provided") do
|
16
|
+
@out.rewind
|
17
|
+
topic.fail("foo", "bar", nil, nil)
|
18
|
+
@out.string
|
19
|
+
end.matches(/\- \e\[33mfoo: bar\e\[0m\n/)
|
20
|
+
|
21
|
+
context 'reporting on an empty context' do
|
22
|
+
setup do
|
23
|
+
context = Riot::Context.new('empty context') do
|
24
|
+
context("a nested empty context") {}
|
25
|
+
end
|
26
|
+
context.run(topic)
|
27
|
+
end
|
28
|
+
should("not output context name") { @out.string }.empty
|
29
|
+
end
|
30
|
+
|
31
|
+
context "reporting on a non-empty context" do
|
32
|
+
setup do
|
33
|
+
context = Riot::Context.new('supercontext') do
|
34
|
+
asserts("truth") { true }
|
35
|
+
end
|
36
|
+
context.run(topic)
|
37
|
+
end
|
38
|
+
|
39
|
+
should('output context name') { @out.string }.matches(/supercontext/)
|
40
|
+
should('output name of passed assertion') { @out.string }.matches(/truth/)
|
41
|
+
end
|
42
|
+
end # StoryReporter
|
43
|
+
|
44
|
+
context "Plain StoryReporter" do
|
45
|
+
setup do
|
46
|
+
@out = StringIO.new
|
47
|
+
Riot::StoryReporter.new(@out, {"plain" => true})
|
48
|
+
end
|
49
|
+
|
50
|
+
asserts("success message is stripped if nil") do
|
51
|
+
topic.pass("foo", nil)
|
52
|
+
@out.string
|
53
|
+
end.matches(/\+ foo\n/)
|
54
|
+
|
55
|
+
asserts("failure message excludes line info if none provided") do
|
56
|
+
@out.rewind
|
57
|
+
topic.fail("foo", "bar", nil, nil)
|
58
|
+
@out.string
|
59
|
+
end.matches(/\- foo: bar\n/)
|
60
|
+
end # Plain StoryReporter
|
61
|
+
|
data/test/teststrap.rb
CHANGED
metadata
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: riot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 39
|
4
5
|
prerelease:
|
5
|
-
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 12
|
9
|
+
- 4
|
10
|
+
version: 0.12.4
|
6
11
|
platform: ruby
|
7
12
|
authors:
|
8
13
|
- Justin 'Gus' Knowlden
|
@@ -10,7 +15,7 @@ autorequire:
|
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
17
|
|
13
|
-
date: 2011-
|
18
|
+
date: 2011-05-28 00:00:00 -05:00
|
14
19
|
default_executable:
|
15
20
|
dependencies:
|
16
21
|
- !ruby/object:Gem::Dependency
|
@@ -21,6 +26,9 @@ dependencies:
|
|
21
26
|
requirements:
|
22
27
|
- - ">="
|
23
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
24
32
|
version: "0"
|
25
33
|
type: :runtime
|
26
34
|
version_requirements: *id001
|
@@ -55,6 +63,7 @@ files:
|
|
55
63
|
- lib/riot/assertion_macros/nil.rb
|
56
64
|
- lib/riot/assertion_macros/not_borat.rb
|
57
65
|
- lib/riot/assertion_macros/raises.rb
|
66
|
+
- lib/riot/assertion_macros/raises_kind_of.rb
|
58
67
|
- lib/riot/assertion_macros/respond_to.rb
|
59
68
|
- lib/riot/assertion_macros/same_elements.rb
|
60
69
|
- lib/riot/assertion_macros/size.rb
|
@@ -89,6 +98,7 @@ files:
|
|
89
98
|
- test/core/assertion_macros/matches_test.rb
|
90
99
|
- test/core/assertion_macros/nil_test.rb
|
91
100
|
- test/core/assertion_macros/not_borat_test.rb
|
101
|
+
- test/core/assertion_macros/raises_kind_of_test.rb
|
92
102
|
- test/core/assertion_macros/raises_test.rb
|
93
103
|
- test/core/assertion_macros/respond_to_test.rb
|
94
104
|
- test/core/assertion_macros/same_elements_test.rb
|
@@ -107,7 +117,9 @@ files:
|
|
107
117
|
- test/core/context/using_describe_in_a_test.rb
|
108
118
|
- test/core/middleware/chained_context_middleware_test.rb
|
109
119
|
- test/core/middleware/context_middleware_test.rb
|
110
|
-
- test/core/
|
120
|
+
- test/core/reports/basic_reporter_test.rb
|
121
|
+
- test/core/reports/dot_matrix_reporter_test.rb
|
122
|
+
- test/core/reports/story_reporter_test.rb
|
111
123
|
- test/core/runnable/assertion_macro_test.rb
|
112
124
|
- test/core/runnable/assertion_test.rb
|
113
125
|
- test/core/runnable/message_test.rb
|
@@ -131,17 +143,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
131
143
|
requirements:
|
132
144
|
- - ">="
|
133
145
|
- !ruby/object:Gem::Version
|
146
|
+
hash: 3
|
147
|
+
segments:
|
148
|
+
- 0
|
134
149
|
version: "0"
|
135
150
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
151
|
none: false
|
137
152
|
requirements:
|
138
153
|
- - ">="
|
139
154
|
- !ruby/object:Gem::Version
|
155
|
+
hash: 3
|
156
|
+
segments:
|
157
|
+
- 0
|
140
158
|
version: "0"
|
141
159
|
requirements: []
|
142
160
|
|
143
161
|
rubyforge_project:
|
144
|
-
rubygems_version: 1.
|
162
|
+
rubygems_version: 1.6.2
|
145
163
|
signing_key:
|
146
164
|
specification_version: 3
|
147
165
|
summary: An extremely fast, expressive, and context-driven unit-testing framework. Protest the slow test.
|
@@ -161,6 +179,7 @@ test_files:
|
|
161
179
|
- test/core/assertion_macros/matches_test.rb
|
162
180
|
- test/core/assertion_macros/nil_test.rb
|
163
181
|
- test/core/assertion_macros/not_borat_test.rb
|
182
|
+
- test/core/assertion_macros/raises_kind_of_test.rb
|
164
183
|
- test/core/assertion_macros/raises_test.rb
|
165
184
|
- test/core/assertion_macros/respond_to_test.rb
|
166
185
|
- test/core/assertion_macros/same_elements_test.rb
|
@@ -179,7 +198,9 @@ test_files:
|
|
179
198
|
- test/core/context/using_describe_in_a_test.rb
|
180
199
|
- test/core/middleware/chained_context_middleware_test.rb
|
181
200
|
- test/core/middleware/context_middleware_test.rb
|
182
|
-
- test/core/
|
201
|
+
- test/core/reports/basic_reporter_test.rb
|
202
|
+
- test/core/reports/dot_matrix_reporter_test.rb
|
203
|
+
- test/core/reports/story_reporter_test.rb
|
183
204
|
- test/core/runnable/assertion_macro_test.rb
|
184
205
|
- test/core/runnable/assertion_test.rb
|
185
206
|
- test/core/runnable/message_test.rb
|
data/test/core/report_test.rb
DELETED
@@ -1,158 +0,0 @@
|
|
1
|
-
require 'teststrap'
|
2
|
-
|
3
|
-
context "A reporter" do
|
4
|
-
setup do
|
5
|
-
Class.new(Riot::Reporter) do
|
6
|
-
def pass(d, message) "passed(#{d}, #{message.inspect})"; end
|
7
|
-
def fail(d, message, line, file) "failed(#{d}, #{message} on line #{line} in file #{file})"; end
|
8
|
-
def error(d, e) "errored(#{d}, #{e})"; end
|
9
|
-
def results(time); end
|
10
|
-
end.new
|
11
|
-
end
|
12
|
-
|
13
|
-
# pass
|
14
|
-
|
15
|
-
asserts("pass count increase when :pass sent to #report") do
|
16
|
-
topic.report("", [:pass])
|
17
|
-
topic.passes
|
18
|
-
end.equals(1)
|
19
|
-
|
20
|
-
asserts("description sent to #pass") do
|
21
|
-
topic.report("hi mom", [:pass])
|
22
|
-
end.equals("passed(hi mom, nil)")
|
23
|
-
|
24
|
-
# fail
|
25
|
-
|
26
|
-
asserts("fail count increase when :fail sent to #report") do
|
27
|
-
topic.report("", [:fail, ""])
|
28
|
-
topic.failures
|
29
|
-
end.equals(1)
|
30
|
-
|
31
|
-
asserts("description, message, line and file sent to #fail") do
|
32
|
-
topic.report("hi mom", [:fail, "how are you", 4, "foo"])
|
33
|
-
end.equals("failed(hi mom, how are you on line 4 in file foo)")
|
34
|
-
|
35
|
-
# error
|
36
|
-
|
37
|
-
asserts("error count increase when :error sent to #report") do
|
38
|
-
topic.report("", [:error, ""])
|
39
|
-
topic.errors
|
40
|
-
end.equals(1)
|
41
|
-
|
42
|
-
asserts("description sent to #error") do
|
43
|
-
topic.report("break it down", [:error, "error time"])
|
44
|
-
end.equals("errored(break it down, error time)")
|
45
|
-
|
46
|
-
context "instance" do
|
47
|
-
setup { Riot::Reporter.new }
|
48
|
-
should("return self invoking new") { topic.new }.equals { topic }
|
49
|
-
end
|
50
|
-
|
51
|
-
context "with no errors or failures" do
|
52
|
-
hookup { topic.report("foo", [:pass, nil]) }
|
53
|
-
asserts(:success?)
|
54
|
-
end
|
55
|
-
|
56
|
-
context "with failures and no errors" do
|
57
|
-
hookup { topic.report("foo", [:fail, "blah"]) }
|
58
|
-
asserts(:success?).equals(false)
|
59
|
-
end
|
60
|
-
|
61
|
-
context "with errors and no failures" do
|
62
|
-
hookup { topic.report("foo", [:error, Exception.new("boogers")]) }
|
63
|
-
asserts(:success?).equals(false)
|
64
|
-
end
|
65
|
-
end # A reporter
|
66
|
-
|
67
|
-
require 'stringio'
|
68
|
-
context "StoryReporter" do
|
69
|
-
setup do
|
70
|
-
@out = StringIO.new
|
71
|
-
Riot::StoryReporter.new(@out)
|
72
|
-
end
|
73
|
-
|
74
|
-
asserts("success message is stripped if nil") do
|
75
|
-
topic.pass("foo", nil)
|
76
|
-
@out.string
|
77
|
-
# ColorHelper.uncolored(@out.string)
|
78
|
-
end.matches(/\+ \e\[32mfoo\e\[0m\n/)
|
79
|
-
# end.equals(" + foo\n")
|
80
|
-
|
81
|
-
asserts("failure message excludes line info if none provided") do
|
82
|
-
@out.rewind
|
83
|
-
topic.fail("foo", "bar", nil, nil)
|
84
|
-
@out.string
|
85
|
-
# ColorHelper.uncolored(@out.string)
|
86
|
-
end.matches(/\- \e\[33mfoo: bar\e\[0m\n/)
|
87
|
-
# end.equals(" - foo: bar\n")
|
88
|
-
|
89
|
-
context 'reporting on an empty context' do
|
90
|
-
setup do
|
91
|
-
context = Riot::Context.new('empty context') do
|
92
|
-
context("a nested empty context") {}
|
93
|
-
end
|
94
|
-
context.run(topic)
|
95
|
-
end
|
96
|
-
should("not output context name") { @out.string }.empty
|
97
|
-
end
|
98
|
-
|
99
|
-
context "reporting on a non-empty context" do
|
100
|
-
setup do
|
101
|
-
context = Riot::Context.new('supercontext') do
|
102
|
-
asserts("truth") { true }
|
103
|
-
end
|
104
|
-
context.run(topic)
|
105
|
-
end
|
106
|
-
|
107
|
-
should('output context name') { @out.string }.matches(/supercontext/)
|
108
|
-
should('output name of passed assertion') { @out.string }.matches(/truth/)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
context "DotMatrixReporter" do
|
113
|
-
setup do
|
114
|
-
@out = StringIO.new
|
115
|
-
Riot::DotMatrixReporter.new(@out)
|
116
|
-
end
|
117
|
-
|
118
|
-
context "with a passing test" do
|
119
|
-
setup do
|
120
|
-
context = Riot::Context.new('whatever') do
|
121
|
-
asserts('true') { true }
|
122
|
-
end
|
123
|
-
context.run(topic)
|
124
|
-
@out.string
|
125
|
-
end
|
126
|
-
asserts_topic('puts a dot').matches('.')
|
127
|
-
end
|
128
|
-
|
129
|
-
context 'with a failing test' do
|
130
|
-
setup do
|
131
|
-
Riot::Context.new('whatever') do
|
132
|
-
asserts('nope!') { false }
|
133
|
-
end.run(topic)
|
134
|
-
topic.results(100)
|
135
|
-
@out.string
|
136
|
-
end
|
137
|
-
|
138
|
-
asserts_topic('puts an F').matches('F')
|
139
|
-
asserts_topic("puts the full context + assertion name").matches('whatever asserts nope!')
|
140
|
-
asserts_topic("puts the failure reason").matches(/Expected .* but got false instead/)
|
141
|
-
end
|
142
|
-
|
143
|
-
context 'with an error test' do
|
144
|
-
setup do
|
145
|
-
Riot::Context.new('whatever') do
|
146
|
-
asserts('bang') { raise "BOOM" }
|
147
|
-
end.run(topic)
|
148
|
-
topic.results(100)
|
149
|
-
@out.string
|
150
|
-
end
|
151
|
-
|
152
|
-
asserts_topic('puts an E').matches('E')
|
153
|
-
asserts_topic('puts the full context + assertion name').matches('whatever asserts bang')
|
154
|
-
asserts_topic('puts the exception message').matches('BOOM')
|
155
|
-
# <file path>:<one or more number><two newlines><anything till end of line><newline> is the last thing in the stack trace
|
156
|
-
asserts_topic('puts the filtered exception backtrace').matches(/#{__FILE__}:\d+:[^\n]*\n\n.*$\n\z/)
|
157
|
-
end
|
158
|
-
end
|