riot 0.10.9 → 0.10.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/CHANGELOG +46 -0
  2. data/README.markdown +53 -16
  3. data/Rakefile +8 -0
  4. data/VERSION +1 -1
  5. data/lib/riot.rb +1 -1
  6. data/lib/riot/assertion.rb +18 -31
  7. data/lib/riot/assertion_macro.rb +35 -0
  8. data/lib/riot/assertion_macros/any.rb +12 -0
  9. data/lib/riot/assertion_macros/assigns.rb +27 -0
  10. data/lib/riot/assertion_macros/empty.rb +13 -0
  11. data/lib/riot/assertion_macros/equals.rb +18 -0
  12. data/lib/riot/assertion_macros/exists.rb +15 -0
  13. data/lib/riot/assertion_macros/includes.rb +17 -0
  14. data/lib/riot/assertion_macros/kind_of.rb +16 -0
  15. data/lib/riot/assertion_macros/matches.rb +17 -0
  16. data/lib/riot/assertion_macros/nil.rb +12 -0
  17. data/lib/riot/assertion_macros/raises.rb +31 -0
  18. data/lib/riot/assertion_macros/respond_to.rb +16 -0
  19. data/lib/riot/assertion_macros/same_elements.rb +14 -0
  20. data/lib/riot/assertion_macros/size.rb +15 -0
  21. data/lib/riot/context.rb +9 -17
  22. data/lib/riot/reporter.rb +25 -21
  23. data/riot.gemspec +17 -3
  24. data/test/assertion_macros/any_test.rb +2 -2
  25. data/test/assertion_macros/equals_test.rb +4 -4
  26. data/test/assertion_macros/exists_test.rb +2 -2
  27. data/test/assertion_macros/includes_test.rb +1 -1
  28. data/test/assertion_macros/kind_of_test.rb +1 -1
  29. data/test/assertion_macros/matching_test.rb +1 -1
  30. data/test/assertion_macros/nil_test.rb +1 -1
  31. data/test/assertion_macros/raises_test.rb +3 -3
  32. data/test/assertion_macros/respond_to_test.rb +1 -1
  33. data/test/assertion_macros/size_test.rb +17 -6
  34. data/test/assertion_test.rb +11 -6
  35. data/test/context_test.rb +2 -54
  36. data/test/report_test.rb +7 -2
  37. data/test/teststrap.rb +12 -3
  38. metadata +17 -3
  39. data/lib/riot/assertion_macros.rb +0 -136
@@ -0,0 +1,31 @@
1
+ module Riot
2
+ # Asserts that the test raises the expected Exception
3
+ # asserts("test") { raise My::Exception }.raises(My::Exception)
4
+ # should("test") { raise My::Exception }.raises(My::Exception)
5
+ #
6
+ # You can also check to see if the provided message equals or matches your expectations. The message
7
+ # from the actual raised exception will be converted to a string before any comparison is executed.
8
+ # asserts("test") { raise My::Exception, "Foo" }.raises(My::Exception, "Foo")
9
+ # asserts("test") { raise My::Exception, "Foo Bar" }.raises(My::Exception, /Bar/)
10
+ class RaisesMacro < AssertionMacro
11
+ register :raises
12
+ expects_exception!
13
+
14
+ def evaluate(actual_exception, expected_class, expected_message=nil)
15
+ actual_message = actual_exception && actual_exception.message
16
+ if actual_exception.nil?
17
+ fail("should have raised #{expected_class}, but raised nothing")
18
+ elsif expected_class != actual_exception.class
19
+ fail("should have raised #{expected_class}, not #{actual_exception.class}")
20
+ elsif expected_message && !(actual_message.to_s =~ %r[#{expected_message}])
21
+ fail("expected #{expected_message.inspect} for message, not #{actual_message.inspect}")
22
+ else
23
+ if expected_message
24
+ pass("raises #{expected_class.inspect} with message #{expected_message.inspect}")
25
+ else
26
+ pass("raises #{expected_class.inspect}")
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,16 @@
1
+ module Riot
2
+ # Asserts that the result of the test is an object that responds to the given method
3
+ # asserts("test") { "foo" }.respond_to(:to_s)
4
+ # should("test") { "foo" }.respond_to(:to_s)
5
+ class RespondToMacro < AssertionMacro
6
+ register :respond_to
7
+
8
+ def evaluate(actual, expected)
9
+ if actual.respond_to?(expected)
10
+ pass("responds to #{expected.inspect}")
11
+ else
12
+ fail("expected method #{expected.inspect} is not defined")
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ module Riot
2
+ # Asserts that two arrays contain the same elements, the same number of times.
3
+ # asserts("test") { ["foo", "bar"] }.same_elements(["bar", "foo"])
4
+ # should("test") { ["foo", "bar"] }.same_elements(["bar", "foo"])
5
+ class SameElementsMacro < AssertionMacro
6
+ register :same_elements
7
+
8
+ def evaluate(actual, expected)
9
+ require 'set'
10
+ same = (Set.new(expected) == Set.new(actual))
11
+ same ? pass : fail("expected elements #{expected.inspect} to match #{actual.inspect}")
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ module Riot
2
+ # Asserts that result's size is as expected. Expected size can be specified as
3
+ # a number or a range.
4
+ # asserts("a string") { 'washington' }.size(9..12)
5
+ # asserts("an array") { [1, 2, 3] }.size(3)
6
+ # asserts("a hash") { {:name => 'washington'} }.size(1)
7
+ class SizeMacro < AssertionMacro
8
+ register :size
9
+
10
+ def evaluate(actual, expected)
11
+ failure_message = "size of #{actual.inspect} expected to be #{expected} but is #{actual.size}"
12
+ expected === actual.size ? pass("is of size #{expected}") : fail(failure_message)
13
+ end
14
+ end
15
+ end
@@ -1,9 +1,5 @@
1
1
  module Riot
2
- RootContext = Struct.new(:setups, :teardowns) do
3
- def assertion_class
4
- Assertion
5
- end
6
- end
2
+ RootContext = Struct.new(:setups, :teardowns)
7
3
 
8
4
  class Context
9
5
  attr_reader :description
@@ -28,23 +24,12 @@ module Riot
28
24
  @contexts << self.class.new("#{@description} #{description}", self, &definition)
29
25
  end
30
26
 
31
- def extend_assertions(*extension_modules)
32
- @assertion_class = Class.new(Assertion) do
33
- include *extension_modules
34
- end
35
- end
36
-
37
27
  def run(reporter)
38
28
  reporter.describe_context(self) unless @assertions.empty?
39
29
  local_run(reporter, Situation.new)
40
30
  run_sub_contexts(reporter)
41
31
  reporter
42
32
  end
43
-
44
- def assertion_class
45
- @assertion_class ||= @parent.assertion_class
46
- end
47
-
48
33
  private
49
34
 
50
35
  def local_run(reporter, situation)
@@ -56,7 +41,14 @@ module Riot
56
41
  def run_sub_contexts(reporter) @contexts.each { |ctx| ctx.run(reporter) }; end
57
42
 
58
43
  def new_assertion(scope, what, &definition)
59
- (@assertions << assertion_class.new("#{scope} #{what}", &definition)).last
44
+ if what.kind_of?(Symbol)
45
+ definition ||= lambda { topic.send(what) }
46
+ description = "#{scope} ##{what}"
47
+ else
48
+ description = "#{scope} #{what}"
49
+ end
50
+
51
+ (@assertions << Assertion.new(description, &definition)).last
60
52
  end
61
53
  end # Context
62
54
  end # Riot
@@ -20,7 +20,7 @@ module Riot
20
20
  case code
21
21
  when :pass then
22
22
  @passes += 1
23
- pass(description)
23
+ pass(description, result)
24
24
  when :fail then
25
25
  @failures += 1
26
26
  fail(description, result)
@@ -36,24 +36,25 @@ module Riot
36
36
  end # Reporter
37
37
 
38
38
  class IOReporter < Reporter
39
- attr_reader :writer
40
39
  def initialize(writer=STDOUT)
41
40
  super()
42
41
  @writer = writer
43
42
  end
44
- def say(message) writer.puts(message); end
43
+ def puts(message) @writer.puts(message); end
44
+ def print(message) @writer.print(message); end
45
45
 
46
46
  def results(time_taken)
47
47
  values = [passes, failures, errors, ("%0.6f" % time_taken)]
48
- say "\n%d passes, %d failures, %d errors in %s seconds" % values
48
+ puts "\n%d passes, %d failures, %d errors in %s seconds" % values
49
49
  end
50
50
 
51
51
  def format_error(e)
52
- format = " #{e.class.name} occured"
53
- format += "\n#{e.to_s}\n"
54
- e.backtrace.each { |line| format += "\n at #{line}" }
52
+ format = []
53
+ format << " #{e.class.name} occurred"
54
+ format << "#{e.to_s}"
55
+ e.backtrace.each { |line| format << " at #{line}" }
55
56
 
56
- format
57
+ format.join("\n")
57
58
  end
58
59
 
59
60
  begin
@@ -71,46 +72,49 @@ module Riot
71
72
  class StoryReporter < IOReporter
72
73
  def describe_context(context)
73
74
  super
74
- say context.description
75
+ puts context.description
75
76
  end
76
- def pass(description) say " + " + green(description); end
77
- def fail(description, message) say " - " + yellow("#{description}: #{message}"); end
78
- def error(description, e) say " ! " + red("#{description}: #{e.message}"); end
77
+ def pass(description, message) puts " + " + green("#{description} #{message}".strip); end
78
+ def fail(description, message) puts " - " + yellow("#{description}: #{message}"); end
79
+ def error(description, e) puts " ! " + red("#{description}: #{e.message}"); end
79
80
  end
80
81
 
81
82
  class VerboseStoryReporter < StoryReporter
82
83
  def error(description, e)
83
- super(description, e)
84
- say red(format_error(e))
84
+ super
85
+ puts red(format_error(e))
85
86
  end
86
87
  end
87
88
 
88
89
  class DotMatrixReporter < IOReporter
89
- def pass(description); writer.write green("."); end
90
-
91
90
  def initialize(writer=STDOUT)
92
91
  super
93
92
  @details = []
94
93
  end
94
+
95
+ def pass(description, message)
96
+ print green(".")
97
+ end
98
+
95
99
  def fail(description, message)
96
- writer.write yellow("F")
100
+ print yellow("F")
97
101
  @details << "FAILURE - #{current_context.description} #{description} => #{message}"
98
102
  end
99
103
 
100
104
  def error(description, e)
101
- writer.write red("E")
105
+ print red("E")
102
106
  @details << "ERROR - #{current_context.description} #{description} => #{format_error(e)}"
103
107
  end
104
108
 
105
109
  def results(time_taken)
106
- say "\n"
107
- @details.each { |detail| say detail }
110
+ puts "\n" unless @details.empty?
111
+ @details.each { |detail| puts detail }
108
112
  super
109
113
  end
110
114
  end
111
115
 
112
116
  class SilentReporter < Reporter
113
- def pass(description); end
117
+ def pass(description, message); end
114
118
  def fail(description, message); end
115
119
  def error(description, e); end
116
120
  def results(time_taken); end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{riot}
8
- s.version = "0.10.9"
8
+ s.version = "0.10.10"
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-15}
12
+ s.date = %q{2009-12-29}
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 = [
@@ -17,6 +17,7 @@ Gem::Specification.new do |s|
17
17
  ]
18
18
  s.files = [
19
19
  ".gitignore",
20
+ "CHANGELOG",
20
21
  "MIT-LICENSE",
21
22
  "README.markdown",
22
23
  "Rakefile",
@@ -24,7 +25,20 @@ Gem::Specification.new do |s|
24
25
  "VERSION",
25
26
  "lib/riot.rb",
26
27
  "lib/riot/assertion.rb",
27
- "lib/riot/assertion_macros.rb",
28
+ "lib/riot/assertion_macro.rb",
29
+ "lib/riot/assertion_macros/any.rb",
30
+ "lib/riot/assertion_macros/assigns.rb",
31
+ "lib/riot/assertion_macros/empty.rb",
32
+ "lib/riot/assertion_macros/equals.rb",
33
+ "lib/riot/assertion_macros/exists.rb",
34
+ "lib/riot/assertion_macros/includes.rb",
35
+ "lib/riot/assertion_macros/kind_of.rb",
36
+ "lib/riot/assertion_macros/matches.rb",
37
+ "lib/riot/assertion_macros/nil.rb",
38
+ "lib/riot/assertion_macros/raises.rb",
39
+ "lib/riot/assertion_macros/respond_to.rb",
40
+ "lib/riot/assertion_macros/same_elements.rb",
41
+ "lib/riot/assertion_macros/size.rb",
28
42
  "lib/riot/context.rb",
29
43
  "lib/riot/reporter.rb",
30
44
  "lib/riot/runnable.rb",
@@ -7,12 +7,12 @@ context "An any assertion macro" do
7
7
  end
8
8
  end
9
9
 
10
- assertion_test_passes("when an array has items") { assert_any([1]) }
10
+ assertion_test_passes("when an array has items", "is not empty") { assert_any([1]) }
11
11
  assertion_test_fails("when an array is empty", "expected [] to have items") do
12
12
  assert_any([])
13
13
  end
14
14
 
15
- assertion_test_passes("when a hash has items") { assert_any({:name => 'washington'}) }
15
+ assertion_test_passes("when a hash has items", "is not empty") { assert_any({:name => 'washington'}) }
16
16
  assertion_test_fails("when a hash is empty", "expected {} to have items") do
17
17
  assert_any({})
18
18
  end
@@ -1,6 +1,6 @@
1
1
  require 'teststrap'
2
2
 
3
- # Using == to verify the tes because this is the test for :equals itself. Look at assertion_test_passes
3
+ # Using == to verify the test because this is the test for :equals itself. Look at assertion_test_passes
4
4
  # and assertion_test_fails for testing other macros.
5
5
 
6
6
  context "An equals assertion macro" do
@@ -9,7 +9,7 @@ context "An equals assertion macro" do
9
9
  end
10
10
 
11
11
  asserts(":pass when expectation met") do
12
- topic.equals("foo").run(Riot::Situation.new) == [:pass]
12
+ topic.equals("foo").run(Riot::Situation.new) == [:pass, %Q{is equal to "foo"}]
13
13
  end
14
14
 
15
15
  context "that is failing" do
@@ -25,7 +25,7 @@ context "An equals assertion macro" do
25
25
  end
26
26
 
27
27
  asserts(":pass when in expected range") do
28
- topic.equals(30000..32000).run(Riot::Situation.new) == [:pass]
28
+ topic.equals(30000..32000).run(Riot::Situation.new) == [:pass, "is equal to 30000..32000"]
29
29
  end
30
30
 
31
31
  context "when not in expected range" do
@@ -39,7 +39,7 @@ context "An equals assertion macro" do
39
39
  context "with block as the expectation" do
40
40
  asserts(":pass when block expectation met") do
41
41
  topic.equals { "foo" }.run(Riot::Situation.new)
42
- end.equals([:pass])
42
+ end.equals([:pass, %Q{is equal to "foo"}])
43
43
 
44
44
  asserts(":fail with message when block expectation not met") do
45
45
  topic.equals { "bar" }.run(Riot::Situation.new)
@@ -5,11 +5,11 @@ context "An exists assertion macro" do
5
5
 
6
6
  asserts(":pass when result has a value") do
7
7
  Riot::Assertion.new("foo") { "foo" }.exists.run(topic)
8
- end.equals([:pass])
8
+ end.equals([:pass, "is not nil"])
9
9
 
10
10
  asserts(":pass because empty string is considered a value") do
11
11
  Riot::Assertion.new("foo") { "" }.exists.run(topic)
12
- end.equals([:pass])
12
+ end.equals([:pass, "is not nil"])
13
13
 
14
14
  asserts(":fail with message when value is nil") do
15
15
  Riot::Assertion.new("foo") { nil }.exists.run(topic)
@@ -5,7 +5,7 @@ context "An includes assertion macro" do
5
5
  Riot::Assertion.new("an array") { [1, 6, 42, 7] }
6
6
  end
7
7
 
8
- assertion_test_passes("when array includes 42") { topic.includes(42) }
8
+ assertion_test_passes("when array includes 42", "includes 42") { topic.includes(42) }
9
9
 
10
10
  assertion_test_fails("when 99 not included in array", "expected [1, 6, 42, 7] to include 99") do
11
11
  topic.includes(99)
@@ -5,7 +5,7 @@ context "A kind_of assertion macro" do
5
5
 
6
6
  asserts ":pass when specific result is a kind of String" do
7
7
  Riot::Assertion.new("foo") { "a" }.kind_of(String).run(topic)
8
- end.equals([:pass])
8
+ end.equals([:pass, %Q{is a kind of String}])
9
9
 
10
10
  asserts ":fail when not a kind of String" do
11
11
  Riot::Assertion.new("foo") { 0 }.kind_of(String).run(topic)
@@ -3,7 +3,7 @@ require 'teststrap'
3
3
  context "A matching assertion macro" do
4
4
  setup { Riot::Assertion.new("foo") { "abc" } }
5
5
 
6
- assertion_test_passes("when expression matches actual") { topic.matches(/abc/) }
6
+ assertion_test_passes("when expression matches actual", %Q{matches /abc/}) { topic.matches(/abc/) }
7
7
 
8
8
  assertion_test_fails("when expression fails to match", "expected /abcd/ to match \"abc\"") do
9
9
  topic.matches(/abcd/)
@@ -5,7 +5,7 @@ context "A nil assertion macro" do
5
5
 
6
6
  asserts(":pass when result is nil") do
7
7
  Riot::Assertion.new("foo") { nil }.nil.run(topic)
8
- end.equals([:pass])
8
+ end.equals([:pass, "is nil"])
9
9
 
10
10
  asserts(":fail with message") do
11
11
  Riot::Assertion.new("foo") { "a" }.nil.run(topic)
@@ -3,7 +3,7 @@ require 'teststrap'
3
3
  class Whoops < Exception; end
4
4
 
5
5
  context "A raises assertion macro" do
6
- assertion_test_passes("when expected exception is raised") do
6
+ assertion_test_passes("when expected exception is raised", "raises Whoops") do
7
7
  Riot::Assertion.new("foo") { raise Whoops }.raises(Whoops)
8
8
  end
9
9
 
@@ -15,7 +15,7 @@ context "A raises assertion macro" do
15
15
  assertion = Riot::Assertion.new("foo") { "barf" }.raises(Whoops)
16
16
  end
17
17
 
18
- assertion_test_passes("when provided message equals expected message") do
18
+ assertion_test_passes("when provided message equals expected message", %Q{raises Whoops with message "Mom"}) do
19
19
  Riot::Assertion.new("foo") { raise Whoops, "Mom" }.raises(Whoops, "Mom")
20
20
  end
21
21
 
@@ -23,7 +23,7 @@ context "A raises assertion macro" do
23
23
  Riot::Assertion.new("foo") { raise Whoops, "Dad" }.raises(Whoops, "Mom")
24
24
  end
25
25
 
26
- assertion_test_passes("when provided message matches expected message") do
26
+ assertion_test_passes("when provided message matches expected message", %Q{raises Whoops with message /Mom/}) do
27
27
  Riot::Assertion.new("foo") { raise Whoops, "Mom" }.raises(Whoops, /Mom/)
28
28
  end
29
29
 
@@ -3,7 +3,7 @@ require 'teststrap'
3
3
  context "A respond_to assertion macro" do
4
4
  setup { Riot::Assertion.new("foo") { "bar" } }
5
5
 
6
- assertion_test_passes("when method is defined") { topic.respond_to(:each_byte) }
6
+ assertion_test_passes("when method is defined", "responds to :each_byte") { topic.respond_to(:each_byte) }
7
7
 
8
8
  assertion_test_fails("when method not defined", "expected method :goofballs is not defined") do
9
9
  topic.respond_to(:goofballs)
@@ -7,8 +7,13 @@ context "A size assertion macro" do
7
7
  end
8
8
  end
9
9
 
10
- assertion_test_passes("when string's size is as expected") { assert_size("washington", 10) }
11
- assertion_test_passes("when string's size is in given range") { assert_size("washington", 9..12) }
10
+ assertion_test_passes("when string's size is as expected", "is of size 10") do
11
+ assert_size("washington", 10)
12
+ end
13
+ assertion_test_passes("when string's size is in given range", "is of size 9..12") do
14
+ assert_size("washington", 9..12)
15
+ end
16
+
12
17
  assertion_test_fails("when string's size is not as expected", "size of \"washington\" expected to be 11 but is 10") do
13
18
  assert_size("washington", 11)
14
19
  end
@@ -16,8 +21,10 @@ context "A size assertion macro" do
16
21
  assert_size("washington", 11..13)
17
22
  end
18
23
 
19
- assertion_test_passes("when an array's size is as expected") { assert_size([1, 2, 3], 3) }
20
- assertion_test_passes("when an array's size is in given range") { assert_size([1, 2, 3], 3..4) }
24
+ assertion_test_passes("when an array's size is as expected", "is of size 3") { assert_size([1, 2, 3], 3) }
25
+ assertion_test_passes("when an array's size is in given range", "is of size 3..4") do
26
+ assert_size([1, 2, 3], 3..4)
27
+ end
21
28
  assertion_test_fails("when an array's size is not as expected", "size of [1, 2, 3] expected to be 2 but is 3") do
22
29
  assert_size([1, 2, 3], 2)
23
30
  end
@@ -25,8 +32,12 @@ context "A size assertion macro" do
25
32
  assert_size([1, 2, 3], 4..6)
26
33
  end
27
34
 
28
- assertion_test_passes("when a hash size is as expected") { assert_size({:name => 'washington'}, 1) }
29
- assertion_test_passes("when a hash size is in range") { assert_size({:name => 'washington'}, 1...3) }
35
+ assertion_test_passes("when a hash size is as expected", "is of size 1") do
36
+ assert_size({:name => 'washington'}, 1)
37
+ end
38
+ assertion_test_passes("when a hash size is in range", "is of size 1...3") do
39
+ assert_size({:name => 'washington'}, 1...3)
40
+ end
30
41
  assertion_test_fails("when a hash size is not as expected", "size of {} expected to be 2 but is 0") do
31
42
  assert_size({}, 2)
32
43
  end