francois-shoulda 2.0.5.4 → 2.10.1
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.rdoc +60 -10
- data/Rakefile +7 -7
- data/lib/shoulda.rb +7 -15
- data/lib/shoulda/action_controller.rb +28 -0
- data/lib/shoulda/action_controller/helpers.rb +47 -0
- data/lib/shoulda/action_controller/macros.rb +277 -0
- data/lib/shoulda/action_controller/matchers.rb +37 -0
- data/lib/shoulda/action_controller/matchers/assign_to_matcher.rb +109 -0
- data/lib/shoulda/action_controller/matchers/filter_param_matcher.rb +57 -0
- data/lib/shoulda/action_controller/matchers/render_with_layout_matcher.rb +81 -0
- data/lib/shoulda/action_controller/matchers/respond_with_content_type_matcher.rb +70 -0
- data/lib/shoulda/action_controller/matchers/respond_with_matcher.rb +81 -0
- data/lib/shoulda/action_controller/matchers/route_matcher.rb +93 -0
- data/lib/shoulda/action_controller/matchers/set_session_matcher.rb +87 -0
- data/lib/shoulda/action_controller/matchers/set_the_flash_matcher.rb +85 -0
- data/lib/shoulda/action_mailer.rb +1 -1
- data/lib/shoulda/action_mailer/assertions.rb +32 -33
- data/lib/shoulda/action_view.rb +10 -0
- data/lib/shoulda/action_view/macros.rb +56 -0
- data/lib/shoulda/active_record.rb +6 -2
- data/lib/shoulda/active_record/assertions.rb +62 -89
- data/lib/shoulda/active_record/helpers.rb +40 -0
- data/lib/shoulda/active_record/macros.rb +520 -684
- data/lib/shoulda/active_record/matchers.rb +42 -0
- data/lib/shoulda/active_record/matchers/allow_mass_assignment_of_matcher.rb +83 -0
- data/lib/shoulda/active_record/matchers/allow_value_matcher.rb +102 -0
- data/lib/shoulda/active_record/matchers/association_matcher.rb +226 -0
- data/lib/shoulda/active_record/matchers/ensure_inclusion_of_matcher.rb +87 -0
- data/lib/shoulda/active_record/matchers/ensure_length_of_matcher.rb +141 -0
- data/lib/shoulda/active_record/matchers/have_db_column_matcher.rb +169 -0
- data/lib/shoulda/active_record/matchers/have_index_matcher.rb +105 -0
- data/lib/shoulda/active_record/matchers/have_named_scope_matcher.rb +125 -0
- data/lib/shoulda/active_record/matchers/have_readonly_attribute_matcher.rb +59 -0
- data/lib/shoulda/active_record/matchers/validate_acceptance_of_matcher.rb +41 -0
- data/lib/shoulda/active_record/matchers/validate_numericality_of_matcher.rb +39 -0
- data/lib/shoulda/active_record/matchers/validate_presence_of_matcher.rb +60 -0
- data/lib/shoulda/active_record/matchers/validate_uniqueness_of_matcher.rb +148 -0
- data/lib/shoulda/active_record/matchers/validation_matcher.rb +56 -0
- data/lib/shoulda/assertions.rb +50 -40
- data/lib/shoulda/autoload_macros.rb +46 -0
- data/lib/shoulda/context.rb +124 -126
- data/lib/shoulda/helpers.rb +5 -7
- data/lib/shoulda/macros.rb +63 -64
- data/lib/shoulda/private_helpers.rb +16 -18
- data/lib/shoulda/rails.rb +5 -11
- data/lib/shoulda/rspec.rb +11 -0
- data/lib/shoulda/tasks/list_tests.rake +6 -1
- data/lib/shoulda/test_unit.rb +19 -0
- data/rails/init.rb +7 -1
- data/test/README +2 -2
- data/test/fail_macros.rb +15 -15
- data/test/fixtures/tags.yml +1 -1
- data/test/functional/posts_controller_test.rb +46 -26
- data/test/functional/users_controller_test.rb +0 -19
- data/test/matchers/active_record/allow_mass_assignment_of_matcher_test.rb +68 -0
- data/test/matchers/active_record/allow_value_matcher_test.rb +41 -0
- data/test/matchers/active_record/association_matcher_test.rb +258 -0
- data/test/matchers/active_record/ensure_inclusion_of_matcher_test.rb +80 -0
- data/test/matchers/active_record/ensure_length_of_matcher_test.rb +158 -0
- data/test/matchers/active_record/have_db_column_matcher_test.rb +169 -0
- data/test/matchers/active_record/have_index_matcher_test.rb +74 -0
- data/test/matchers/active_record/have_named_scope_matcher_test.rb +65 -0
- data/test/matchers/active_record/have_readonly_attributes_matcher_test.rb +29 -0
- data/test/matchers/active_record/validate_acceptance_of_matcher_test.rb +44 -0
- data/test/matchers/active_record/validate_numericality_of_matcher_test.rb +52 -0
- data/test/matchers/active_record/validate_presence_of_matcher_test.rb +86 -0
- data/test/matchers/active_record/validate_uniqueness_of_matcher_test.rb +147 -0
- data/test/matchers/controller/assign_to_matcher_test.rb +35 -0
- data/test/matchers/controller/filter_param_matcher_test.rb +32 -0
- data/test/matchers/controller/render_with_layout_matcher_test.rb +33 -0
- data/test/matchers/controller/respond_with_content_type_matcher_test.rb +27 -0
- data/test/matchers/controller/respond_with_matcher_test.rb +106 -0
- data/test/matchers/controller/route_matcher_test.rb +58 -0
- data/test/matchers/controller/set_session_matcher_test.rb +31 -0
- data/test/matchers/controller/set_the_flash_matcher.rb +41 -0
- data/test/model_builder.rb +106 -0
- data/test/other/autoload_macro_test.rb +18 -0
- data/test/other/helpers_test.rb +58 -0
- data/test/other/private_helpers_test.rb +1 -1
- data/test/other/should_test.rb +16 -16
- data/test/rails_root/app/controllers/posts_controller.rb +6 -5
- data/test/rails_root/app/models/pets/dog.rb +10 -0
- data/test/rails_root/app/models/treat.rb +3 -0
- data/test/rails_root/app/models/user.rb +4 -3
- data/test/rails_root/app/views/layouts/posts.rhtml +2 -0
- data/test/rails_root/config/database.yml +1 -1
- data/test/rails_root/config/environment.rb +1 -1
- data/test/rails_root/config/environments/{sqlite3.rb → test.rb} +0 -0
- data/test/rails_root/db/migrate/001_create_users.rb +3 -2
- data/test/rails_root/db/migrate/011_create_treats.rb +12 -0
- data/test/rails_root/test/shoulda_macros/custom_macro.rb +6 -0
- data/test/rails_root/vendor/gems/gem_with_macro-0.0.1/shoulda_macros/gem_macro.rb +6 -0
- data/test/rails_root/vendor/plugins/plugin_with_macro/shoulda_macros/plugin_macro.rb +6 -0
- data/test/rspec_test.rb +207 -0
- data/test/test_helper.rb +3 -1
- data/test/unit/address_test.rb +1 -23
- data/test/unit/dog_test.rb +5 -2
- data/test/unit/post_test.rb +7 -3
- data/test/unit/product_test.rb +2 -2
- data/test/unit/tag_test.rb +2 -1
- data/test/unit/user_test.rb +25 -9
- metadata +84 -23
- data/lib/shoulda/controller.rb +0 -30
- data/lib/shoulda/controller/formats/html.rb +0 -201
- data/lib/shoulda/controller/formats/xml.rb +0 -170
- data/lib/shoulda/controller/helpers.rb +0 -64
- data/lib/shoulda/controller/macros.rb +0 -316
- data/lib/shoulda/controller/resource_options.rb +0 -236
- data/test/rails_root/app/models/dog.rb +0 -5
@@ -0,0 +1,56 @@
|
|
1
|
+
module Shoulda # :nodoc:
|
2
|
+
module ActiveRecord # :nodoc:
|
3
|
+
module Matchers
|
4
|
+
|
5
|
+
class ValidationMatcher # :nodoc:
|
6
|
+
|
7
|
+
attr_reader :failure_message
|
8
|
+
|
9
|
+
def initialize(attribute)
|
10
|
+
@attribute = attribute
|
11
|
+
end
|
12
|
+
|
13
|
+
def negative_failure_message
|
14
|
+
@negative_failure_message || @failure_message
|
15
|
+
end
|
16
|
+
|
17
|
+
def matches?(subject)
|
18
|
+
@subject = subject
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def allows_value_of(value, message = nil)
|
25
|
+
allow = AllowValueMatcher.
|
26
|
+
new(value).
|
27
|
+
for(@attribute).
|
28
|
+
with_message(message)
|
29
|
+
if allow.matches?(@subject)
|
30
|
+
@negative_failure_message = allow.failure_message
|
31
|
+
true
|
32
|
+
else
|
33
|
+
@failure_message = allow.negative_failure_message
|
34
|
+
false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def disallows_value_of(value, message = nil)
|
39
|
+
disallow = AllowValueMatcher.
|
40
|
+
new(value).
|
41
|
+
for(@attribute).
|
42
|
+
with_message(message)
|
43
|
+
if disallow.matches?(@subject)
|
44
|
+
@failure_message = disallow.negative_failure_message
|
45
|
+
false
|
46
|
+
else
|
47
|
+
@negative_failure_message = disallow.failure_message
|
48
|
+
true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
data/lib/shoulda/assertions.rb
CHANGED
@@ -1,49 +1,59 @@
|
|
1
|
-
module
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
[
|
9
|
-
|
10
|
-
end
|
1
|
+
module Shoulda # :nodoc:
|
2
|
+
module Assertions
|
3
|
+
# Asserts that two arrays contain the same elements, the same number of times. Essentially ==, but unordered.
|
4
|
+
#
|
5
|
+
# assert_same_elements([:a, :b, :c], [:c, :a, :b]) => passes
|
6
|
+
def assert_same_elements(a1, a2, msg = nil)
|
7
|
+
[:select, :inject, :size].each do |m|
|
8
|
+
[a1, a2].each {|a| assert_respond_to(a, m, "Are you sure that #{a.inspect} is an array? It doesn't respond to #{m}.") }
|
9
|
+
end
|
11
10
|
|
12
|
-
|
13
|
-
|
11
|
+
assert a1h = a1.inject({}) { |h,e| h[e] = a1.select { |i| i == e }.size; h }
|
12
|
+
assert a2h = a2.inject({}) { |h,e| h[e] = a2.select { |i| i == e }.size; h }
|
14
13
|
|
15
|
-
|
16
|
-
|
14
|
+
assert_equal(a1h, a2h, msg)
|
15
|
+
end
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
17
|
+
# Asserts that the given collection contains item x. If x is a regular expression, ensure that
|
18
|
+
# at least one element from the collection matches x. +extra_msg+ is appended to the error message if the assertion fails.
|
19
|
+
#
|
20
|
+
# assert_contains(['a', '1'], /\d/) => passes
|
21
|
+
# assert_contains(['a', '1'], 'a') => passes
|
22
|
+
# assert_contains(['a', '1'], /not there/) => fails
|
23
|
+
def assert_contains(collection, x, extra_msg = "")
|
24
|
+
collection = [collection] unless collection.is_a?(Array)
|
25
|
+
msg = "#{x.inspect} not found in #{collection.to_a.inspect} #{extra_msg}"
|
26
|
+
case x
|
27
|
+
when Regexp
|
28
|
+
assert(collection.detect { |e| e =~ x }, msg)
|
29
|
+
else
|
30
|
+
assert(collection.include?(x), msg)
|
33
31
|
end
|
32
|
+
end
|
34
33
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
34
|
+
# Asserts that the given collection does not contain item x. If x is a regular expression, ensure that
|
35
|
+
# none of the elements from the collection match x.
|
36
|
+
def assert_does_not_contain(collection, x, extra_msg = "")
|
37
|
+
collection = [collection] unless collection.is_a?(Array)
|
38
|
+
msg = "#{x.inspect} found in #{collection.to_a.inspect} " + extra_msg
|
39
|
+
case x
|
40
|
+
when Regexp
|
41
|
+
assert(!collection.detect { |e| e =~ x }, msg)
|
42
|
+
else
|
43
|
+
assert(!collection.include?(x), msg)
|
46
44
|
end
|
47
45
|
end
|
46
|
+
|
47
|
+
# Asserts that the given matcher returns true when +target+ is passed to #matches?
|
48
|
+
def assert_accepts(matcher, target)
|
49
|
+
success = matcher.matches?(target)
|
50
|
+
assert_block(matcher.failure_message) { success }
|
51
|
+
end
|
52
|
+
|
53
|
+
# Asserts that the given matcher returns false when +target+ is passed to #matches?
|
54
|
+
def assert_rejects(matcher, target)
|
55
|
+
success = !matcher.matches?(target)
|
56
|
+
assert_block(matcher.negative_failure_message) { success }
|
57
|
+
end
|
48
58
|
end
|
49
59
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Shoulda # :nodoc:
|
2
|
+
# Call autoload_macros when you want to load test macros automatically in a non-Rails
|
3
|
+
# project (it's done automatically for Rails projects).
|
4
|
+
# You don't need to specify ROOT/test/shoulda_macros explicitly. Your custom macros
|
5
|
+
# are loaded automatically when you call autoload_macros.
|
6
|
+
#
|
7
|
+
# The first argument is the path to you application's root directory.
|
8
|
+
# All following arguments are directories relative to your root, which contain
|
9
|
+
# shoulda_macros subdirectories. These directories support the same kinds of globs as the
|
10
|
+
# Dir class.
|
11
|
+
#
|
12
|
+
# Basic usage (from a test_helper):
|
13
|
+
# Shoulda.autoload_macros(File.dirname(__FILE__) + '/..')
|
14
|
+
# will load everything in
|
15
|
+
# - your_app/test/shoulda_macros
|
16
|
+
#
|
17
|
+
# To load vendored macros as well:
|
18
|
+
# Shoulda.autoload_macros(APP_ROOT, 'vendor/*')
|
19
|
+
# will load everything in
|
20
|
+
# - APP_ROOT/vendor/*/shoulda_macros
|
21
|
+
# - APP_ROOT/test/shoulda_macros
|
22
|
+
#
|
23
|
+
# To load macros in an app with a vendor directory laid out like Rails':
|
24
|
+
# Shoulda.autoload_macros(APP_ROOT, 'vendor/{plugins,gems}/*')
|
25
|
+
# or
|
26
|
+
# Shoulda.autoload_macros(APP_ROOT, 'vendor/plugins/*', 'vendor/gems/*')
|
27
|
+
# will load everything in
|
28
|
+
# - APP_ROOT/vendor/plugins/*/shoulda_macros
|
29
|
+
# - APP_ROOT/vendor/gems/*/shoulda_macros
|
30
|
+
# - APP_ROOT/test/shoulda_macros
|
31
|
+
#
|
32
|
+
# If you prefer to stick testing dependencies away from your production dependencies:
|
33
|
+
# Shoulda.autoload_macros(APP_ROOT, 'vendor/*', 'test/vendor/*')
|
34
|
+
# will load everything in
|
35
|
+
# - APP_ROOT/vendor/*/shoulda_macros
|
36
|
+
# - APP_ROOT/test/vendor/*/shoulda_macros
|
37
|
+
# - APP_ROOT/test/shoulda_macros
|
38
|
+
def self.autoload_macros(root, *dirs)
|
39
|
+
dirs << File.join('test')
|
40
|
+
complete_dirs = dirs.map{|d| File.join(root, d, 'shoulda_macros')}
|
41
|
+
all_files = complete_dirs.inject([]){ |files, dir| files + Dir[File.join(dir, '*.rb')] }
|
42
|
+
all_files.each do |file|
|
43
|
+
require file
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/shoulda/context.rb
CHANGED
@@ -1,26 +1,24 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
def contexts # :nodoc:
|
8
|
-
@contexts ||= []
|
9
|
-
end
|
1
|
+
module Shoulda
|
2
|
+
class << self
|
3
|
+
attr_accessor :contexts
|
4
|
+
def contexts # :nodoc:
|
5
|
+
@contexts ||= []
|
6
|
+
end
|
10
7
|
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
def current_context # :nodoc:
|
9
|
+
self.contexts.last
|
10
|
+
end
|
14
11
|
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
def add_context(context) # :nodoc:
|
13
|
+
self.contexts.push(context)
|
14
|
+
end
|
18
15
|
|
19
|
-
|
20
|
-
|
21
|
-
end
|
16
|
+
def remove_context # :nodoc:
|
17
|
+
self.contexts.pop
|
22
18
|
end
|
19
|
+
end
|
23
20
|
|
21
|
+
module ClassMethods
|
24
22
|
# == Should statements
|
25
23
|
#
|
26
24
|
# Should statements are just syntactic sugar over normal Test::Unit test methods. A should block
|
@@ -29,7 +27,7 @@ module Thoughtbot # :nodoc:
|
|
29
27
|
#
|
30
28
|
# === Example:
|
31
29
|
#
|
32
|
-
# class UserTest
|
30
|
+
# class UserTest < Test::Unit::TestCase
|
33
31
|
#
|
34
32
|
# def setup
|
35
33
|
# @user = User.new("John", "Doe")
|
@@ -64,7 +62,7 @@ module Thoughtbot # :nodoc:
|
|
64
62
|
block_given? ? Shoulda.current_context.should(name, options, &blk) : Should.current_context.should_eventually(name)
|
65
63
|
else
|
66
64
|
context_name = self.name.gsub(/Test/, "")
|
67
|
-
context =
|
65
|
+
context = Shoulda::Context.new(context_name, self) do
|
68
66
|
block_given? ? should(name, options, &blk) : should_eventually(name)
|
69
67
|
end
|
70
68
|
context.build
|
@@ -104,7 +102,7 @@ module Thoughtbot # :nodoc:
|
|
104
102
|
# Just like should, but never runs, and instead prints an 'X' in the Test::Unit output.
|
105
103
|
def should_eventually(name, options = {}, &blk)
|
106
104
|
context_name = self.name.gsub(/Test/, "")
|
107
|
-
context =
|
105
|
+
context = Shoulda::Context.new(context_name, self) do
|
108
106
|
should_eventually(name, &blk)
|
109
107
|
end
|
110
108
|
context.build
|
@@ -118,7 +116,7 @@ module Thoughtbot # :nodoc:
|
|
118
116
|
#
|
119
117
|
# A context block can contain setup, should, should_eventually, and teardown blocks.
|
120
118
|
#
|
121
|
-
# class UserTest
|
119
|
+
# class UserTest < Test::Unit::TestCase
|
122
120
|
# context "A User instance" do
|
123
121
|
# setup do
|
124
122
|
# @user = User.find(:first)
|
@@ -135,7 +133,7 @@ module Thoughtbot # :nodoc:
|
|
135
133
|
# Contexts may be nested. Nested contexts run their setup blocks from out to in before each
|
136
134
|
# should statement. They then run their teardown blocks from in to out after each should statement.
|
137
135
|
#
|
138
|
-
# class UserTest
|
136
|
+
# class UserTest < Test::Unit::TestCase
|
139
137
|
# context "A User instance" do
|
140
138
|
# setup do
|
141
139
|
# @user = User.find(:first)
|
@@ -168,139 +166,139 @@ module Thoughtbot # :nodoc:
|
|
168
166
|
if Shoulda.current_context
|
169
167
|
Shoulda.current_context.context(name, &blk)
|
170
168
|
else
|
171
|
-
context =
|
169
|
+
context = Shoulda::Context.new(name, self, &blk)
|
172
170
|
context.build
|
173
171
|
end
|
174
172
|
end
|
173
|
+
end
|
175
174
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
175
|
+
class Context # :nodoc:
|
176
|
+
|
177
|
+
attr_accessor :name # my name
|
178
|
+
attr_accessor :parent # may be another context, or the original test::unit class.
|
179
|
+
attr_accessor :subcontexts # array of contexts nested under myself
|
180
|
+
attr_accessor :setup_blocks # blocks given via setup methods
|
181
|
+
attr_accessor :teardown_blocks # blocks given via teardown methods
|
182
|
+
attr_accessor :shoulds # array of hashes representing the should statements
|
183
|
+
attr_accessor :should_eventuallys # array of hashes representing the should eventually statements
|
184
|
+
|
185
|
+
def initialize(name, parent, &blk)
|
186
|
+
Shoulda.add_context(self)
|
187
|
+
self.name = name
|
188
|
+
self.parent = parent
|
189
|
+
self.setup_blocks = []
|
190
|
+
self.teardown_blocks = []
|
191
|
+
self.shoulds = []
|
192
|
+
self.should_eventuallys = []
|
193
|
+
self.subcontexts = []
|
194
|
+
|
195
|
+
merge_block(&blk)
|
196
|
+
Shoulda.remove_context
|
197
|
+
end
|
199
198
|
|
200
|
-
|
201
|
-
|
202
|
-
|
199
|
+
def merge_block(&blk)
|
200
|
+
blk.bind(self).call
|
201
|
+
end
|
203
202
|
|
204
|
-
|
205
|
-
|
206
|
-
|
203
|
+
def context(name, &blk)
|
204
|
+
self.subcontexts << Context.new(name, self, &blk)
|
205
|
+
end
|
207
206
|
|
208
|
-
|
209
|
-
|
210
|
-
|
207
|
+
def setup(&blk)
|
208
|
+
self.setup_blocks << blk
|
209
|
+
end
|
211
210
|
|
212
|
-
|
213
|
-
|
214
|
-
|
211
|
+
def teardown(&blk)
|
212
|
+
self.teardown_blocks << blk
|
213
|
+
end
|
215
214
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
215
|
+
def should(name, options = {}, &blk)
|
216
|
+
if block_given?
|
217
|
+
self.shoulds << { :name => name, :before => options[:before], :block => blk }
|
218
|
+
else
|
219
|
+
self.should_eventuallys << { :name => name }
|
220
|
+
end
|
221
|
+
end
|
223
222
|
|
224
|
-
|
225
|
-
|
226
|
-
|
223
|
+
def should_eventually(name, &blk)
|
224
|
+
self.should_eventuallys << { :name => name, :block => blk }
|
225
|
+
end
|
227
226
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
227
|
+
def full_name
|
228
|
+
parent_name = parent.full_name if am_subcontext?
|
229
|
+
return [parent_name, name].join(" ").strip
|
230
|
+
end
|
232
231
|
|
233
|
-
|
234
|
-
|
235
|
-
|
232
|
+
def am_subcontext?
|
233
|
+
parent.is_a?(self.class) # my parent is the same class as myself.
|
234
|
+
end
|
236
235
|
|
237
|
-
|
238
|
-
|
239
|
-
|
236
|
+
def test_unit_class
|
237
|
+
am_subcontext? ? parent.test_unit_class : parent
|
238
|
+
end
|
240
239
|
|
241
|
-
|
242
|
-
|
240
|
+
def create_test_from_should_hash(should)
|
241
|
+
test_name = ["test:", full_name, "should", "#{should[:name]}. "].flatten.join(' ').to_sym
|
243
242
|
|
244
|
-
|
245
|
-
|
246
|
-
|
243
|
+
if test_unit_class.instance_methods.include?(test_name.to_s)
|
244
|
+
warn " * WARNING: '#{test_name}' is already defined"
|
245
|
+
end
|
247
246
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
end
|
247
|
+
context = self
|
248
|
+
test_unit_class.send(:define_method, test_name) do
|
249
|
+
begin
|
250
|
+
context.run_parent_setup_blocks(self)
|
251
|
+
should[:before].bind(self).call if should[:before]
|
252
|
+
context.run_current_setup_blocks(self)
|
253
|
+
should[:block].bind(self).call
|
254
|
+
ensure
|
255
|
+
context.run_all_teardown_blocks(self)
|
258
256
|
end
|
259
257
|
end
|
258
|
+
end
|
260
259
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
260
|
+
def run_all_setup_blocks(binding)
|
261
|
+
run_parent_setup_blocks(binding)
|
262
|
+
run_current_setup_blocks(binding)
|
263
|
+
end
|
265
264
|
|
266
|
-
|
267
|
-
|
268
|
-
|
265
|
+
def run_parent_setup_blocks(binding)
|
266
|
+
self.parent.run_all_setup_blocks(binding) if am_subcontext?
|
267
|
+
end
|
269
268
|
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
end
|
269
|
+
def run_current_setup_blocks(binding)
|
270
|
+
setup_blocks.each do |setup_block|
|
271
|
+
setup_block.bind(binding).call
|
274
272
|
end
|
273
|
+
end
|
275
274
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
end
|
280
|
-
self.parent.run_all_teardown_blocks(binding) if am_subcontext?
|
275
|
+
def run_all_teardown_blocks(binding)
|
276
|
+
teardown_blocks.reverse.each do |teardown_block|
|
277
|
+
teardown_block.bind(binding).call
|
281
278
|
end
|
279
|
+
self.parent.run_all_teardown_blocks(binding) if am_subcontext?
|
280
|
+
end
|
282
281
|
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
end
|
282
|
+
def print_should_eventuallys
|
283
|
+
should_eventuallys.each do |should|
|
284
|
+
test_name = [full_name, "should", "#{should[:name]}. "].flatten.join(' ')
|
285
|
+
puts " * DEFERRED: " + test_name
|
288
286
|
end
|
287
|
+
end
|
289
288
|
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
end
|
294
|
-
|
295
|
-
subcontexts.each { |context| context.build }
|
296
|
-
|
297
|
-
print_should_eventuallys
|
289
|
+
def build
|
290
|
+
shoulds.each do |should|
|
291
|
+
create_test_from_should_hash(should)
|
298
292
|
end
|
299
293
|
|
300
|
-
|
301
|
-
test_unit_class.send(method, *args, &blk)
|
302
|
-
end
|
294
|
+
subcontexts.each { |context| context.build }
|
303
295
|
|
296
|
+
print_should_eventuallys
|
304
297
|
end
|
298
|
+
|
299
|
+
def method_missing(method, *args, &blk)
|
300
|
+
test_unit_class.send(method, *args, &blk)
|
301
|
+
end
|
302
|
+
|
305
303
|
end
|
306
304
|
end
|