riot 0.9.12 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.markdown +37 -45
- data/VERSION +1 -1
- data/lib/riot.rb +27 -18
- data/lib/riot/assertion_macros.rb +63 -53
- data/lib/riot/context.rb +26 -36
- data/lib/riot/reporter.rb +77 -0
- data/lib/riot/runnable.rb +50 -0
- data/lib/riot/situation.rb +6 -3
- data/riot.gemspec +30 -21
- data/test/assertion_macros/assigns_test.rb +24 -0
- data/test/assertion_macros/equals_test.rb +18 -0
- data/test/assertion_macros/exists_test.rb +17 -0
- data/test/assertion_macros/kind_of_test.rb +17 -0
- data/test/assertion_macros/matching_test.rb +12 -0
- data/test/assertion_macros/nil_test.rb +13 -0
- data/test/assertion_macros/raises_test.rb +33 -0
- data/test/assertion_macros/respond_to_test.rb +12 -0
- data/test/assertion_macros/same_elements_test.rb +17 -0
- data/test/assertion_test.rb +25 -22
- data/test/benchmark/riot_vs_minitest.rb +8 -8
- data/test/benchmark/same_elements_vs_set.rb +41 -0
- data/test/benchmark/simple_context_and_assertions.rb +8 -8
- data/test/context_test.rb +68 -83
- data/test/report_test.rb +44 -0
- data/test/setup_test.rb +17 -0
- data/test/situation_test.rb +16 -0
- data/test/teststrap.rb +31 -0
- metadata +30 -21
- data/lib/riot/assertion.rb +0 -37
- data/lib/riot/errors.rb +0 -15
- data/lib/riot/report.rb +0 -82
- data/test/assertion_macros/assertion_macro_assigns_test.rb +0 -40
- data/test/assertion_macros/assertion_macro_equals_test.rb +0 -13
- data/test/assertion_macros/assertion_macro_exists_test.rb +0 -17
- data/test/assertion_macros/assertion_macro_kind_of_test.rb +0 -13
- data/test/assertion_macros/assertion_macro_matching_test.rb +0 -17
- data/test/assertion_macros/assertion_macro_nil_test.rb +0 -13
- data/test/assertion_macros/assertion_macro_raises_test.rb +0 -43
- data/test/assertion_macros/assertion_macro_respond_to_test.rb +0 -16
@@ -0,0 +1,77 @@
|
|
1
|
+
module Riot
|
2
|
+
class Reporter
|
3
|
+
attr_accessor :passes, :failures, :errors
|
4
|
+
def initialize
|
5
|
+
@passes = @failures = @errors = 0
|
6
|
+
end
|
7
|
+
|
8
|
+
def summarize(&block)
|
9
|
+
started = Time.now
|
10
|
+
yield
|
11
|
+
ensure
|
12
|
+
results(Time.now - started)
|
13
|
+
end
|
14
|
+
|
15
|
+
def describe_context(msg); end
|
16
|
+
|
17
|
+
def report(description, response)
|
18
|
+
code, result = *response
|
19
|
+
case code
|
20
|
+
when :pass then
|
21
|
+
@passes += 1
|
22
|
+
pass(description)
|
23
|
+
when :fail then
|
24
|
+
@failures += 1
|
25
|
+
fail(description, result)
|
26
|
+
when :error then
|
27
|
+
@errors += 1
|
28
|
+
error(description, result)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end # Reporter
|
32
|
+
|
33
|
+
class IOReporter < Reporter
|
34
|
+
def initialize(writer=nil)
|
35
|
+
super()
|
36
|
+
@writer = writer || STDOUT
|
37
|
+
end
|
38
|
+
def say(message) @writer.puts(message); end
|
39
|
+
|
40
|
+
def results(time_taken)
|
41
|
+
values = [@passes, @failures, @errors, ("%0.6f" % time_taken)]
|
42
|
+
say "\n%d passes, %d failures, %d errors in %s seconds" % values
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class StoryReporter < IOReporter
|
47
|
+
def describe_context(description) say description; end
|
48
|
+
def pass(description) say " + " + description.green; end
|
49
|
+
def fail(description, message) say " - " + "#{description}: #{message}".yellow; end
|
50
|
+
def error(description, e) say " ! " + "#{description}: #{e.message}".red; end
|
51
|
+
end
|
52
|
+
|
53
|
+
class DotMatrixReporter < IOReporter
|
54
|
+
def pass(description); @writer.write ".".green; end
|
55
|
+
def fail(description, message); @writer.write "F".yellow; end
|
56
|
+
def error(description, e); @writer.write "E".red; end
|
57
|
+
end
|
58
|
+
|
59
|
+
class SilentReporter < Reporter
|
60
|
+
def pass(description); end
|
61
|
+
def fail(description, message); end
|
62
|
+
def error(description, e); end
|
63
|
+
def results(time_taken); end
|
64
|
+
end
|
65
|
+
end # Riot
|
66
|
+
|
67
|
+
begin
|
68
|
+
raise LoadError if ENV["TM_MODE"]
|
69
|
+
require 'rubygems'
|
70
|
+
require 'colorize'
|
71
|
+
rescue LoadError
|
72
|
+
class ::String
|
73
|
+
def green; self; end
|
74
|
+
alias :red :green
|
75
|
+
alias :yellow :green
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Riot
|
2
|
+
class RunnableBlock
|
3
|
+
def initialize(description, &definition)
|
4
|
+
@description, @definition = description, definition
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_s
|
8
|
+
@description
|
9
|
+
end
|
10
|
+
end # RunnableBlock
|
11
|
+
|
12
|
+
class Setup < RunnableBlock
|
13
|
+
def initialize(&definition)
|
14
|
+
super("setup", &definition)
|
15
|
+
end
|
16
|
+
|
17
|
+
def run(situation)
|
18
|
+
situation.setup(&@definition)
|
19
|
+
[:setup]
|
20
|
+
end
|
21
|
+
end # Setup
|
22
|
+
|
23
|
+
class Assertion < RunnableBlock
|
24
|
+
def self.pass() [:pass]; end
|
25
|
+
def self.fail(message) [:fail, message]; end
|
26
|
+
def self.error(e) [:error, e]; end
|
27
|
+
|
28
|
+
def run(situation)
|
29
|
+
process_macro(situation, false) do |actual|
|
30
|
+
actual ? Assertion.pass : Assertion.fail("Expected non-false but got #{actual.inspect} instead")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.assertion(name, expect_exception=false, &assertion_block)
|
35
|
+
define_method(name) do |*expectings|
|
36
|
+
(class << self; self; end).send(:define_method, :run) do |situation|
|
37
|
+
process_macro(situation, expect_exception) { |actual| assertion_block.call(actual, *expectings) }
|
38
|
+
end # redefine run method when the assertion is called
|
39
|
+
self
|
40
|
+
end # define_method for assertion
|
41
|
+
end
|
42
|
+
private
|
43
|
+
def process_macro(situation, expect_exception)
|
44
|
+
actual = situation.evaluate(&@definition)
|
45
|
+
yield(expect_exception ? nil : actual)
|
46
|
+
rescue Exception => e
|
47
|
+
expect_exception ? yield(e) : Assertion.error(e)
|
48
|
+
end
|
49
|
+
end # Assertion
|
50
|
+
end # Riot
|
data/lib/riot/situation.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
module Riot
|
2
2
|
class Situation
|
3
3
|
attr_accessor :topic
|
4
|
+
def setup(&block)
|
5
|
+
@topic = self.instance_eval(&block)
|
6
|
+
end
|
4
7
|
|
5
|
-
def
|
6
|
-
|
8
|
+
def evaluate(&block)
|
9
|
+
self.instance_eval(&block)
|
7
10
|
end
|
8
11
|
end # Situation
|
9
|
-
end # Riot
|
12
|
+
end # Riot
|
data/riot.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{riot}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.10.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Justin 'Gus' Knowlden"]
|
12
|
-
s.date = %q{2009-
|
12
|
+
s.date = %q{2009-11-21}
|
13
13
|
s.description = %q{An extremely fast, expressive, and context-driven unit-testing framework. A replacement for all other testing frameworks. Protest the slow test.}
|
14
14
|
s.email = %q{gus@gusg.us}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -22,25 +22,29 @@ Gem::Specification.new do |s|
|
|
22
22
|
"Rakefile",
|
23
23
|
"VERSION",
|
24
24
|
"lib/riot.rb",
|
25
|
-
"lib/riot/assertion.rb",
|
26
25
|
"lib/riot/assertion_macros.rb",
|
27
26
|
"lib/riot/context.rb",
|
28
|
-
"lib/riot/
|
29
|
-
"lib/riot/
|
27
|
+
"lib/riot/reporter.rb",
|
28
|
+
"lib/riot/runnable.rb",
|
30
29
|
"lib/riot/situation.rb",
|
31
30
|
"riot.gemspec",
|
32
|
-
"test/assertion_macros/
|
33
|
-
"test/assertion_macros/
|
34
|
-
"test/assertion_macros/
|
35
|
-
"test/assertion_macros/
|
36
|
-
"test/assertion_macros/
|
37
|
-
"test/assertion_macros/
|
38
|
-
"test/assertion_macros/
|
39
|
-
"test/assertion_macros/
|
31
|
+
"test/assertion_macros/assigns_test.rb",
|
32
|
+
"test/assertion_macros/equals_test.rb",
|
33
|
+
"test/assertion_macros/exists_test.rb",
|
34
|
+
"test/assertion_macros/kind_of_test.rb",
|
35
|
+
"test/assertion_macros/matching_test.rb",
|
36
|
+
"test/assertion_macros/nil_test.rb",
|
37
|
+
"test/assertion_macros/raises_test.rb",
|
38
|
+
"test/assertion_macros/respond_to_test.rb",
|
39
|
+
"test/assertion_macros/same_elements_test.rb",
|
40
40
|
"test/assertion_test.rb",
|
41
41
|
"test/benchmark/riot_vs_minitest.rb",
|
42
|
+
"test/benchmark/same_elements_vs_set.rb",
|
42
43
|
"test/benchmark/simple_context_and_assertions.rb",
|
43
44
|
"test/context_test.rb",
|
45
|
+
"test/report_test.rb",
|
46
|
+
"test/setup_test.rb",
|
47
|
+
"test/situation_test.rb",
|
44
48
|
"test/teststrap.rb"
|
45
49
|
]
|
46
50
|
s.homepage = %q{http://github.com/thumblemonks/riot}
|
@@ -49,18 +53,23 @@ Gem::Specification.new do |s|
|
|
49
53
|
s.rubygems_version = %q{1.3.5}
|
50
54
|
s.summary = %q{An extremely fast, expressive, and context-driven unit-testing framework. Protest the slow test.}
|
51
55
|
s.test_files = [
|
52
|
-
"test/assertion_macros/
|
53
|
-
"test/assertion_macros/
|
54
|
-
"test/assertion_macros/
|
55
|
-
"test/assertion_macros/
|
56
|
-
"test/assertion_macros/
|
57
|
-
"test/assertion_macros/
|
58
|
-
"test/assertion_macros/
|
59
|
-
"test/assertion_macros/
|
56
|
+
"test/assertion_macros/assigns_test.rb",
|
57
|
+
"test/assertion_macros/equals_test.rb",
|
58
|
+
"test/assertion_macros/exists_test.rb",
|
59
|
+
"test/assertion_macros/kind_of_test.rb",
|
60
|
+
"test/assertion_macros/matching_test.rb",
|
61
|
+
"test/assertion_macros/nil_test.rb",
|
62
|
+
"test/assertion_macros/raises_test.rb",
|
63
|
+
"test/assertion_macros/respond_to_test.rb",
|
64
|
+
"test/assertion_macros/same_elements_test.rb",
|
60
65
|
"test/assertion_test.rb",
|
61
66
|
"test/benchmark/riot_vs_minitest.rb",
|
67
|
+
"test/benchmark/same_elements_vs_set.rb",
|
62
68
|
"test/benchmark/simple_context_and_assertions.rb",
|
63
69
|
"test/context_test.rb",
|
70
|
+
"test/report_test.rb",
|
71
|
+
"test/setup_test.rb",
|
72
|
+
"test/situation_test.rb",
|
64
73
|
"test/teststrap.rb"
|
65
74
|
]
|
66
75
|
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'teststrap'
|
2
|
+
|
3
|
+
context "An assigns assertion macro" do
|
4
|
+
setup do
|
5
|
+
item = Object.new
|
6
|
+
item.instance_eval { @foo = 1; @bar; @nil_val = nil }
|
7
|
+
Riot::Assertion.new("test") { item }
|
8
|
+
end
|
9
|
+
|
10
|
+
assertion_test_passes("when foo is defined") { topic.assigns(:foo) }
|
11
|
+
assertion_test_passes("when foo is defined with expected value") { topic.assigns(:foo, 1) }
|
12
|
+
|
13
|
+
assertion_test_fails("when foo does not match expectation", "expected @foo to be equal to 2, not 1") do
|
14
|
+
topic.assigns(:foo, 2)
|
15
|
+
end
|
16
|
+
|
17
|
+
assertion_test_fails("when bar is not define", "expected @bar to be assigned a value") do
|
18
|
+
topic.assigns(:bar)
|
19
|
+
end
|
20
|
+
|
21
|
+
assertion_test_fails("when var assigned nil value", "expected @nil_val to be assigned a value") do
|
22
|
+
topic.assigns(:nil_val)
|
23
|
+
end
|
24
|
+
end # An assigns assertion macro
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'teststrap'
|
2
|
+
|
3
|
+
context "An equals assertion macro" do
|
4
|
+
setup do
|
5
|
+
Riot::Assertion.new("blue") { "foo" }
|
6
|
+
end
|
7
|
+
|
8
|
+
asserts(":pass when expectation met") do
|
9
|
+
topic.equals("foo").run(Riot::Situation.new) == [:pass]
|
10
|
+
end
|
11
|
+
|
12
|
+
context "that is failing" do
|
13
|
+
setup { topic.equals("bar").run(Riot::Situation.new) }
|
14
|
+
|
15
|
+
asserts(":fail") { topic.first == :fail }
|
16
|
+
asserts("message") { topic.last == %Q{expected "foo" to equal "bar"} }
|
17
|
+
end # that is failing
|
18
|
+
end # An equals assertion macro
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'teststrap'
|
2
|
+
|
3
|
+
context "An exists assertion macro" do
|
4
|
+
setup { Riot::Situation.new }
|
5
|
+
|
6
|
+
asserts(":pass when result has a value") do
|
7
|
+
Riot::Assertion.new("foo") { "foo" }.exists.run(topic)
|
8
|
+
end.equals([:pass])
|
9
|
+
|
10
|
+
asserts(":pass because empty string is considered a value") do
|
11
|
+
Riot::Assertion.new("foo") { "" }.exists.run(topic)
|
12
|
+
end.equals([:pass])
|
13
|
+
|
14
|
+
asserts(":fail with message when value is nil") do
|
15
|
+
Riot::Assertion.new("foo") { nil }.exists.run(topic)
|
16
|
+
end.equals([:fail, "expected a non-nil value"])
|
17
|
+
end # An exists assertion macro
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'teststrap'
|
2
|
+
|
3
|
+
context "A kind_of assertion macro" do
|
4
|
+
setup { Riot::Situation.new }
|
5
|
+
|
6
|
+
asserts ":pass when specific result is a kind of String" do
|
7
|
+
Riot::Assertion.new("foo") { "a" }.kind_of(String).run(topic)
|
8
|
+
end.equals([:pass])
|
9
|
+
|
10
|
+
asserts ":fail when not a kind of String" do
|
11
|
+
Riot::Assertion.new("foo") { 0 }.kind_of(String).run(topic)
|
12
|
+
end.equals([:fail, %Q{expected kind of String, not 0}])
|
13
|
+
|
14
|
+
asserts ":fail when nil" do
|
15
|
+
Riot::Assertion.new("foo") { }.kind_of(String).run(topic)
|
16
|
+
end.equals([:fail, %Q{expected kind of String, not nil}])
|
17
|
+
end # A kind_of assertion macro
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'teststrap'
|
2
|
+
|
3
|
+
context "A matching assertion macro" do
|
4
|
+
setup { Riot::Assertion.new("foo") { "abc" } }
|
5
|
+
|
6
|
+
assertion_test_passes("when expression matches actual") { topic.matches(/abc/) }
|
7
|
+
|
8
|
+
assertion_test_fails("when expression fails to match", "expected /abcd/ to match \"abc\"") do
|
9
|
+
topic.matches(/abcd/)
|
10
|
+
end
|
11
|
+
|
12
|
+
end # A matching assertion macro
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'teststrap'
|
2
|
+
|
3
|
+
context "A nil assertion macro" do
|
4
|
+
setup { Riot::Situation.new }
|
5
|
+
|
6
|
+
asserts(":pass when result is nil") do
|
7
|
+
Riot::Assertion.new("foo") { nil }.nil.run(topic)
|
8
|
+
end.equals([:pass])
|
9
|
+
|
10
|
+
asserts(":fail with message") do
|
11
|
+
Riot::Assertion.new("foo") { "a" }.nil.run(topic)
|
12
|
+
end.equals([:fail, %Q{expected nil, not "a"}])
|
13
|
+
end # A nil assertion macro
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'teststrap'
|
2
|
+
|
3
|
+
class Whoops < Exception; end
|
4
|
+
|
5
|
+
context "A raises assertion macro" do
|
6
|
+
assertion_test_passes("when expected exception is raised") do
|
7
|
+
Riot::Assertion.new("foo") { raise Whoops }.raises(Whoops)
|
8
|
+
end
|
9
|
+
|
10
|
+
assertion_test_fails("when unexpected exception is raised", "should have raised Exception, not Whoops") do
|
11
|
+
Riot::Assertion.new("foo") { raise Whoops }.raises(Exception)
|
12
|
+
end
|
13
|
+
|
14
|
+
assertion_test_fails("when nothing was raised", "should have raised Whoops, but raised nothing") do
|
15
|
+
assertion = Riot::Assertion.new("foo") { "barf" }.raises(Whoops)
|
16
|
+
end
|
17
|
+
|
18
|
+
assertion_test_passes("when provided message equals expected message") do
|
19
|
+
Riot::Assertion.new("foo") { raise Whoops, "Mom" }.raises(Whoops, "Mom")
|
20
|
+
end
|
21
|
+
|
22
|
+
assertion_test_fails("when messages aren't equal", %Q{expected "Mom" for message, not "Dad"}) do
|
23
|
+
Riot::Assertion.new("foo") { raise Whoops, "Dad" }.raises(Whoops, "Mom")
|
24
|
+
end
|
25
|
+
|
26
|
+
assertion_test_passes("when provided message matches expected message") do
|
27
|
+
Riot::Assertion.new("foo") { raise Whoops, "Mom" }.raises(Whoops, /Mom/)
|
28
|
+
end
|
29
|
+
|
30
|
+
assertion_test_fails("when messages don't match", %Q{expected /Mom/ for message, not "Dad"}) do
|
31
|
+
Riot::Assertion.new("foo") { raise Whoops, "Dad" }.raises(Whoops, /Mom/)
|
32
|
+
end
|
33
|
+
end # A raises assertion macro
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'teststrap'
|
2
|
+
|
3
|
+
context "A respond_to assertion macro" do
|
4
|
+
setup { Riot::Assertion.new("foo") { "bar" } }
|
5
|
+
|
6
|
+
assertion_test_passes("when method is defined") { topic.respond_to(:each_byte) }
|
7
|
+
|
8
|
+
assertion_test_fails("when method not defined", "expected method :goofballs is not defined") do
|
9
|
+
topic.respond_to(:goofballs)
|
10
|
+
end
|
11
|
+
|
12
|
+
end # A respond_to assertion macro
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'teststrap'
|
2
|
+
|
3
|
+
context "A same_elements assertion macro" do
|
4
|
+
setup { Riot::Assertion.new("test") { ["foo", "bar", 69] } }
|
5
|
+
|
6
|
+
assertion_test_passes(%Q{when [69, "foo", "bar"] are returned}) do
|
7
|
+
topic.same_elements([69, "foo", "bar"])
|
8
|
+
end
|
9
|
+
|
10
|
+
assertion_test_passes(%Q{when [69, "foo", "bar"] are returned in any order}) do
|
11
|
+
topic.same_elements(["foo", "bar", 69])
|
12
|
+
end
|
13
|
+
|
14
|
+
assertion_test_fails("when elements do not match", %Q{expected elements ["foo", "bar", 96] to match ["foo", "bar", 69]}) do
|
15
|
+
topic.same_elements(["foo", "bar", 96])
|
16
|
+
end
|
17
|
+
end # A same_elements assertion macro
|
data/test/assertion_test.rb
CHANGED
@@ -1,31 +1,34 @@
|
|
1
1
|
require 'teststrap'
|
2
2
|
|
3
|
-
context "
|
4
|
-
|
3
|
+
context "An assertion block" do
|
4
|
+
context "that is passing" do
|
5
|
+
setup { Riot::Assertion.new("foo") { true } }
|
6
|
+
asserts("to_s") { topic.to_s == "foo" }
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
asserts "pass? is true when assertion passed" do
|
11
|
-
Riot::Assertion.new("i will pass", topic) { true }.passed?
|
12
|
-
end
|
8
|
+
asserts(":pass is returned when evaluated") do
|
9
|
+
topic.run(Riot::Situation.new) == [:pass]
|
10
|
+
end
|
11
|
+
end # that is passing
|
13
12
|
|
14
|
-
|
15
|
-
Riot::Assertion.new("
|
16
|
-
|
13
|
+
context "that is failing" do
|
14
|
+
setup { Riot::Assertion.new("foo") { nil } }
|
15
|
+
asserts("to_s") { topic.to_s == "foo" }
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
asserts(":fail and message are evaluated") do
|
18
|
+
topic.run(Riot::Situation.new) == [:fail, "Expected non-false but got nil instead"]
|
19
|
+
end
|
20
|
+
end # that is failing
|
21
21
|
|
22
|
-
context "that
|
22
|
+
context "that is erroring" do
|
23
23
|
setup do
|
24
|
-
|
25
|
-
Riot::Assertion.new("
|
24
|
+
@exception = exception = Exception.new("blah")
|
25
|
+
Riot::Assertion.new("baz") { raise exception }
|
26
26
|
end
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
asserts("to_s") { topic.to_s == "baz" }
|
29
|
+
|
30
|
+
asserts(":error and exception are evaluated") do
|
31
|
+
topic.run(Riot::Situation.new) == [:error, @exception]
|
32
|
+
end
|
33
|
+
end # that is erroring
|
34
|
+
end # An assertion block
|