riot 0.10.11 → 0.10.12.pre

Sign up to get free protection for your applications and to get access to all the features.
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