riot 0.10.11 → 0.10.12.pre

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.
Files changed (40) hide show
  1. data/.gitignore +3 -1
  2. data/CHANGELOG +34 -0
  3. data/README.markdown +81 -456
  4. data/Rakefile +31 -28
  5. data/VERSION +1 -1
  6. data/lib/riot.rb +2 -1
  7. data/lib/riot/assertion.rb +1 -1
  8. data/lib/riot/assertion_macro.rb +51 -5
  9. data/lib/riot/assertion_macros/any.rb +1 -1
  10. data/lib/riot/assertion_macros/assigns.rb +2 -2
  11. data/lib/riot/assertion_macros/empty.rb +1 -1
  12. data/lib/riot/assertion_macros/equals.rb +4 -4
  13. data/lib/riot/assertion_macros/equivalent_to.rb +22 -0
  14. data/lib/riot/assertion_macros/includes.rb +2 -2
  15. data/lib/riot/assertion_macros/kind_of.rb +2 -2
  16. data/lib/riot/assertion_macros/matches.rb +2 -2
  17. data/lib/riot/assertion_macros/nil.rb +1 -1
  18. data/lib/riot/assertion_macros/raises.rb +7 -10
  19. data/lib/riot/assertion_macros/respond_to.rb +3 -2
  20. data/lib/riot/assertion_macros/same_elements.rb +1 -1
  21. data/lib/riot/assertion_macros/size.rb +2 -2
  22. data/lib/riot/context.rb +104 -19
  23. data/lib/riot/message.rb +23 -0
  24. data/lib/riot/rr.rb +35 -0
  25. data/lib/riot/runnable.rb +12 -0
  26. data/lib/riot/situation.rb +4 -0
  27. data/riot.gemspec +20 -4
  28. data/test/assertion_macro_test.rb +30 -0
  29. data/test/assertion_macros/assigns_test.rb +3 -3
  30. data/test/assertion_macros/equals_test.rb +2 -9
  31. data/test/assertion_macros/equivalent_to_test.rb +36 -0
  32. data/test/assertion_macros/respond_to_test.rb +1 -0
  33. data/test/assertion_macros/size_test.rb +6 -6
  34. data/test/assertion_test.rb +1 -1
  35. data/test/benchmark/message_concatenation.rb +82 -0
  36. data/test/context_test.rb +17 -2
  37. data/test/extensions/rrriot_test.rb +69 -0
  38. data/test/message_test.rb +35 -0
  39. data/test/teststrap.rb +1 -1
  40. metadata +27 -4
@@ -0,0 +1,23 @@
1
+ class BlankSlate
2
+ instance_methods.each { |meth| undef_method(meth) unless meth =~ /^__/ }
3
+ end
4
+
5
+ module Riot
6
+ class Message < BlankSlate
7
+ def initialize(*phrases)
8
+ @chunks = []; _inspect(phrases)
9
+ end
10
+
11
+ def to_s; @chunks.join.strip; end
12
+
13
+ def method_missing(meth, *phrases, &blk) push(meth.to_s.gsub('_', ' ')); _inspect(phrases); end
14
+
15
+ def comma(str, *phrases) _concat([", ", str]); _inspect(phrases); end
16
+ def but(*phrases); comma("but", *phrases); end
17
+ def not(*phrases); comma("not", *phrases); end
18
+ def push(str) _concat([" ", str]); end
19
+ private
20
+ def _concat(chunks) @chunks.concat(chunks); self; end
21
+ def _inspect(phrases) phrases.each { |phrase| push(phrase.inspect) }; self; end
22
+ end # Message
23
+ end # Riot
@@ -0,0 +1,35 @@
1
+ require 'rr'
2
+
3
+ module Riot
4
+ module RR
5
+
6
+ class Situation < Riot::Situation
7
+ include ::RR::Adapters::RRMethods
8
+ end # Situation
9
+
10
+ class Assertion < Riot::Assertion
11
+ def run(situation)
12
+ result = super
13
+ situation.verify
14
+ result
15
+ rescue ::RR::Errors::RRError => e
16
+ [:fail, e.message.gsub(/\n/, " ")]
17
+ ensure
18
+ situation.reset
19
+ end
20
+ end # Assertion
21
+
22
+ module ContextHelpers
23
+ private
24
+ def assertion_class; Riot::RR::Assertion; end
25
+ def situation_class; Riot::RR::Situation; end
26
+ end # ContextHelpers
27
+
28
+ def self.enable(context_class)
29
+ context_class.instance_eval { include Riot::RR::ContextHelpers }
30
+ end
31
+
32
+ end # RR
33
+ end # Riot
34
+
35
+ Riot::RR.enable(Riot::Context)
@@ -18,4 +18,16 @@ module Riot
18
18
  [:setup]
19
19
  end
20
20
  end # Setup
21
+
22
+ class Helper < RunnableBlock
23
+ def initialize(name, &definition)
24
+ super("helper #{name}", &definition)
25
+ @name = name
26
+ end
27
+
28
+ def run(situation)
29
+ situation.helper(@name, &definition)
30
+ [:helper]
31
+ end
32
+ end
21
33
  end # Riot
@@ -5,6 +5,10 @@ module Riot
5
5
  @topic = self.instance_eval(&block)
6
6
  end
7
7
 
8
+ def helper(name, &block)
9
+ (class << self; self; end).send(:define_method, name, &block)
10
+ end
11
+
8
12
  def evaluate(&block)
9
13
  self.instance_eval(&block)
10
14
  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.11"
8
+ s.version = "0.10.12.pre"
9
9
 
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
10
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Justin 'Gus' Knowlden"]
12
- s.date = %q{2009-12-29}
12
+ s.date = %q{2010-02-09}
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 = [
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
30
30
  "lib/riot/assertion_macros/assigns.rb",
31
31
  "lib/riot/assertion_macros/empty.rb",
32
32
  "lib/riot/assertion_macros/equals.rb",
33
+ "lib/riot/assertion_macros/equivalent_to.rb",
33
34
  "lib/riot/assertion_macros/exists.rb",
34
35
  "lib/riot/assertion_macros/includes.rb",
35
36
  "lib/riot/assertion_macros/kind_of.rb",
@@ -41,14 +42,18 @@ Gem::Specification.new do |s|
41
42
  "lib/riot/assertion_macros/same_elements.rb",
42
43
  "lib/riot/assertion_macros/size.rb",
43
44
  "lib/riot/context.rb",
45
+ "lib/riot/message.rb",
44
46
  "lib/riot/reporter.rb",
47
+ "lib/riot/rr.rb",
45
48
  "lib/riot/runnable.rb",
46
49
  "lib/riot/situation.rb",
47
50
  "riot.gemspec",
51
+ "test/assertion_macro_test.rb",
48
52
  "test/assertion_macros/any_test.rb",
49
53
  "test/assertion_macros/assigns_test.rb",
50
54
  "test/assertion_macros/empty_test.rb",
51
55
  "test/assertion_macros/equals_test.rb",
56
+ "test/assertion_macros/equivalent_to_test.rb",
52
57
  "test/assertion_macros/exists_test.rb",
53
58
  "test/assertion_macros/includes_test.rb",
54
59
  "test/assertion_macros/kind_of_test.rb",
@@ -61,10 +66,13 @@ Gem::Specification.new do |s|
61
66
  "test/assertion_macros/size_test.rb",
62
67
  "test/assertion_test.rb",
63
68
  "test/benchmark/colorize.rb",
69
+ "test/benchmark/message_concatenation.rb",
64
70
  "test/benchmark/riot_vs_minitest.rb",
65
71
  "test/benchmark/same_elements_vs_set.rb",
66
72
  "test/benchmark/simple_context_and_assertions.rb",
67
73
  "test/context_test.rb",
74
+ "test/extensions/rrriot_test.rb",
75
+ "test/message_test.rb",
68
76
  "test/report_test.rb",
69
77
  "test/setup_test.rb",
70
78
  "test/situation_test.rb",
@@ -77,10 +85,12 @@ Gem::Specification.new do |s|
77
85
  s.rubygems_version = %q{1.3.5}
78
86
  s.summary = %q{An extremely fast, expressive, and context-driven unit-testing framework. Protest the slow test.}
79
87
  s.test_files = [
80
- "test/assertion_macros/any_test.rb",
88
+ "test/assertion_macro_test.rb",
89
+ "test/assertion_macros/any_test.rb",
81
90
  "test/assertion_macros/assigns_test.rb",
82
91
  "test/assertion_macros/empty_test.rb",
83
92
  "test/assertion_macros/equals_test.rb",
93
+ "test/assertion_macros/equivalent_to_test.rb",
84
94
  "test/assertion_macros/exists_test.rb",
85
95
  "test/assertion_macros/includes_test.rb",
86
96
  "test/assertion_macros/kind_of_test.rb",
@@ -93,10 +103,13 @@ Gem::Specification.new do |s|
93
103
  "test/assertion_macros/size_test.rb",
94
104
  "test/assertion_test.rb",
95
105
  "test/benchmark/colorize.rb",
106
+ "test/benchmark/message_concatenation.rb",
96
107
  "test/benchmark/riot_vs_minitest.rb",
97
108
  "test/benchmark/same_elements_vs_set.rb",
98
109
  "test/benchmark/simple_context_and_assertions.rb",
99
110
  "test/context_test.rb",
111
+ "test/extensions/rrriot_test.rb",
112
+ "test/message_test.rb",
100
113
  "test/report_test.rb",
101
114
  "test/setup_test.rb",
102
115
  "test/situation_test.rb",
@@ -109,11 +122,14 @@ Gem::Specification.new do |s|
109
122
  s.specification_version = 3
110
123
 
111
124
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
125
+ s.add_runtime_dependency(%q<rr>, [">= 0"])
112
126
  s.add_runtime_dependency(%q<term-ansicolor>, [">= 0"])
113
127
  else
128
+ s.add_dependency(%q<rr>, [">= 0"])
114
129
  s.add_dependency(%q<term-ansicolor>, [">= 0"])
115
130
  end
116
131
  else
132
+ s.add_dependency(%q<rr>, [">= 0"])
117
133
  s.add_dependency(%q<term-ansicolor>, [">= 0"])
118
134
  end
119
135
  end
@@ -0,0 +1,30 @@
1
+ require 'teststrap'
2
+
3
+ context "An AssertionMacro instance" do
4
+ setup { Riot::AssertionMacro.new }
5
+
6
+ asserts_topic.responds_to(:new_message)
7
+ asserts_topic.responds_to(:expected_message)
8
+ asserts_topic.responds_to(:should_have_message)
9
+
10
+ context "receiving #new_message" do
11
+ setup { topic.new_message("hope") }
12
+
13
+ asserts_topic.kind_of(Riot::Message)
14
+ asserts(:to_s).equals(%q["hope"])
15
+ end
16
+
17
+ context "receiving #should_have_message" do
18
+ setup { topic.should_have_message("hope") }
19
+
20
+ asserts_topic.kind_of(Riot::Message)
21
+ asserts(:to_s).equals(%q[should have "hope"])
22
+ end
23
+
24
+ context "receiving #expected_message" do
25
+ setup { topic.expected_message("hope") }
26
+
27
+ asserts_topic.kind_of(Riot::Message)
28
+ asserts(:to_s).equals(%q[expected "hope"])
29
+ end
30
+ end # An AssertionMacro instance
@@ -10,15 +10,15 @@ context "An assigns assertion macro" do
10
10
  assertion_test_passes("when foo is defined") { topic.assigns(:foo) }
11
11
  assertion_test_passes("when foo is defined with expected value") { topic.assigns(:foo, 1) }
12
12
 
13
- assertion_test_fails("when foo does not match expectation", "expected @foo to be equal to 2, not 1") do
13
+ assertion_test_fails("when foo does not match expectation", "expected :foo to be equal to 2, not 1") do
14
14
  topic.assigns(:foo, 2)
15
15
  end
16
16
 
17
- assertion_test_fails("when bar is not define", "expected @bar to be assigned a value") do
17
+ assertion_test_fails("when bar is not define", "expected :bar to be assigned a value") do
18
18
  topic.assigns(:bar)
19
19
  end
20
20
 
21
- assertion_test_fails("when var assigned nil value", "expected @nil_val to be assigned a value") do
21
+ assertion_test_fails("when var assigned nil value", "expected :nil_val to be assigned a value") do
22
22
  topic.assigns(:nil_val)
23
23
  end
24
24
  end # An assigns assertion macro
@@ -24,15 +24,8 @@ context "An equals assertion macro" do
24
24
  Riot::Assertion.new("blue") { 31415 }
25
25
  end
26
26
 
27
- asserts(":pass when in expected range") do
28
- topic.equals(30000..32000).run(Riot::Situation.new) == [:pass, "is equal to 30000..32000"]
29
- end
30
-
31
- context "when not in expected range" do
32
- setup { topic.equals(32000..33000).run(Riot::Situation.new) }
33
-
34
- asserts(":fail") { topic.first == :fail }
35
- asserts("message") { topic.last == %Q{expected 32000..33000, not 31415} }
27
+ asserts("failure") do
28
+ topic.equals(30000..32000).run(Riot::Situation.new) == [:fail, "expected 30000..32000, not 31415"]
36
29
  end
37
30
  end # with numeric topic
38
31
 
@@ -0,0 +1,36 @@
1
+ require 'teststrap'
2
+
3
+ # Using == to verify the test because this is the test for :equals itself. Look at assertion_test_passes
4
+ # and assertion_test_fails for testing other macros.
5
+
6
+ context "An equivalent_to assertion macro" do
7
+ setup do
8
+ Riot::Assertion.new("red") { "what" }
9
+ end
10
+
11
+ asserts("String is equivalent to 'what'") do
12
+ topic.equivalent_to(String).run(Riot::Situation.new) == [:pass, %Q{is equivalent to String}]
13
+ end
14
+
15
+ asserts("an array is not equivalent to 'what'") do
16
+ topic.equivalent_to([]).run(Riot::Situation.new) == [:fail, %Q{expected "what" to be equivalent to []}]
17
+ end
18
+
19
+ context "with numeric topic" do
20
+ setup do
21
+ Riot::Assertion.new("blue") { 31413 }
22
+ end
23
+
24
+ asserts(":pass when in expected range") do
25
+ topic.equivalent_to(30000..32000).run(Riot::Situation.new) == [:pass, "is equivalent to 30000..32000"]
26
+ end
27
+
28
+ context "when not in expected range" do
29
+ setup { topic.equivalent_to(32000..33000).run(Riot::Situation.new) }
30
+
31
+ asserts(":fail") { topic.first == :fail }
32
+ asserts("message") { topic.last == %Q{expected 31413 to be equivalent to 32000..33000} }
33
+ end
34
+ end # with numeric topic
35
+
36
+ end # An equivalent_to assertion macro
@@ -4,6 +4,7 @@ context "A respond_to assertion macro" do
4
4
  setup { Riot::Assertion.new("foo") { "bar" } }
5
5
 
6
6
  assertion_test_passes("when method is defined", "responds to :each_byte") { topic.respond_to(:each_byte) }
7
+ assertion_test_passes("using responds_to alias", "responds to :length") { topic.responds_to(:length) }
7
8
 
8
9
  assertion_test_fails("when method not defined", "expected method :goofballs is not defined") do
9
10
  topic.respond_to(:goofballs)
@@ -14,10 +14,10 @@ context "A size assertion macro" do
14
14
  assert_size("washington", 9..12)
15
15
  end
16
16
 
17
- assertion_test_fails("when string's size is not as expected", "size of \"washington\" expected to be 11 but is 10") do
17
+ assertion_test_fails("when string's size is not as expected", "expected size of \"washington\" to be 11, not 10") do
18
18
  assert_size("washington", 11)
19
19
  end
20
- assertion_test_fails("when string's size is out of range", "size of \"washington\" expected to be 11..13 but is 10") do
20
+ assertion_test_fails("when string's size is out of range", "expected size of \"washington\" to be 11..13, not 10") do
21
21
  assert_size("washington", 11..13)
22
22
  end
23
23
 
@@ -25,10 +25,10 @@ context "A size assertion macro" do
25
25
  assertion_test_passes("when an array's size is in given range", "is of size 3..4") do
26
26
  assert_size([1, 2, 3], 3..4)
27
27
  end
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
28
+ assertion_test_fails("when an array's size is not as expected", "expected size of [1, 2, 3] to be 2, not 3") do
29
29
  assert_size([1, 2, 3], 2)
30
30
  end
31
- assertion_test_fails("when an array's size is out of range", "size of [1, 2, 3] expected to be 4..6 but is 3") do
31
+ assertion_test_fails("when an array's size is out of range", "expected size of [1, 2, 3] to be 4..6, not 3") do
32
32
  assert_size([1, 2, 3], 4..6)
33
33
  end
34
34
 
@@ -38,10 +38,10 @@ context "A size assertion macro" do
38
38
  assertion_test_passes("when a hash size is in range", "is of size 1...3") do
39
39
  assert_size({:name => 'washington'}, 1...3)
40
40
  end
41
- assertion_test_fails("when a hash size is not as expected", "size of {} expected to be 2 but is 0") do
41
+ assertion_test_fails("when a hash size is not as expected", "expected size of {} to be 2, not 0") do
42
42
  assert_size({}, 2)
43
43
  end
44
- assertion_test_fails("when a hash size is out of range", "size of {} expected to be 2...4 but is 0") do
44
+ assertion_test_fails("when a hash size is out of range", "expected size of {} to be 2...4, not 0") do
45
45
  assert_size({}, 2...4)
46
46
  end
47
47
  end
@@ -6,7 +6,7 @@ context "An assertion" do
6
6
  asserts("to_s") { topic.to_s == "foo" }
7
7
 
8
8
  asserts(":pass is returned when evaluated") do
9
- topic.run(Riot::Situation.new) == [:pass, nil]
9
+ topic.run(Riot::Situation.new) == [:pass, ""]
10
10
  end
11
11
  end # that is passing
12
12
 
@@ -0,0 +1,82 @@
1
+ require 'benchmark'
2
+
3
+ class BlankSlate
4
+ instance_methods.each { |meth| undef_method(meth) unless meth =~ /^__/ }
5
+ end
6
+
7
+ class NormalMessage < BlankSlate
8
+ def initialize(*phrases)
9
+ @message = ""; _phrase(*phrases)
10
+ end
11
+
12
+ def to_s; @message; end
13
+
14
+ def method_missing(meth, *phrases, &blk) push(meth.to_s.gsub('_', ' ')); _phrase(*phrases); end
15
+
16
+ def comma(str, *phrases) raise Exception, "Whoops - comma"; end
17
+ def but(*phrases); comma("but", *phrases); end
18
+ def not(*phrases); comma("not", *phrases); end
19
+ def push(str) raise Exception, "Whoops - push"; end
20
+ private
21
+ def _concat(str) (@message << str).strip!; self; end
22
+ def _phrase(*phrases) phrases.each { |phrase| push(phrase.inspect) }; self; end
23
+ end # Message
24
+
25
+ # +
26
+
27
+ class PlusMessage < NormalMessage
28
+ def comma(str, *phrases) _concat(", " + str); _phrase(*phrases); end
29
+ def push(str) _concat(" " + str); end
30
+ end # Message
31
+
32
+ # <<
33
+
34
+ class AppendMessage < NormalMessage
35
+ def comma(str, *phrases) _concat(", " << str); _phrase(*phrases); end
36
+ def push(str) _concat(" " << str); end
37
+ end # Message
38
+
39
+ # Experimental
40
+
41
+ class ExperimentalMessage < BlankSlate
42
+ def initialize(*phrases)
43
+ @chunks = []; _inspect(phrases)
44
+ end
45
+
46
+ def to_s; @chunks.join; end
47
+
48
+ def method_missing(meth, *phrases, &blk) push(meth.to_s.gsub('_', ' ')); _inspect(phrases); end
49
+
50
+ def comma(str, *phrases) _concat([", ", str]); _inspect(phrases); end
51
+ def but(*phrases); comma("but", *phrases); end
52
+ def not(*phrases); comma("not", *phrases); end
53
+ def push(str) _concat([" ", str]); end
54
+ private
55
+ def _concat(chunks) @chunks.concat(chunks); self; end
56
+ def _inspect(phrases) phrases.each { |phrase| push(phrase.inspect) }; self; end
57
+ end # Message
58
+
59
+ #
60
+ # Benchmarking
61
+
62
+ Benchmark.bmbm do |x|
63
+ def message_test(klass)
64
+ STDOUT.puts(klass.new.comma("yes").push("no").foo.bar("baz").to_s)
65
+ 10_000.times do
66
+ klass.new.comma("yes").push("no").foo.bar("baz").to_s
67
+ end
68
+ end
69
+
70
+ x.report("+ based message") do
71
+ message_test(PlusMessage)
72
+ end
73
+
74
+ x.report("<< based message") do
75
+ message_test(AppendMessage)
76
+ end
77
+
78
+ x.report("experimental message") do
79
+ message_test(ExperimentalMessage)
80
+ end
81
+ end
82
+
@@ -88,13 +88,12 @@ context "The asserts_topic shortcut" do
88
88
  topic.equals("bar").run(situation)
89
89
  end.equals([:pass, %Q{is equal to "bar"}])
90
90
 
91
- asserts(:to_s).equals("asserts topic")
91
+ asserts(:to_s).equals("asserts that it")
92
92
 
93
93
  context "with an explicit description" do
94
94
  setup { Riot::Context.new("foo") {}.asserts_topic("get some") }
95
95
  asserts(:to_s).equals("asserts get some")
96
96
  end
97
-
98
97
  end # The asserts_topic shortcut
99
98
 
100
99
  context "Using a hookup" do
@@ -108,3 +107,19 @@ context "Using a hookup" do
108
107
 
109
108
  asserts_topic.equals("I'm a string")
110
109
  end # Using a hookup
110
+
111
+ context "Making a new context" do
112
+ asserts("RootContext is used if nil parent is provided") do
113
+ Riot::Context.new("hello", nil) {}.parent
114
+ end.kind_of(Riot::RootContext)
115
+ end # Making a context
116
+
117
+ context "A context with a helper" do
118
+ setup { "foo" }
119
+
120
+ helper(:upcase) { topic.upcase }
121
+ helper(:append) {|str| topic + str }
122
+
123
+ asserts("executing the helper") { upcase }.equals("FOO")
124
+ asserts("calling a helper with an argument") { append("bar") }.equals("foobar")
125
+ end