riot 0.10.13 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,58 @@
1
+ *0.11.0*
2
+
3
+ * Added option to Context#setup which puts the specific setup block at the beginning of the setups to be called for a context. Also useful for middlewares. [jaknowlden]
4
+
5
+ context "Foo" do
6
+ setup { puts "called second" }
7
+ setup { puts "called third" }
8
+ setup(true) { puts "called first" }
9
+ end # Foo
10
+
11
+ * Added idea of options for a context. This is another feature picked up from riot-rails work. [jaknowlden]
12
+
13
+ Essentially, these are useful for middlewares. For instance, if you wanted to tell a middleware that was looking for a "transactional" option before running code in a transaction block, you might do this:
14
+
15
+ context User do
16
+ set :transactional, true
17
+ end # User
18
+
19
+ The middleware might do something with it:
20
+
21
+ class TransactionalMiddleware < Riot::ContextMiddleware
22
+ register
23
+
24
+ def handle?(context) context.option(:transactional) == true; end
25
+
26
+ def prepare(context)
27
+ # transactional stuff
28
+ end
29
+ end # TransactionalMiddleware
30
+
31
+ You can call set as many times as you like
32
+
33
+ context User do
34
+ set :transactional, true
35
+ set :foo, :bar
36
+ end
37
+
38
+ * ContextMiddleware: a construction pattern that allows for custom code to be applied to any context given that the middleware chooses to. This is something I started building into riot-rails and decided it was useful enough to just put it into riot itself. [jaknowlden]
39
+
40
+ If, for instance, you wanted to add a setup with some stuff only if the context description was equal to "Your Mom":
41
+
42
+ class YourMomMiddleware < Riot::ContextMiddleware
43
+ register
44
+
45
+ def handle?(context)
46
+ context.description == "Your Mom"
47
+ end
48
+
49
+ def prepare(context)
50
+ context.setup do
51
+ "your mom is the topic"
52
+ end
53
+ end
54
+ end # YourMomMiddleware
55
+
1
56
  *0.10.13*
2
57
 
3
58
  * Helpers are now run with other setups, not separately. Which means you could use a helper in a setup. [jaknowlden]
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.10.13
1
+ 0.11.0
@@ -1,15 +1,62 @@
1
1
  module Riot
2
2
  RootContext = Struct.new(:setups, :teardowns, :detailed_description)
3
3
 
4
- module ContextHelpers
4
+ class ContextMiddleware
5
+ # Registers the current middleware class with Riot so that it may be included in the set of middlewares
6
+ # Riot will poke before executing a Context.
7
+ #
8
+ # class MyContextMiddleware < Riot::ContextMiddleware
9
+ # register
10
+ # def handle?(context); ...; end
11
+ # def prepare(context); ...; end
12
+ # end
13
+ def self.register; Context.middlewares << self.new; end
14
+
15
+ # Called prior to a Context being executed. If this method returns true, +call+ will be called. This
16
+ # methods expects to receive an instance of the Context to be executed. Generally, you will inspect
17
+ # various aspects of the Context to determine if this middleware is meant to be used.
18
+ def handle?(context); false; end
19
+
20
+ # The meat of the middleware. Because you have access to the Context, you can add your own setups,
21
+ # hookups, etc. +call+ will be called before any tests are run, but after the Context is configured.
22
+ def call(context); end
23
+ end
24
+
25
+ module ContextClassOverrides
5
26
  def assertion_class; Assertion; end
6
27
  def situation_class; Situation; end
7
28
  end
8
29
 
9
- # You make your assertions within a Context. The context stores setup and
10
- # teardown blocks, and allows for nesting and refactoring into helpers.
30
+ module ContextOptions
31
+ # Set options for the specific context. These options will generally be used for context middleware.
32
+ # Riot::Context does not currently look at any options.
33
+ #
34
+ # context "Foo" do
35
+ # set :transactional, true
36
+ # end
37
+ def set(key, value) options[key] = value; end
38
+
39
+ # Returns the value of a set option. The key must match exactly, symbols and strings are not
40
+ # interchangeable.
41
+ #
42
+ # @return [Object]
43
+ def option(key) options[key]; end
44
+ private
45
+ def options; @options ||= {}; end
46
+ end
47
+
48
+ # You make your assertions within a Context. The context stores setup and teardown blocks, and allows for
49
+ # nesting and refactoring into helpers. Extension developers may also configure ContextMiddleware objects
50
+ # in order to extend the functionality of a Context.
11
51
  class Context
12
- include ContextHelpers
52
+ include ContextClassOverrides
53
+ include ContextOptions
54
+
55
+ # The set of middleware helpers configured for the current test space.
56
+ #
57
+ # @return [Array]
58
+ def self.middlewares; @middlewares ||= []; end
59
+
13
60
  # The description of the context.
14
61
  #
15
62
  # @return [String]
@@ -25,6 +72,7 @@ module Riot
25
72
  @description = description
26
73
  @contexts, @setups, @assertions, @teardowns = [], [], [], []
27
74
  self.instance_eval(&definition)
75
+ prepare_middleware
28
76
  end
29
77
 
30
78
  # Create a new test context.
@@ -33,7 +81,7 @@ module Riot
33
81
  def context(description, &definition)
34
82
  new_context(description, self.class, &definition)
35
83
  end
36
-
84
+
37
85
  # Returns an ordered list of the setup blocks for the context.
38
86
  #
39
87
  # @return [Array[Riot::RunnableBlock]]
@@ -58,8 +106,13 @@ module Riot
58
106
  # setup { topic * 2 }
59
107
  # asserts(:length).equals(6)
60
108
  # end
61
- def setup(&definition)
62
- (@setups << Setup.new(&definition)).last
109
+ #
110
+ # If you provide +true+ as the first argument, the setup will be unshifted onto the list of setups,
111
+ # ensuring it will be run before any other setups. This is really only useful for context middlewares.
112
+ def setup(premium=false, &definition)
113
+ setup = Setup.new(&definition)
114
+ premium ? @setups.unshift(setup) : @setups.push(setup)
115
+ setup
63
116
  end
64
117
 
65
118
  # Helpers are essentially methods accessible within a situation.
@@ -90,7 +143,9 @@ module Riot
90
143
  setup { self.instance_eval(&definition); topic }
91
144
  end
92
145
 
93
- # Add a teardown block.
146
+ # Add a teardown block. You may define multiple of these as well.
147
+ #
148
+ # teardown { Bombs.drop! }
94
149
  def teardown(&definition)
95
150
  (@teardowns << Setup.new(&definition)).last
96
151
  end
@@ -113,11 +168,17 @@ module Riot
113
168
  # Passing a Symbol to +asserts+ enables this behaviour. For more information on
114
169
  # assertion macros, see {Riot::AssertionMacro}.
115
170
  #
116
- # @param [String, Symbol] what the property being tested
171
+ # @param [String, Symbol] the property being tested
117
172
  def asserts(what, &definition)
118
173
  new_assertion("asserts", what, &definition)
119
174
  end
120
175
 
176
+ # Same as #asserts, except it uses the phrase "should" in the report output. Sometimes you feel like a
177
+ # nut, sometimes you don't.
178
+ #
179
+ # should("ensure expected") { "bar" }.equals("bar")
180
+ #
181
+ # @param [String, Symbol] the property being tested
121
182
  def should(what, &definition)
122
183
  new_assertion("should", what, &definition)
123
184
  end
@@ -146,6 +207,10 @@ module Riot
146
207
 
147
208
  private
148
209
 
210
+ def prepare_middleware
211
+ Context.middlewares.each { |middleware| middleware.call(self) if middleware.handle?(self) }
212
+ end
213
+
149
214
  def runnables
150
215
  setups + @assertions + teardowns
151
216
  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.13"
8
+ s.version = "0.11.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{2010-03-01}
12
+ s.date = %q{2010-05-17}
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 = [
@@ -70,7 +70,9 @@ Gem::Specification.new do |s|
70
70
  "test/core/assertion_macros/same_elements_test.rb",
71
71
  "test/core/assertion_macros/size_test.rb",
72
72
  "test/core/assertion_test.rb",
73
+ "test/core/context_middleware_test.rb",
73
74
  "test/core/context_test.rb",
75
+ "test/core/context_with_options_test.rb",
74
76
  "test/core/message_test.rb",
75
77
  "test/core/report_test.rb",
76
78
  "test/core/setup_test.rb",
@@ -82,7 +84,7 @@ Gem::Specification.new do |s|
82
84
  s.homepage = %q{http://github.com/thumblemonks/riot}
83
85
  s.rdoc_options = ["--charset=UTF-8"]
84
86
  s.require_paths = ["lib"]
85
- s.rubygems_version = %q{1.3.5}
87
+ s.rubygems_version = %q{1.3.6}
86
88
  s.summary = %q{An extremely fast, expressive, and context-driven unit-testing framework. Protest the slow test.}
87
89
  s.test_files = [
88
90
  "test/benchmark/colorize.rb",
@@ -107,7 +109,9 @@ Gem::Specification.new do |s|
107
109
  "test/core/assertion_macros/same_elements_test.rb",
108
110
  "test/core/assertion_macros/size_test.rb",
109
111
  "test/core/assertion_test.rb",
112
+ "test/core/context_middleware_test.rb",
110
113
  "test/core/context_test.rb",
114
+ "test/core/context_with_options_test.rb",
111
115
  "test/core/message_test.rb",
112
116
  "test/core/report_test.rb",
113
117
  "test/core/setup_test.rb",
@@ -0,0 +1,90 @@
1
+ require 'teststrap'
2
+
3
+ context "ContextMiddleware" do
4
+ setup { Riot::ContextMiddleware.new }
5
+ teardown { Riot::Context.middlewares.clear }
6
+
7
+ asserts("handle? with context") { topic.handle?("Foo") }.equals(false)
8
+ asserts("call with context") { topic.call("Foo") }.nil
9
+
10
+ context "registration" do
11
+ setup { Class.new(Riot::ContextMiddleware) { register } }
12
+ asserts("registered middlewares list") { Riot::Context.middlewares }.size(1)
13
+ asserts("registered middleware") { Riot::Context.middlewares.first }.kind_of(Riot::ContextMiddleware)
14
+ end # registration
15
+
16
+ context "that is not meant to be used" do
17
+ hookup do
18
+ Class.new(Riot::ContextMiddleware) do
19
+ register
20
+ def handle?(context) context.description == "Bar"; end
21
+ def call(context) context.setup { "fooberries" }; end
22
+ end
23
+ end
24
+
25
+ setup do
26
+ Riot::Context.new("Foo") { asserts_topic.nil }.run(MockReporter.new)
27
+ end
28
+
29
+ asserts("tests passed") { topic.passes }.equals(1)
30
+ end # that is not meant to be used
31
+
32
+ context "that is meant to be used" do
33
+ hookup do
34
+ Class.new(Riot::ContextMiddleware) do
35
+ register
36
+ def handle?(context); true; end
37
+ def call(context) context.setup { "fooberries" }; end
38
+ end
39
+ end
40
+
41
+ setup do
42
+ Riot::Context.new("Foo") { asserts_topic.equals("fooberries") }.run(MockReporter.new)
43
+ end
44
+
45
+ asserts("tests passed") { topic.passes }.equals(1)
46
+ end # that is meant to be used
47
+
48
+ context "applied in multiples" do
49
+ hookup do
50
+ Class.new(Riot::ContextMiddleware) do
51
+ register
52
+ def handle?(context); true; end
53
+ def call(context) context.setup { "foo" }; end
54
+ end
55
+ end
56
+
57
+ hookup do
58
+ Class.new(Riot::ContextMiddleware) do
59
+ register
60
+ def handle?(context); true; end
61
+ def call(context) context.setup { topic + "berries" }; end
62
+ end
63
+ end
64
+
65
+ setup do
66
+ Riot::Context.new("Foo") { asserts_topic.equals("fooberries") }.run(MockReporter.new)
67
+ end
68
+
69
+ asserts("tests passed") { topic.passes }.equals(1)
70
+ end # that are not exclusive
71
+
72
+ context "has access to options" do
73
+ hookup do
74
+ Class.new(Riot::ContextMiddleware) do
75
+ register
76
+ def handle?(context); context.option(:foo) == "bar"; end
77
+ def call(context) context.setup { "fooberries" }; end
78
+ end
79
+ end
80
+
81
+ setup do
82
+ Riot::Context.new("Foo") do
83
+ set :foo, "bar"
84
+ asserts_topic.equals("fooberries")
85
+ end.run(MockReporter.new)
86
+ end
87
+
88
+ asserts("tests passed") { topic.passes }.equals(1)
89
+ end # has access to options
90
+ end # ContextMiddleware
@@ -124,13 +124,25 @@ context "A context with a helper" do
124
124
  asserts("calling a helper with an argument") { append("bar") }.equals("foobar")
125
125
  end
126
126
 
127
+ context "A context with nested descriptions as classes" do
128
+ setup { Riot::Context.new(String) {}.context(Hash) {} }
129
+ asserts(:description).equals { Hash }
130
+ asserts(:detailed_description).equals("String Hash")
131
+ end
132
+
133
+ class SingletonArray
134
+ def self.<<(value); values << value; end
135
+ def self.values; @@values ||= []; end
136
+ end
127
137
 
128
- context "A context with a description" do
129
- Foo, Bar = Class.new {}, Class.new {}
138
+ context "A context with premium_setup" do
130
139
  setup do
131
- Riot::Context.new(Foo) {}.context(Bar) {}
140
+ Riot::Context.new("Foo") do
141
+ setup { SingletonArray << "baz" }
142
+ setup(true) { SingletonArray << "bar" }
143
+ setup(true) { SingletonArray << "foo" }
144
+ end.run(MockReporter.new)
132
145
  end
133
146
 
134
- asserts(:description).equals(Bar)
135
- asserts(:detailed_description).equals("Foo Bar")
147
+ asserts("order of setups ensures topic") { SingletonArray.values }.equals(%w[foo bar baz])
136
148
  end
@@ -0,0 +1,16 @@
1
+ require 'teststrap'
2
+
3
+ context "Context with options" do
4
+ setup do
5
+ Riot::Context.new("Foo") do
6
+ set :foo, "bar"
7
+ set "bar", 2
8
+ end
9
+ end
10
+
11
+ asserts_topic.responds_to(:option)
12
+
13
+ asserts("option :foo") { topic.option(:foo) }.equals("bar")
14
+ asserts("option \"foo\"") { topic.option("foo") }.nil
15
+ asserts("option \"bar\"") { topic.option("bar") }.equals(2)
16
+ end # Context with options
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.13
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 11
8
+ - 0
9
+ version: 0.11.0
5
10
  platform: ruby
6
11
  authors:
7
12
  - Justin 'Gus' Knowlden
@@ -9,29 +14,33 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2010-03-01 00:00:00 -06:00
17
+ date: 2010-05-17 00:00:00 -05:00
13
18
  default_executable:
14
19
  dependencies:
15
20
  - !ruby/object:Gem::Dependency
16
21
  name: rr
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
20
24
  requirements:
21
25
  - - ">="
22
26
  - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
23
29
  version: "0"
24
- version:
30
+ type: :runtime
31
+ version_requirements: *id001
25
32
  - !ruby/object:Gem::Dependency
26
33
  name: term-ansicolor
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
34
+ prerelease: false
35
+ requirement: &id002 !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - ">="
32
38
  - !ruby/object:Gem::Version
39
+ segments:
40
+ - 0
33
41
  version: "0"
34
- version:
42
+ type: :runtime
43
+ version_requirements: *id002
35
44
  description: An extremely fast, expressive, and context-driven unit-testing framework. A replacement for all other testing frameworks. Protest the slow test.
36
45
  email: gus@gusg.us
37
46
  executables: []
@@ -95,7 +104,9 @@ files:
95
104
  - test/core/assertion_macros/same_elements_test.rb
96
105
  - test/core/assertion_macros/size_test.rb
97
106
  - test/core/assertion_test.rb
107
+ - test/core/context_middleware_test.rb
98
108
  - test/core/context_test.rb
109
+ - test/core/context_with_options_test.rb
99
110
  - test/core/message_test.rb
100
111
  - test/core/report_test.rb
101
112
  - test/core/setup_test.rb
@@ -116,18 +127,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
116
127
  requirements:
117
128
  - - ">="
118
129
  - !ruby/object:Gem::Version
130
+ segments:
131
+ - 0
119
132
  version: "0"
120
- version:
121
133
  required_rubygems_version: !ruby/object:Gem::Requirement
122
134
  requirements:
123
135
  - - ">="
124
136
  - !ruby/object:Gem::Version
137
+ segments:
138
+ - 0
125
139
  version: "0"
126
- version:
127
140
  requirements: []
128
141
 
129
142
  rubyforge_project:
130
- rubygems_version: 1.3.5
143
+ rubygems_version: 1.3.6
131
144
  signing_key:
132
145
  specification_version: 3
133
146
  summary: An extremely fast, expressive, and context-driven unit-testing framework. Protest the slow test.
@@ -154,7 +167,9 @@ test_files:
154
167
  - test/core/assertion_macros/same_elements_test.rb
155
168
  - test/core/assertion_macros/size_test.rb
156
169
  - test/core/assertion_test.rb
170
+ - test/core/context_middleware_test.rb
157
171
  - test/core/context_test.rb
172
+ - test/core/context_with_options_test.rb
158
173
  - test/core/message_test.rb
159
174
  - test/core/report_test.rb
160
175
  - test/core/setup_test.rb