riot 0.10.2 → 0.10.3
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/README.markdown +13 -0
- data/Rakefile +5 -4
- data/TODO.markdown +3 -0
- data/VERSION +1 -1
- data/lib/riot.rb +11 -4
- data/lib/riot/assertion.rb +45 -0
- data/lib/riot/assertion_macros.rb +2 -1
- data/lib/riot/reporter.rb +19 -12
- data/lib/riot/runnable.rb +4 -34
- data/riot.gemspec +8 -5
- data/test/assertion_macros/assigns_test.rb +1 -1
- data/test/assertion_test.rb +9 -3
- data/test/benchmark/colorize.rb +39 -0
- data/test/benchmark/riot_vs_minitest.rb +1 -1
- data/test/report_test.rb +6 -0
- metadata +6 -3
data/README.markdown
CHANGED
@@ -17,6 +17,7 @@ An extremely fast, expressive, and context-driven unit-testing framework. Protes
|
|
17
17
|
- [Respond To](#examples-respond-to)
|
18
18
|
- [Assigns](#examples-assigns)
|
19
19
|
- [Nested contexts](#examples-nested)
|
20
|
+
- [Block expectations](#examples-block)
|
20
21
|
- [OMG! Why did you write this](#omg)
|
21
22
|
- [Running tests](#running)
|
22
23
|
- [With Sinatra](#sinatra)
|
@@ -297,6 +298,18 @@ Oh yeah, Riot does those, too. The `setup` from each parent is "loaded" into the
|
|
297
298
|
end
|
298
299
|
end
|
299
300
|
|
301
|
+
<a name="examples-block"></a>
|
302
|
+
#### Example: Block expectations
|
303
|
+
|
304
|
+
You can use a block to create the expected value for your assertion,
|
305
|
+
which might come in useful if it takes a bit of work to generate your
|
306
|
+
expected value. My apologies for the incredibly contrived example as so:
|
307
|
+
|
308
|
+
context "block expectations" do
|
309
|
+
setup { 2 }
|
310
|
+
asserts_topic.equals { 1 + 1 }
|
311
|
+
end
|
312
|
+
|
300
313
|
#### More examples/documentation
|
301
314
|
|
302
315
|
There are many more basic assertion modifiers to come. See below for writing Riot extensions if you want to help out.
|
data/Rakefile
CHANGED
@@ -5,9 +5,10 @@ task :default => [:test]
|
|
5
5
|
|
6
6
|
require 'rake/testtask'
|
7
7
|
Rake::TestTask.new(:test) do |test|
|
8
|
-
test.libs
|
9
|
-
test.pattern =
|
10
|
-
test.
|
8
|
+
test.libs << 'test'
|
9
|
+
test.pattern = 'test/**/*_test.rb'
|
10
|
+
test.warning = true
|
11
|
+
test.verbose = false
|
11
12
|
end
|
12
13
|
|
13
14
|
desc "Run Flog against library (except tests)"
|
@@ -47,7 +48,7 @@ begin
|
|
47
48
|
gem.email = "gus@gusg.us"
|
48
49
|
gem.homepage = "http://github.com/thumblemonks/riot"
|
49
50
|
gem.authors = ["Justin 'Gus' Knowlden"]
|
50
|
-
gem.add_dependency '
|
51
|
+
gem.add_dependency 'term-ansicolor'
|
51
52
|
end
|
52
53
|
Jeweler::GemcutterTasks.new
|
53
54
|
rescue LoadError
|
data/TODO.markdown
CHANGED
@@ -4,6 +4,9 @@
|
|
4
4
|
- Assertion
|
5
5
|
- scope
|
6
6
|
- extensions (e.g. rack/test)
|
7
|
+
- Yard
|
8
|
+
- use yard to document the #assertion method used to define new assertions so the defined assertions will show up in the docs ( http://gnuu.org/2009/11/18/customizing-yard-templates/ )
|
9
|
+
|
7
10
|
- Assertion Macros
|
8
11
|
- include/any/contains (array,hash, maybe string?)
|
9
12
|
- perhaps able to take an enumerable and compare...
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.10.
|
1
|
+
0.10.3
|
data/lib/riot.rb
CHANGED
@@ -2,6 +2,7 @@ require 'riot/reporter'
|
|
2
2
|
require 'riot/context'
|
3
3
|
require 'riot/situation'
|
4
4
|
require 'riot/runnable'
|
5
|
+
require 'riot/assertion'
|
5
6
|
require 'riot/assertion_macros'
|
6
7
|
|
7
8
|
module Riot
|
@@ -19,14 +20,20 @@ module Riot
|
|
19
20
|
end
|
20
21
|
|
21
22
|
def self.silently!; @silent = true; end
|
22
|
-
def self.silently?; @silent == true
|
23
|
+
def self.silently?; defined?(@silent) && @silent == true end
|
24
|
+
|
25
|
+
def self.reporter=(reporter_class) @reporter_class = reporter_class; end
|
23
26
|
|
24
27
|
def self.reporter
|
25
|
-
Riot.silently?
|
28
|
+
if Riot.silently?
|
29
|
+
Riot::SilentReporter
|
30
|
+
else
|
31
|
+
(defined?(@reporter_class) && @reporter_class) || Riot::StoryReporter
|
32
|
+
end
|
26
33
|
end
|
27
|
-
|
34
|
+
|
28
35
|
# TODO: make this a flag that DotMatrix and Story respect and cause them to print errors/failures
|
29
|
-
def self.verbose; Riot.reporter = Riot::
|
36
|
+
def self.verbose; Riot.reporter = Riot::VerboseStoryReporter; end
|
30
37
|
def self.dots; Riot.reporter = Riot::DotMatrixReporter; end
|
31
38
|
|
32
39
|
at_exit { run unless Riot.silently? }
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Riot
|
2
|
+
class Assertion < RunnableBlock
|
3
|
+
|
4
|
+
def initialize(description, &definition)
|
5
|
+
super
|
6
|
+
@expectings, @expect_exception, @expectation_block = [], false, nil
|
7
|
+
@assertion_block = lambda do |actual|
|
8
|
+
actual ? Assertion.pass : Assertion.fail("Expected non-false but got #{actual.inspect} instead")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def pass() [:pass]; end
|
14
|
+
def fail(message) [:fail, message]; end
|
15
|
+
def error(e) [:error, e]; end
|
16
|
+
def assertions; @assertions ||= {}; end
|
17
|
+
|
18
|
+
# TODO: Make everyone switch to 1.8.7 or above so we can go mostly stateless again.
|
19
|
+
# Had to do this for 1.8.6 compatibility {:() I'm a sad sock monkey
|
20
|
+
def assertion(name, expect_exception=false, &assertion_block)
|
21
|
+
assertions[name] = [expect_exception, assertion_block]
|
22
|
+
class_eval <<-EOC
|
23
|
+
def #{name}(*expectings, &expectation_block)
|
24
|
+
@expectings, @expectation_block = expectings, expectation_block
|
25
|
+
@expect_exception, @assertion_block = Assertion.assertions[#{name.inspect}]
|
26
|
+
self
|
27
|
+
end
|
28
|
+
EOC
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def run(situation)
|
33
|
+
@expectings << situation.evaluate(&@expectation_block) if @expectation_block
|
34
|
+
process_macro(situation, @expect_exception) { |actual| @assertion_block.call(actual, *@expectings) }
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def process_macro(situation, expect_exception)
|
39
|
+
actual = situation.evaluate(&definition)
|
40
|
+
yield(expect_exception ? nil : actual)
|
41
|
+
rescue Exception => e
|
42
|
+
expect_exception ? yield(e) : Assertion.error(e)
|
43
|
+
end
|
44
|
+
end # Assertion
|
45
|
+
end # Riot
|
@@ -44,7 +44,8 @@ module Riot
|
|
44
44
|
# topic.assigns(:email, "foo@bar.baz")
|
45
45
|
assertion(:assigns) do |actual, *expectings|
|
46
46
|
variable, expected_value = expectings
|
47
|
-
|
47
|
+
variable_name = "@#{variable}"
|
48
|
+
actual_value = actual.instance_variable_defined?(variable_name) ? actual.instance_variable_get(variable_name) : nil
|
48
49
|
if actual_value.nil?
|
49
50
|
fail("expected @#{variable} to be assigned a value")
|
50
51
|
elsif !expected_value.nil? && expected_value != actual_value
|
data/lib/riot/reporter.rb
CHANGED
@@ -28,17 +28,22 @@ module Riot
|
|
28
28
|
error(description, result)
|
29
29
|
end
|
30
30
|
end
|
31
|
+
|
32
|
+
def new(*args, &block)
|
33
|
+
self
|
34
|
+
end
|
31
35
|
end # Reporter
|
32
36
|
|
33
37
|
class IOReporter < Reporter
|
38
|
+
attr_reader :writer
|
34
39
|
def initialize(writer=nil)
|
35
40
|
super()
|
36
41
|
@writer = writer || STDOUT
|
37
42
|
end
|
38
|
-
def say(message)
|
43
|
+
def say(message) writer.puts(message); end
|
39
44
|
|
40
45
|
def results(time_taken)
|
41
|
-
values = [
|
46
|
+
values = [passes, failures, errors, ("%0.6f" % time_taken)]
|
42
47
|
say "\n%d passes, %d failures, %d errors in %s seconds" % values
|
43
48
|
end
|
44
49
|
end
|
@@ -50,7 +55,7 @@ module Riot
|
|
50
55
|
def error(description, e) say " ! " + "#{description}: #{e.message}".red; end
|
51
56
|
end
|
52
57
|
|
53
|
-
class
|
58
|
+
class VerboseStoryReporter < StoryReporter
|
54
59
|
def error(description, e)
|
55
60
|
super(description, e)
|
56
61
|
say " #{e.class.name} occured".red
|
@@ -59,9 +64,9 @@ module Riot
|
|
59
64
|
end
|
60
65
|
|
61
66
|
class DotMatrixReporter < IOReporter
|
62
|
-
def pass(description);
|
63
|
-
def fail(description, message);
|
64
|
-
def error(description, e);
|
67
|
+
def pass(description); writer.write ".".green; end
|
68
|
+
def fail(description, message); writer.write "F".yellow; end
|
69
|
+
def error(description, e); writer.write "E".red; end
|
65
70
|
# TODO: Print the failures and errors at the end. Sorry :|
|
66
71
|
end
|
67
72
|
|
@@ -73,12 +78,14 @@ module Riot
|
|
73
78
|
end
|
74
79
|
end # Riot
|
75
80
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
81
|
+
# Colorize strings
|
82
|
+
class ::String
|
83
|
+
begin
|
84
|
+
raise LoadError if ENV["TM_MODE"]
|
85
|
+
require 'rubygems'
|
86
|
+
require 'term/ansicolor'
|
87
|
+
include Term::ANSIColor
|
88
|
+
rescue LoadError
|
82
89
|
def green; self; end
|
83
90
|
alias :red :green
|
84
91
|
alias :yellow :green
|
data/lib/riot/runnable.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
module Riot
|
2
2
|
class RunnableBlock
|
3
|
+
attr_reader :definition
|
3
4
|
def initialize(description, &definition)
|
4
|
-
@description, @definition = description, definition ||
|
5
|
+
@description, @definition = description, definition || lambda { topic }
|
5
6
|
end
|
6
7
|
|
7
|
-
def to_s
|
8
|
-
@description
|
9
|
-
end
|
8
|
+
def to_s; @description; end
|
10
9
|
end # RunnableBlock
|
11
10
|
|
12
11
|
class Setup < RunnableBlock
|
@@ -15,37 +14,8 @@ module Riot
|
|
15
14
|
end
|
16
15
|
|
17
16
|
def run(situation)
|
18
|
-
situation.setup(
|
17
|
+
situation.setup(&definition)
|
19
18
|
[:setup]
|
20
19
|
end
|
21
20
|
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, &expectation_block|
|
36
|
-
(class << self; self; end).send(:define_method, :run) do |situation|
|
37
|
-
expectings << situation.evaluate(&expectation_block) if expectation_block
|
38
|
-
process_macro(situation, expect_exception) { |actual| assertion_block.call(actual, *expectings) }
|
39
|
-
end # redefine run method when the assertion is called
|
40
|
-
self
|
41
|
-
end # define_method for assertion
|
42
|
-
end
|
43
|
-
private
|
44
|
-
def process_macro(situation, expect_exception)
|
45
|
-
actual = situation.evaluate(&@definition)
|
46
|
-
yield(expect_exception ? nil : actual)
|
47
|
-
rescue Exception => e
|
48
|
-
expect_exception ? yield(e) : Assertion.error(e)
|
49
|
-
end
|
50
|
-
end # Assertion
|
51
21
|
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.10.
|
8
|
+
s.version = "0.10.3"
|
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-12-02}
|
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 = [
|
@@ -23,6 +23,7 @@ Gem::Specification.new do |s|
|
|
23
23
|
"TODO.markdown",
|
24
24
|
"VERSION",
|
25
25
|
"lib/riot.rb",
|
26
|
+
"lib/riot/assertion.rb",
|
26
27
|
"lib/riot/assertion_macros.rb",
|
27
28
|
"lib/riot/context.rb",
|
28
29
|
"lib/riot/reporter.rb",
|
@@ -41,6 +42,7 @@ Gem::Specification.new do |s|
|
|
41
42
|
"test/assertion_macros/respond_to_test.rb",
|
42
43
|
"test/assertion_macros/same_elements_test.rb",
|
43
44
|
"test/assertion_test.rb",
|
45
|
+
"test/benchmark/colorize.rb",
|
44
46
|
"test/benchmark/riot_vs_minitest.rb",
|
45
47
|
"test/benchmark/same_elements_vs_set.rb",
|
46
48
|
"test/benchmark/simple_context_and_assertions.rb",
|
@@ -68,6 +70,7 @@ Gem::Specification.new do |s|
|
|
68
70
|
"test/assertion_macros/respond_to_test.rb",
|
69
71
|
"test/assertion_macros/same_elements_test.rb",
|
70
72
|
"test/assertion_test.rb",
|
73
|
+
"test/benchmark/colorize.rb",
|
71
74
|
"test/benchmark/riot_vs_minitest.rb",
|
72
75
|
"test/benchmark/same_elements_vs_set.rb",
|
73
76
|
"test/benchmark/simple_context_and_assertions.rb",
|
@@ -83,12 +86,12 @@ Gem::Specification.new do |s|
|
|
83
86
|
s.specification_version = 3
|
84
87
|
|
85
88
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
86
|
-
s.add_runtime_dependency(%q<
|
89
|
+
s.add_runtime_dependency(%q<term-ansicolor>, [">= 0"])
|
87
90
|
else
|
88
|
-
s.add_dependency(%q<
|
91
|
+
s.add_dependency(%q<term-ansicolor>, [">= 0"])
|
89
92
|
end
|
90
93
|
else
|
91
|
-
s.add_dependency(%q<
|
94
|
+
s.add_dependency(%q<term-ansicolor>, [">= 0"])
|
92
95
|
end
|
93
96
|
end
|
94
97
|
|
data/test/assertion_test.rb
CHANGED
@@ -32,27 +32,33 @@ context "An assertion" do
|
|
32
32
|
end
|
33
33
|
end # that is erroring
|
34
34
|
|
35
|
-
context "with no block" do
|
35
|
+
context "with no block to provide the actual" do
|
36
36
|
setup do
|
37
37
|
@situation = Riot::Situation.new
|
38
38
|
@situation.topic = "hello"
|
39
39
|
Riot::Assertion.new("test")
|
40
40
|
end
|
41
|
-
should("
|
41
|
+
should("uses block returning topic as default") do
|
42
42
|
topic.equals("hello")
|
43
43
|
result = topic.run(@situation)
|
44
44
|
end.equals([:pass])
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
context "with block expectation" do
|
48
48
|
setup do
|
49
49
|
@situation = Riot::Situation.new
|
50
50
|
@situation.topic = "hello"
|
51
51
|
Riot::Assertion.new("test")
|
52
52
|
end
|
53
|
+
|
53
54
|
should("use block returning topic as default") do
|
54
55
|
topic.equals { "hello" }
|
55
56
|
result = topic.run(@situation)
|
56
57
|
end.equals([:pass])
|
58
|
+
|
59
|
+
asserts("block expectation has access to the situation items") do
|
60
|
+
topic.equals { @topic }
|
61
|
+
topic.run(@situation)
|
62
|
+
end.equals([:pass])
|
57
63
|
end
|
58
64
|
end # An assertion block
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'benchmark'
|
3
|
+
require 'colorize'
|
4
|
+
require 'term/ansicolor'
|
5
|
+
|
6
|
+
class MyString < String
|
7
|
+
include ::Term::ANSIColor
|
8
|
+
end
|
9
|
+
|
10
|
+
colorize = String.new
|
11
|
+
term_ansicolor = MyString.new
|
12
|
+
|
13
|
+
n = 50_000
|
14
|
+
|
15
|
+
Benchmark.bmbm do |x|
|
16
|
+
x.report("colorize") do
|
17
|
+
n.times do
|
18
|
+
colorize.green
|
19
|
+
colorize.yellow
|
20
|
+
colorize.red
|
21
|
+
end
|
22
|
+
end
|
23
|
+
x.report("term-ansicolor") do
|
24
|
+
n.times do
|
25
|
+
term_ansicolor.green
|
26
|
+
term_ansicolor.yellow
|
27
|
+
term_ansicolor.red
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Rehearsal --------------------------------------------------
|
33
|
+
# colorize 4.140000 0.160000 4.300000 ( 4.375765)
|
34
|
+
# term-ansicolor 0.720000 0.000000 0.720000 ( 0.730665)
|
35
|
+
# ----------------------------------------- total: 5.020000sec
|
36
|
+
#
|
37
|
+
# user system total real
|
38
|
+
# colorize 4.070000 0.170000 4.240000 ( 4.459804)
|
39
|
+
# term-ansicolor 0.700000 0.000000 0.700000 ( 0.728494)
|
data/test/report_test.rb
CHANGED
@@ -41,6 +41,12 @@ context "A reporter" do
|
|
41
41
|
asserts("description sent to #error") do
|
42
42
|
topic.report("break it down", [:error, "error time"])
|
43
43
|
end.equals("errored(break it down, error time)")
|
44
|
+
|
45
|
+
context "instance" do
|
46
|
+
setup { Riot::Reporter.new }
|
47
|
+
|
48
|
+
should("return self invoking new") { topic.new }.equals { topic }
|
49
|
+
end
|
44
50
|
end # A reporter
|
45
51
|
|
46
52
|
require 'stringio'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: riot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin 'Gus' Knowlden
|
@@ -9,11 +9,11 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-12-02 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
16
|
+
name: term-ansicolor
|
17
17
|
type: :runtime
|
18
18
|
version_requirement:
|
19
19
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -38,6 +38,7 @@ files:
|
|
38
38
|
- TODO.markdown
|
39
39
|
- VERSION
|
40
40
|
- lib/riot.rb
|
41
|
+
- lib/riot/assertion.rb
|
41
42
|
- lib/riot/assertion_macros.rb
|
42
43
|
- lib/riot/context.rb
|
43
44
|
- lib/riot/reporter.rb
|
@@ -56,6 +57,7 @@ files:
|
|
56
57
|
- test/assertion_macros/respond_to_test.rb
|
57
58
|
- test/assertion_macros/same_elements_test.rb
|
58
59
|
- test/assertion_test.rb
|
60
|
+
- test/benchmark/colorize.rb
|
59
61
|
- test/benchmark/riot_vs_minitest.rb
|
60
62
|
- test/benchmark/same_elements_vs_set.rb
|
61
63
|
- test/benchmark/simple_context_and_assertions.rb
|
@@ -105,6 +107,7 @@ test_files:
|
|
105
107
|
- test/assertion_macros/respond_to_test.rb
|
106
108
|
- test/assertion_macros/same_elements_test.rb
|
107
109
|
- test/assertion_test.rb
|
110
|
+
- test/benchmark/colorize.rb
|
108
111
|
- test/benchmark/riot_vs_minitest.rb
|
109
112
|
- test/benchmark/same_elements_vs_set.rb
|
110
113
|
- test/benchmark/simple_context_and_assertions.rb
|