shoulda-context 1.2.2 → 2.0.0
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.
- checksums.yaml +5 -5
- data/.gitignore +0 -1
- data/.hound.yml +3 -0
- data/.rubocop.yml +190 -0
- data/.ruby-version +1 -1
- data/.travis.yml +36 -2
- data/Appraisals +100 -29
- data/CHANGELOG.md +29 -0
- data/Gemfile +15 -1
- data/Gemfile.lock +70 -0
- data/MIT-LICENSE +1 -1
- data/README.md +140 -29
- data/Rakefile +20 -15
- data/bin/install_gems_in_all_appraisals +16 -0
- data/bin/run_all_tests +16 -0
- data/bin/setup +190 -0
- data/bin/supported_ruby_versions +7 -0
- data/bin/update_gem_in_all_appraisals +17 -0
- data/bin/update_gems_in_all_appraisals +16 -0
- data/{bin → exe}/convert_to_should_syntax +0 -0
- data/gemfiles/rails_4_2.gemfile +35 -0
- data/gemfiles/rails_4_2.gemfile.lock +234 -0
- data/gemfiles/rails_5_0.gemfile +33 -0
- data/gemfiles/rails_5_0.gemfile.lock +226 -0
- data/gemfiles/rails_5_1.gemfile +34 -0
- data/gemfiles/rails_5_1.gemfile.lock +242 -0
- data/gemfiles/rails_5_2.gemfile +36 -0
- data/gemfiles/rails_5_2.gemfile.lock +261 -0
- data/gemfiles/rails_6_0.gemfile +38 -0
- data/gemfiles/rails_6_0.gemfile.lock +286 -0
- data/lib/shoulda/context.rb +13 -16
- data/lib/shoulda/context/assertions.rb +16 -13
- data/lib/shoulda/context/configuration.rb +19 -0
- data/lib/shoulda/context/context.rb +33 -307
- data/lib/shoulda/context/dsl.rb +279 -0
- data/lib/shoulda/context/rails_test_unit_reporter_patch.rb +21 -0
- data/lib/shoulda/context/railtie.rb +14 -0
- data/lib/shoulda/context/test_framework_detection.rb +4 -5
- data/lib/shoulda/context/version.rb +1 -1
- data/lib/shoulda/context/world.rb +22 -0
- data/shoulda-context.gemspec +11 -18
- data/test/fake_rails_root/test/shoulda_macros/custom_macro.rb +1 -1
- data/test/fake_rails_root/vendor/gems/gem_with_macro-0.0.1/shoulda_macros/gem_macro.rb +1 -2
- data/test/fake_rails_root/vendor/plugins/plugin_with_macro/shoulda_macros/plugin_macro.rb +1 -2
- data/test/shoulda/autoload_macro_test.rb +1 -1
- data/test/shoulda/context_test.rb +92 -53
- data/test/shoulda/convert_to_should_syntax_test.rb +5 -7
- data/test/shoulda/helpers_test.rb +24 -59
- data/test/shoulda/railtie_test.rb +43 -0
- data/test/shoulda/rerun_snippet_test.rb +45 -0
- data/test/shoulda/should_test.rb +163 -24
- data/test/shoulda/test_framework_detection_test.rb +64 -71
- data/test/support/current_bundle.rb +61 -0
- data/test/support/rails_application_with_shoulda_context.rb +46 -0
- data/test/support/snowglobe.rb +5 -0
- data/test/test_helper.rb +43 -11
- metadata +46 -142
- data/gemfiles/minitest_4_x.gemfile +0 -7
- data/gemfiles/minitest_4_x.gemfile.lock +0 -96
- data/gemfiles/minitest_5_x.gemfile +0 -7
- data/gemfiles/minitest_5_x.gemfile.lock +0 -102
- data/gemfiles/rails_3_0.gemfile +0 -8
- data/gemfiles/rails_3_0.gemfile.lock +0 -93
- data/gemfiles/rails_3_1.gemfile +0 -10
- data/gemfiles/rails_3_1.gemfile.lock +0 -114
- data/gemfiles/rails_3_2.gemfile +0 -10
- data/gemfiles/rails_3_2.gemfile.lock +0 -112
- data/gemfiles/rails_4_0.gemfile +0 -10
- data/gemfiles/rails_4_0.gemfile.lock +0 -107
- data/gemfiles/rails_4_1.gemfile +0 -10
- data/gemfiles/rails_4_1.gemfile.lock +0 -119
- data/gemfiles/test_unit.gemfile +0 -7
- data/gemfiles/test_unit.gemfile.lock +0 -95
- data/init.rb +0 -1
- data/rails/init.rb +0 -4
@@ -0,0 +1,279 @@
|
|
1
|
+
require "shoulda/context/assertions"
|
2
|
+
|
3
|
+
module Shoulda
|
4
|
+
module Context
|
5
|
+
module DSL
|
6
|
+
def self.included(base)
|
7
|
+
base.class_eval do
|
8
|
+
include Assertions
|
9
|
+
include InstanceMethods
|
10
|
+
end
|
11
|
+
base.extend(ClassMethods)
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
# == Should statements
|
16
|
+
#
|
17
|
+
# Should statements are just syntactic sugar over normal Test::Unit test
|
18
|
+
# methods. A should block contains all the normal code and assertions
|
19
|
+
# you're used to seeing, with the added benefit that they can be wrapped
|
20
|
+
# inside context blocks (see below).
|
21
|
+
#
|
22
|
+
# === Example:
|
23
|
+
#
|
24
|
+
# class UserTest < Test::Unit::TestCase
|
25
|
+
#
|
26
|
+
# def setup
|
27
|
+
# @user = User.new("John", "Doe")
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# should "return its full name"
|
31
|
+
# assert_equal 'John Doe', @user.full_name
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# ...will produce the following test:
|
37
|
+
# * <tt>"test: User should return its full name. "</tt>
|
38
|
+
#
|
39
|
+
# Note: The part before <tt>should</tt> in the test name is gleamed from the name of the Test::Unit class.
|
40
|
+
#
|
41
|
+
# Should statements can also take a Proc as a <tt>:before </tt>option. This proc runs after any
|
42
|
+
# parent context's setups but before the current context's setup.
|
43
|
+
#
|
44
|
+
# === Example:
|
45
|
+
#
|
46
|
+
# context "Some context" do
|
47
|
+
# setup { puts("I run after the :before proc") }
|
48
|
+
#
|
49
|
+
# should "run a :before proc", :before => lambda { puts("I run before the setup") } do
|
50
|
+
# assert true
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# Should statements can also wrap matchers, making virtually any matcher
|
55
|
+
# usable in a macro style. The matcher's description is used to generate a
|
56
|
+
# test name and failure message, and the test will pass if the matcher
|
57
|
+
# matches the subject.
|
58
|
+
#
|
59
|
+
# === Example:
|
60
|
+
#
|
61
|
+
# should validate_presence_of(:first_name).with_message(/gotta be there/)
|
62
|
+
#
|
63
|
+
|
64
|
+
def should(name_or_matcher, options = {}, &blk)
|
65
|
+
if Shoulda::Context.current_context
|
66
|
+
Shoulda::Context.current_context.should(name_or_matcher, options, &blk)
|
67
|
+
else
|
68
|
+
context_name = self.name.gsub(/Test$/, "") if name
|
69
|
+
context = Shoulda::Context::Context.new(context_name, self) do
|
70
|
+
should(name_or_matcher, options, &blk)
|
71
|
+
end
|
72
|
+
context.build
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Allows negative tests using matchers. The matcher's description is used
|
77
|
+
# to generate a test name and negative failure message, and the test will
|
78
|
+
# pass unless the matcher matches the subject.
|
79
|
+
#
|
80
|
+
# === Example:
|
81
|
+
#
|
82
|
+
# should_not set_the_flash
|
83
|
+
def should_not(matcher)
|
84
|
+
if Shoulda::Context.current_context
|
85
|
+
Shoulda::Context.current_context.should_not(matcher)
|
86
|
+
else
|
87
|
+
context_name = self.name.gsub(/Test$/, "") if name
|
88
|
+
context = Shoulda::Context::Context.new(context_name, self) do
|
89
|
+
should_not(matcher)
|
90
|
+
end
|
91
|
+
context.build
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# == Before statements
|
96
|
+
#
|
97
|
+
# Before statements are should statements that run before the current
|
98
|
+
# context's setup. These are especially useful when setting expectations.
|
99
|
+
#
|
100
|
+
# === Example:
|
101
|
+
#
|
102
|
+
# class UserControllerTest < Test::Unit::TestCase
|
103
|
+
# context "the index action" do
|
104
|
+
# setup do
|
105
|
+
# @users = [Factory(:user)]
|
106
|
+
# User.stubs(:find).returns(@users)
|
107
|
+
# end
|
108
|
+
#
|
109
|
+
# context "on GET" do
|
110
|
+
# setup { get :index }
|
111
|
+
#
|
112
|
+
# should respond_with(:success)
|
113
|
+
#
|
114
|
+
# # runs before "get :index"
|
115
|
+
# before_should "find all users" do
|
116
|
+
# User.expects(:find).with(:all).returns(@users)
|
117
|
+
# end
|
118
|
+
# end
|
119
|
+
# end
|
120
|
+
# end
|
121
|
+
def before_should(name, &blk)
|
122
|
+
should(name, :before => blk) { assert true }
|
123
|
+
end
|
124
|
+
|
125
|
+
# Just like should, but never runs, and instead prints an 'X' in the Test::Unit output.
|
126
|
+
def should_eventually(name, options = {}, &blk)
|
127
|
+
context_name = self.name.gsub(/Test$/, "")
|
128
|
+
context = Shoulda::Context::Context.new(context_name, self) do
|
129
|
+
should_eventually(name, &blk)
|
130
|
+
end
|
131
|
+
context.build
|
132
|
+
end
|
133
|
+
|
134
|
+
# == Contexts
|
135
|
+
#
|
136
|
+
# A context block groups should statements under a common set of setup/teardown methods.
|
137
|
+
# Context blocks can be arbitrarily nested, and can do wonders for improving the maintainability
|
138
|
+
# and readability of your test code.
|
139
|
+
#
|
140
|
+
# A context block can contain setup, should, should_eventually, and teardown blocks.
|
141
|
+
#
|
142
|
+
# class UserTest < Test::Unit::TestCase
|
143
|
+
# context "A User instance" do
|
144
|
+
# setup do
|
145
|
+
# @user = User.find(:first)
|
146
|
+
# end
|
147
|
+
#
|
148
|
+
# should "return its full name"
|
149
|
+
# assert_equal 'John Doe', @user.full_name
|
150
|
+
# end
|
151
|
+
# end
|
152
|
+
# end
|
153
|
+
#
|
154
|
+
# This code will produce the method <tt>"test: A User instance should return its full name. "</tt>.
|
155
|
+
#
|
156
|
+
# Contexts may be nested. Nested contexts run their setup blocks from out to in before each
|
157
|
+
# should statement. They then run their teardown blocks from in to out after each should statement.
|
158
|
+
#
|
159
|
+
# class UserTest < Test::Unit::TestCase
|
160
|
+
# context "A User instance" do
|
161
|
+
# setup do
|
162
|
+
# @user = User.find(:first)
|
163
|
+
# end
|
164
|
+
#
|
165
|
+
# should "return its full name"
|
166
|
+
# assert_equal 'John Doe', @user.full_name
|
167
|
+
# end
|
168
|
+
#
|
169
|
+
# context "with a profile" do
|
170
|
+
# setup do
|
171
|
+
# @user.profile = Profile.find(:first)
|
172
|
+
# end
|
173
|
+
#
|
174
|
+
# should "return true when sent :has_profile?"
|
175
|
+
# assert @user.has_profile?
|
176
|
+
# end
|
177
|
+
# end
|
178
|
+
# end
|
179
|
+
# end
|
180
|
+
#
|
181
|
+
# This code will produce the following methods
|
182
|
+
# * <tt>"test: A User instance should return its full name. "</tt>
|
183
|
+
# * <tt>"test: A User instance with a profile should return true when sent :has_profile?. "</tt>
|
184
|
+
#
|
185
|
+
# <b>Just like should statements, a context block can exist next to normal <tt>def test_the_old_way; end</tt>
|
186
|
+
# tests</b>. This means you do not have to fully commit to the context/should syntax in a test file.
|
187
|
+
|
188
|
+
def context(name, &blk)
|
189
|
+
if Shoulda::Context.current_context
|
190
|
+
Shoulda::Context.current_context.context(name, &blk)
|
191
|
+
else
|
192
|
+
context = Shoulda::Context::Context.new(name, self, &blk)
|
193
|
+
context.build
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# Returns the class being tested, as determined by the test class name.
|
198
|
+
#
|
199
|
+
# class UserTest; described_type; end
|
200
|
+
# # => User
|
201
|
+
def described_type
|
202
|
+
@described_type ||= self.name.
|
203
|
+
gsub(/Test$/, '').
|
204
|
+
split('::').
|
205
|
+
inject(Object) do |parent, local_name|
|
206
|
+
parent.const_get(local_name, false)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
# Sets the return value of the subject instance method:
|
211
|
+
#
|
212
|
+
# class UserTest < Test::Unit::TestCase
|
213
|
+
# subject { User.first }
|
214
|
+
#
|
215
|
+
# # uses the existing user
|
216
|
+
# should validate_uniqueness_of(:email)
|
217
|
+
# end
|
218
|
+
def subject(&block)
|
219
|
+
@subject_block = block
|
220
|
+
end
|
221
|
+
|
222
|
+
def subject_block # :nodoc:
|
223
|
+
@subject_block ||= nil
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
module InstanceMethods
|
228
|
+
# Returns an instance of the class under test.
|
229
|
+
#
|
230
|
+
# class UserTest
|
231
|
+
# should "be a user" do
|
232
|
+
# assert_kind_of User, subject # passes
|
233
|
+
# end
|
234
|
+
# end
|
235
|
+
#
|
236
|
+
# The subject can be explicitly set using the subject class method:
|
237
|
+
#
|
238
|
+
# class UserTest
|
239
|
+
# subject { User.first }
|
240
|
+
# should "be an existing user" do
|
241
|
+
# assert !subject.new_record? # uses the first user
|
242
|
+
# end
|
243
|
+
# end
|
244
|
+
#
|
245
|
+
# The subject is used by all macros that require an instance of the class
|
246
|
+
# being tested.
|
247
|
+
def subject
|
248
|
+
@shoulda_subject ||= construct_subject
|
249
|
+
end
|
250
|
+
|
251
|
+
def subject_block # :nodoc:
|
252
|
+
(@shoulda_context && @shoulda_context.subject_block) || self.class.subject_block
|
253
|
+
end
|
254
|
+
|
255
|
+
def get_instance_of(object_or_klass) # :nodoc:
|
256
|
+
if object_or_klass.is_a?(Class)
|
257
|
+
object_or_klass.new
|
258
|
+
else
|
259
|
+
object_or_klass
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
def instance_variable_name_for(klass) # :nodoc:
|
264
|
+
klass.to_s.split('::').last.underscore
|
265
|
+
end
|
266
|
+
|
267
|
+
private
|
268
|
+
|
269
|
+
def construct_subject
|
270
|
+
if subject_block
|
271
|
+
instance_eval(&subject_block)
|
272
|
+
else
|
273
|
+
get_instance_of(self.class.described_type)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
begin
|
2
|
+
require "rails/test_unit/reporter"
|
3
|
+
|
4
|
+
Rails::TestUnitReporter.class_eval do
|
5
|
+
# Fix #format_rerun_snippet so that it works with recent versions of Minitest.
|
6
|
+
# This was cribbed from:
|
7
|
+
# <https://github.com/rails/rails/commit/ff0d5f14504f1aa29ad908ab15bab66b101427b7#diff-a071a1c8f51ce3b8bcb17ca59c79fc70>
|
8
|
+
def format_rerun_snippet(result)
|
9
|
+
location, line =
|
10
|
+
if result.respond_to?(:source_location)
|
11
|
+
result.source_location
|
12
|
+
else
|
13
|
+
result.method(result.name).source_location
|
14
|
+
end
|
15
|
+
|
16
|
+
"#{executable} #{relative_path_for(location)}:#{line}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
rescue LoadError
|
20
|
+
# Rails::TestUnitReporter was introduced in Rails 5
|
21
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Shoulda
|
2
|
+
module Context
|
3
|
+
class Railtie < Rails::Railtie
|
4
|
+
initializer "shoulda_context.autoload_macros" do
|
5
|
+
if Rails.env.test?
|
6
|
+
Shoulda.autoload_macros(
|
7
|
+
Rails.root,
|
8
|
+
File.join("vendor", "{plugins,gems}", "*")
|
9
|
+
)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -3,10 +3,9 @@ module Shoulda
|
|
3
3
|
module TestFrameworkDetection
|
4
4
|
def self.possible_test_frameworks
|
5
5
|
[
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
lambda { Test::Unit::TestCase }
|
6
|
+
-> { ActiveSupport::TestCase },
|
7
|
+
-> { Minitest::Test },
|
8
|
+
-> { Test::Unit::TestCase }
|
10
9
|
]
|
11
10
|
end
|
12
11
|
|
@@ -23,7 +22,7 @@ module Shoulda
|
|
23
22
|
end
|
24
23
|
|
25
24
|
def self.test_framework_test_cases
|
26
|
-
@
|
25
|
+
@_test_framework_test_cases ||= detected_test_framework_test_cases
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Shoulda
|
2
|
+
module Context
|
3
|
+
class << self
|
4
|
+
def contexts # :nodoc:
|
5
|
+
@contexts ||= []
|
6
|
+
end
|
7
|
+
attr_writer :contexts
|
8
|
+
|
9
|
+
def current_context # :nodoc:
|
10
|
+
self.contexts.last
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_context(context) # :nodoc:
|
14
|
+
self.contexts.push(context)
|
15
|
+
end
|
16
|
+
|
17
|
+
def remove_context # :nodoc:
|
18
|
+
self.contexts.pop
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/shoulda-context.gemspec
CHANGED
@@ -1,30 +1,23 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
3
|
-
|
2
|
+
|
3
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), "lib")
|
4
|
+
require "shoulda/context/version"
|
4
5
|
|
5
6
|
Gem::Specification.new do |s|
|
6
|
-
s.name =
|
7
|
+
s.name = "shoulda-context"
|
7
8
|
s.version = Shoulda::Context::VERSION.dup
|
8
9
|
s.platform = Gem::Platform::RUBY
|
9
10
|
s.authors = ["thoughtbot, inc.", "Tammer Saleh", "Joe Ferris",
|
10
11
|
"Ryan McGeary", "Dan Croak", "Matt Jankowski"]
|
11
|
-
s.email =
|
12
|
-
s.homepage =
|
13
|
-
s.summary =
|
14
|
-
s.description =
|
15
|
-
s.license =
|
12
|
+
s.email = "support@thoughtbot.com"
|
13
|
+
s.homepage = "http://thoughtbot.com/community/"
|
14
|
+
s.summary = "Context framework extracted from Shoulda"
|
15
|
+
s.description = "Context framework extracted from Shoulda"
|
16
|
+
s.license = "MIT"
|
16
17
|
|
17
18
|
s.files = `git ls-files`.split("\n")
|
18
19
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
-
s.executables = `git ls-files --
|
20
|
+
s.executables = `git ls-files -- exe/*`.split("\n").map { |f| File.basename(f) }
|
21
|
+
s.bindir = "exe"
|
20
22
|
s.require_paths = ["lib"]
|
21
|
-
|
22
|
-
s.add_development_dependency("appraisal", "~> 0.5")
|
23
|
-
s.add_development_dependency("rails", ">= 3.0")
|
24
|
-
s.add_development_dependency("mocha", "~> 0.9.10")
|
25
|
-
s.add_development_dependency("rake")
|
26
|
-
s.add_development_dependency("test-unit", "~> 2.1.0")
|
27
|
-
s.add_development_dependency("pry")
|
28
|
-
s.add_development_dependency("byebug")
|
29
|
-
s.add_development_dependency("pry-byebug")
|
30
23
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class ContextTest <
|
4
|
-
|
3
|
+
class ContextTest < PARENT_TEST_CASE
|
5
4
|
def self.context_macro(&blk)
|
6
5
|
context "with a subcontext made by a macro" do
|
7
6
|
setup { @context_macro = :foo }
|
@@ -20,7 +19,7 @@ class ContextTest < Test::Unit::TestCase # :nodoc:
|
|
20
19
|
end
|
21
20
|
|
22
21
|
should "have name set right" do
|
23
|
-
assert_match(/^test: context with setup block/,
|
22
|
+
assert_match(/^test: context with setup block/, normalized_name)
|
24
23
|
end
|
25
24
|
|
26
25
|
context "and a subcontext" do
|
@@ -29,7 +28,7 @@ class ContextTest < Test::Unit::TestCase # :nodoc:
|
|
29
28
|
end
|
30
29
|
|
31
30
|
should "be named correctly" do
|
32
|
-
assert_match(/^test: context with setup block and a subcontext should be named correctly/,
|
31
|
+
assert_match(/^test: context with setup block and a subcontext should be named correctly/, normalized_name)
|
33
32
|
end
|
34
33
|
|
35
34
|
should "run the setup blocks in order" do
|
@@ -39,7 +38,7 @@ class ContextTest < Test::Unit::TestCase # :nodoc:
|
|
39
38
|
|
40
39
|
context_macro do
|
41
40
|
should "have name set right" do
|
42
|
-
assert_match(/^test: context with setup block with a subcontext made by a macro should have name set right/,
|
41
|
+
assert_match(/^test: context with setup block with a subcontext made by a macro should have name set right/, normalized_name)
|
43
42
|
end
|
44
43
|
|
45
44
|
should "run the setup block of that context macro" do
|
@@ -63,7 +62,7 @@ class ContextTest < Test::Unit::TestCase # :nodoc:
|
|
63
62
|
end
|
64
63
|
|
65
64
|
should "have name set right" do
|
66
|
-
assert_match(/^test: another context with setup block/,
|
65
|
+
assert_match(/^test: another context with setup block/, normalized_name)
|
67
66
|
end
|
68
67
|
end
|
69
68
|
|
@@ -77,7 +76,7 @@ class ContextTest < Test::Unit::TestCase # :nodoc:
|
|
77
76
|
end
|
78
77
|
|
79
78
|
should "have name set right" do
|
80
|
-
assert_match(/^test: context with method definition/,
|
79
|
+
assert_match(/^test: context with method definition/, normalized_name)
|
81
80
|
end
|
82
81
|
end
|
83
82
|
|
@@ -166,19 +165,22 @@ class ContextTest < Test::Unit::TestCase # :nodoc:
|
|
166
165
|
end
|
167
166
|
end
|
168
167
|
|
168
|
+
def normalized_name
|
169
|
+
name.sub("test_:", "test:")
|
170
|
+
end
|
169
171
|
end
|
170
172
|
|
171
173
|
class ::Some
|
172
174
|
class NestedModel; end
|
173
175
|
end
|
174
176
|
|
175
|
-
class Some::NestedModelTest <
|
177
|
+
class Some::NestedModelTest < PARENT_TEST_CASE
|
176
178
|
should "determine the described type for a nested model" do
|
177
179
|
assert_equal Some::NestedModel, self.class.described_type
|
178
180
|
end
|
179
181
|
end
|
180
182
|
|
181
|
-
class Some::SomeTest <
|
183
|
+
class Some::SomeTest < PARENT_TEST_CASE
|
182
184
|
should "not fallback to higher-level constants with same name" do
|
183
185
|
assert_raises(NameError) do
|
184
186
|
assert_equal nil, self.class.described_type
|
@@ -186,13 +188,13 @@ class Some::SomeTest < Test::Unit::TestCase
|
|
186
188
|
end
|
187
189
|
end
|
188
190
|
|
189
|
-
class ShouldMatcherTest <
|
191
|
+
class ShouldMatcherTest < PARENT_TEST_CASE
|
190
192
|
class FakeMatcher
|
191
193
|
attr_reader :subject
|
192
194
|
attr_accessor :fail
|
193
195
|
|
194
196
|
def description
|
195
|
-
"
|
197
|
+
"be a fake matcher"
|
196
198
|
end
|
197
199
|
|
198
200
|
def matches?(subject)
|
@@ -200,46 +202,33 @@ class ShouldMatcherTest < Test::Unit::TestCase
|
|
200
202
|
!@fail
|
201
203
|
end
|
202
204
|
|
203
|
-
def
|
204
|
-
"failure message
|
205
|
+
def failure_message
|
206
|
+
"positive failure message"
|
205
207
|
end
|
206
208
|
|
207
|
-
def
|
208
|
-
"failure message
|
209
|
+
def failure_message_when_negated
|
210
|
+
"negative failure message"
|
209
211
|
end
|
210
212
|
end
|
211
213
|
|
212
|
-
def run_test_suite
|
213
|
-
@test_suite.run(@test_result) { |event, name| }
|
214
|
-
end
|
215
|
-
|
216
214
|
def setup
|
217
215
|
@matcher = FakeMatcher.new
|
218
|
-
@test_result = Test::Unit::TestResult.new
|
219
|
-
class << @test_result
|
220
|
-
def failure_messages
|
221
|
-
@failures.map { |failure| failure.message }
|
222
|
-
end
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
|
-
def create_test_suite(&definition)
|
227
|
-
test_class = Class.new(Test::Unit::TestCase, &definition)
|
228
|
-
test_class.suite
|
229
216
|
end
|
230
217
|
|
231
|
-
def assert_failed_with(message,
|
232
|
-
assert_equal
|
233
|
-
assert_equal [message], test_result.failure_messages
|
218
|
+
def assert_failed_with(message, test_suite)
|
219
|
+
assert_equal [message], test_suite.failure_messages
|
234
220
|
end
|
235
221
|
|
236
|
-
def assert_passed(
|
237
|
-
assert_equal
|
222
|
+
def assert_passed(test_suite)
|
223
|
+
assert_equal [], test_suite.failure_messages
|
238
224
|
end
|
239
225
|
|
240
226
|
def assert_test_named(expected_name, test_suite)
|
241
|
-
name = test_suite.
|
242
|
-
assert
|
227
|
+
name = test_suite.test_names.first
|
228
|
+
assert(
|
229
|
+
name.include?(expected_name),
|
230
|
+
"Expected #{name} to include #{expected_name}"
|
231
|
+
)
|
243
232
|
end
|
244
233
|
|
245
234
|
def self.should_use_positive_matcher
|
@@ -249,19 +238,19 @@ class ShouldMatcherTest < Test::Unit::TestCase
|
|
249
238
|
|
250
239
|
should "pass with a passing matcher" do
|
251
240
|
@matcher.fail = false
|
252
|
-
|
253
|
-
assert_passed @
|
241
|
+
@test_suite.run
|
242
|
+
assert_passed @test_suite
|
254
243
|
end
|
255
244
|
|
256
245
|
should "fail with a failing matcher" do
|
257
246
|
@matcher.fail = true
|
258
|
-
|
259
|
-
assert_failed_with "failure message
|
247
|
+
@test_suite.run
|
248
|
+
assert_failed_with "positive failure message", @test_suite
|
260
249
|
end
|
261
250
|
|
262
251
|
should "provide the subject" do
|
263
252
|
@matcher.fail = false
|
264
|
-
|
253
|
+
@test_suite.run
|
265
254
|
assert_equal 'a subject', @matcher.subject
|
266
255
|
end
|
267
256
|
end
|
@@ -273,19 +262,19 @@ class ShouldMatcherTest < Test::Unit::TestCase
|
|
273
262
|
|
274
263
|
should "pass with a failing matcher" do
|
275
264
|
@matcher.fail = true
|
276
|
-
|
277
|
-
assert_passed @
|
265
|
+
@test_suite.run
|
266
|
+
assert_passed @test_suite
|
278
267
|
end
|
279
268
|
|
280
269
|
should "fail with a passing matcher" do
|
281
270
|
@matcher.fail = false
|
282
|
-
|
283
|
-
assert_failed_with "failure message
|
271
|
+
@test_suite.run
|
272
|
+
assert_failed_with "negative failure message", @test_suite
|
284
273
|
end
|
285
274
|
|
286
275
|
should "provide the subject" do
|
287
276
|
@matcher.fail = false
|
288
|
-
|
277
|
+
@test_suite.run
|
289
278
|
assert_equal 'a subject', @matcher.subject
|
290
279
|
end
|
291
280
|
end
|
@@ -293,7 +282,7 @@ class ShouldMatcherTest < Test::Unit::TestCase
|
|
293
282
|
context "a should block with a matcher" do
|
294
283
|
setup do
|
295
284
|
matcher = @matcher
|
296
|
-
@test_suite =
|
285
|
+
@test_suite = TestSuite.create do
|
297
286
|
subject { 'a subject' }
|
298
287
|
should matcher
|
299
288
|
end
|
@@ -305,7 +294,7 @@ class ShouldMatcherTest < Test::Unit::TestCase
|
|
305
294
|
context "a should block with a matcher within a context" do
|
306
295
|
setup do
|
307
296
|
matcher = @matcher
|
308
|
-
@test_suite =
|
297
|
+
@test_suite = TestSuite.create do
|
309
298
|
context "in context" do
|
310
299
|
subject { 'a subject' }
|
311
300
|
should matcher
|
@@ -319,7 +308,7 @@ class ShouldMatcherTest < Test::Unit::TestCase
|
|
319
308
|
context "a should_not block with a matcher" do
|
320
309
|
setup do
|
321
310
|
matcher = @matcher
|
322
|
-
@test_suite =
|
311
|
+
@test_suite = TestSuite.create do
|
323
312
|
subject { 'a subject' }
|
324
313
|
should_not matcher
|
325
314
|
end
|
@@ -331,7 +320,7 @@ class ShouldMatcherTest < Test::Unit::TestCase
|
|
331
320
|
context "a should_not block with a matcher within a context" do
|
332
321
|
setup do
|
333
322
|
matcher = @matcher
|
334
|
-
@test_suite =
|
323
|
+
@test_suite = TestSuite.create do
|
335
324
|
context "in context" do
|
336
325
|
subject { 'a subject' }
|
337
326
|
should_not matcher
|
@@ -341,11 +330,61 @@ class ShouldMatcherTest < Test::Unit::TestCase
|
|
341
330
|
|
342
331
|
should_use_negative_matcher
|
343
332
|
end
|
333
|
+
|
334
|
+
class TestSuite
|
335
|
+
def self.create(&definition)
|
336
|
+
if defined?(Test::Unit)
|
337
|
+
TestUnitSuite.new(&definition)
|
338
|
+
else
|
339
|
+
MinitestSuite.new(&definition)
|
340
|
+
end
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
class TestUnitSuite
|
345
|
+
def initialize(&definition)
|
346
|
+
@suite = Class.new(Test::Unit::TestCase, &definition).suite
|
347
|
+
@result = Test::Unit::TestResult.new
|
348
|
+
end
|
349
|
+
|
350
|
+
def run
|
351
|
+
@suite.run(@result) do |event, name|
|
352
|
+
# do nothing
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
def failure_messages
|
357
|
+
@result.failures.map(&:message)
|
358
|
+
end
|
359
|
+
|
360
|
+
def test_names
|
361
|
+
@suite.tests.map(&:method_name)
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
class MinitestSuite
|
366
|
+
def initialize(&definition)
|
367
|
+
@test_case_class = Class.new(Minitest::Test, &definition)
|
368
|
+
@reporter = Minitest::StatisticsReporter.new(StringIO.new)
|
369
|
+
end
|
370
|
+
|
371
|
+
def run
|
372
|
+
@test_case_class.run(@reporter)
|
373
|
+
end
|
374
|
+
|
375
|
+
def failure_messages
|
376
|
+
@reporter.results.flat_map(&:failures).map(&:message)
|
377
|
+
end
|
378
|
+
|
379
|
+
def test_names
|
380
|
+
@test_case_class.runnable_methods
|
381
|
+
end
|
382
|
+
end
|
344
383
|
end
|
345
384
|
|
346
385
|
class Subject; end
|
347
386
|
|
348
|
-
class SubjectTest <
|
387
|
+
class SubjectTest < PARENT_TEST_CASE
|
349
388
|
|
350
389
|
def setup
|
351
390
|
@expected = Subject.new
|
@@ -358,7 +397,7 @@ class SubjectTest < Test::Unit::TestCase
|
|
358
397
|
end
|
359
398
|
end
|
360
399
|
|
361
|
-
class SubjectLazinessTest <
|
400
|
+
class SubjectLazinessTest < PARENT_TEST_CASE
|
362
401
|
subject { Subject.new }
|
363
402
|
|
364
403
|
should "only build the subject once" do
|