shoulda-context 1.2.2 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +0 -1
  3. data/.rubocop.yml +190 -0
  4. data/.ruby-version +1 -1
  5. data/.travis.yml +27 -2
  6. data/Appraisals +15 -32
  7. data/CHANGELOG.md +27 -0
  8. data/Gemfile +4 -1
  9. data/Gemfile.lock +72 -0
  10. data/MIT-LICENSE +1 -1
  11. data/README.md +140 -29
  12. data/Rakefile +19 -14
  13. data/bin/install_gems_in_all_appraisals +16 -0
  14. data/bin/run_all_tests +16 -0
  15. data/bin/setup +190 -0
  16. data/bin/supported_ruby_versions +7 -0
  17. data/bin/update_gem_in_all_appraisals +17 -0
  18. data/bin/update_gems_in_all_appraisals +16 -0
  19. data/{bin → exe}/convert_to_should_syntax +0 -0
  20. data/gemfiles/rails_4_2.gemfile +10 -0
  21. data/gemfiles/rails_4_2.gemfile.lock +164 -0
  22. data/gemfiles/rails_5_0.gemfile +10 -0
  23. data/gemfiles/rails_5_0.gemfile.lock +170 -0
  24. data/gemfiles/rails_5_1.gemfile +10 -0
  25. data/gemfiles/rails_5_1.gemfile.lock +170 -0
  26. data/gemfiles/rails_5_2.gemfile +10 -0
  27. data/gemfiles/rails_5_2.gemfile.lock +178 -0
  28. data/lib/shoulda/context.rb +12 -16
  29. data/lib/shoulda/context/assertions.rb +16 -13
  30. data/lib/shoulda/context/configuration.rb +19 -0
  31. data/lib/shoulda/context/context.rb +22 -305
  32. data/lib/shoulda/context/dsl.rb +279 -0
  33. data/lib/shoulda/context/railtie.rb +14 -0
  34. data/lib/shoulda/context/test_framework_detection.rb +4 -5
  35. data/lib/shoulda/context/version.rb +1 -1
  36. data/lib/shoulda/context/world.rb +22 -0
  37. data/shoulda-context.gemspec +19 -17
  38. data/test/fake_rails_root/test/shoulda_macros/custom_macro.rb +1 -1
  39. data/test/fake_rails_root/vendor/gems/gem_with_macro-0.0.1/shoulda_macros/gem_macro.rb +1 -2
  40. data/test/fake_rails_root/vendor/plugins/plugin_with_macro/shoulda_macros/plugin_macro.rb +1 -2
  41. data/test/shoulda/autoload_macro_test.rb +1 -1
  42. data/test/shoulda/context_test.rb +92 -53
  43. data/test/shoulda/convert_to_should_syntax_test.rb +5 -7
  44. data/test/shoulda/helpers_test.rb +24 -59
  45. data/test/shoulda/railtie_test.rb +43 -0
  46. data/test/shoulda/should_test.rb +163 -24
  47. data/test/shoulda/test_framework_detection_test.rb +64 -71
  48. data/test/support/current_bundle.rb +61 -0
  49. data/test/support/rails_application_with_shoulda_context.rb +46 -0
  50. data/test/support/snowglobe.rb +5 -0
  51. data/test/test_helper.rb +35 -11
  52. metadata +71 -60
  53. data/gemfiles/minitest_4_x.gemfile +0 -7
  54. data/gemfiles/minitest_4_x.gemfile.lock +0 -96
  55. data/gemfiles/minitest_5_x.gemfile +0 -7
  56. data/gemfiles/minitest_5_x.gemfile.lock +0 -102
  57. data/gemfiles/rails_3_0.gemfile +0 -8
  58. data/gemfiles/rails_3_0.gemfile.lock +0 -93
  59. data/gemfiles/rails_3_1.gemfile +0 -10
  60. data/gemfiles/rails_3_1.gemfile.lock +0 -114
  61. data/gemfiles/rails_3_2.gemfile +0 -10
  62. data/gemfiles/rails_3_2.gemfile.lock +0 -112
  63. data/gemfiles/rails_4_0.gemfile +0 -10
  64. data/gemfiles/rails_4_0.gemfile.lock +0 -107
  65. data/gemfiles/rails_4_1.gemfile +0 -10
  66. data/gemfiles/rails_4_1.gemfile.lock +0 -119
  67. data/gemfiles/test_unit.gemfile +0 -7
  68. data/gemfiles/test_unit.gemfile.lock +0 -95
  69. data/init.rb +0 -1
  70. data/rails/init.rb +0 -4
@@ -1,20 +1,16 @@
1
- require 'shoulda/context/test_framework_detection'
2
- require 'shoulda/context/version'
3
- require 'shoulda/context/proc_extensions'
4
- require 'shoulda/context/assertions'
5
- require 'shoulda/context/context'
6
- require 'shoulda/context/autoload_macros'
1
+ require "shoulda/context/autoload_macros"
2
+ require "shoulda/context/configuration"
3
+ require "shoulda/context/context"
4
+ require "shoulda/context/dsl"
5
+ require "shoulda/context/proc_extensions"
6
+ require "shoulda/context/test_framework_detection"
7
+ require "shoulda/context/version"
8
+ require "shoulda/context/world"
7
9
 
8
- module ShouldaContextLoadable
9
- def self.included(base)
10
- base.class_eval do
11
- include Shoulda::Context::Assertions
12
- include Shoulda::Context::InstanceMethods
13
- end
14
- base.extend(Shoulda::Context::ClassMethods)
15
- end
10
+ if defined?(Rails)
11
+ require "shoulda/context/railtie"
16
12
  end
17
13
 
18
- Shoulda::Context.test_framework_test_cases.each do |test_case|
19
- test_case.class_eval { include ShouldaContextLoadable }
14
+ Shoulda::Context.configure do |config|
15
+ config.include(Shoulda::Context::DSL)
20
16
  end
@@ -3,7 +3,7 @@ module Shoulda # :nodoc:
3
3
  module Assertions
4
4
  # Asserts that two arrays contain the same elements, the same number of times. Essentially ==, but unordered.
5
5
  #
6
- # assert_same_elements([:a, :b, :c], [:c, :a, :b]) => passes
6
+ # assert_same_elements([:a, :b, :c], [:c, :a, :b]) => passes)
7
7
  def assert_same_elements(a1, a2, msg = nil)
8
8
  [:select, :inject, :size].each do |m|
9
9
  [a1, a2].each {|a| assert_respond_to(a, m, "Are you sure that #{a.inspect} is an array? It doesn't respond to #{m}.") }
@@ -45,7 +45,8 @@ module Shoulda # :nodoc:
45
45
  end
46
46
  end
47
47
 
48
- # Asserts that the given matcher returns true when +target+ is passed to #matches?
48
+ # Asserts that the given matcher returns true when +target+ is passed to
49
+ # #matches?
49
50
  def assert_accepts(matcher, target, options = {})
50
51
  if matcher.respond_to?(:in_context)
51
52
  matcher.in_context(self)
@@ -54,33 +55,35 @@ module Shoulda # :nodoc:
54
55
  if matcher.matches?(target)
55
56
  safe_assert_block { true }
56
57
  if options[:message]
57
- message = matcher.respond_to?(:failure_message_for_should_not) ? matcher.failure_message_for_should_not : matcher.negative_failure_message
58
- assert_match options[:message], message
58
+ assert_match options[:message], matcher.failure_message_when_negated
59
59
  end
60
60
  else
61
- message = matcher.respond_to?(:failure_message_for_should) ? matcher.failure_message_for_should : matcher.failure_message
62
- safe_assert_block(message) { false }
61
+ safe_assert_block(matcher.failure_message) { false }
63
62
  end
64
63
  end
65
64
 
66
- # Asserts that the given matcher returns true when +target+ is passed to #does_not_match?
67
- # or false when +target+ is passed to #matches? if #does_not_match? is not implemented
65
+ # Asserts that the given matcher returns true when +target+ is passed to
66
+ # #does_not_match? or false when +target+ is passed to #matches? if
67
+ # #does_not_match? is not implemented
68
68
  def assert_rejects(matcher, target, options = {})
69
69
  if matcher.respond_to?(:in_context)
70
70
  matcher.in_context(self)
71
71
  end
72
72
 
73
- not_match = matcher.respond_to?(:does_not_match?) ? matcher.does_not_match?(target) : !matcher.matches?(target)
73
+ not_match =
74
+ if matcher.respond_to?(:does_not_match?)
75
+ matcher.does_not_match?(target)
76
+ else
77
+ !matcher.matches?(target)
78
+ end
74
79
 
75
80
  if not_match
76
81
  safe_assert_block { true }
77
82
  if options[:message]
78
- message = matcher.respond_to?(:failure_message_for_should) ? matcher.failure_message_for_should : matcher.failure_message
79
- assert_match options[:message], message
83
+ assert_match options[:message], matcher.failure_message
80
84
  end
81
85
  else
82
- message = matcher.respond_to?(:failure_message_for_should_not) ? matcher.failure_message_for_should_not : matcher.negative_failure_message
83
- safe_assert_block(message) { false }
86
+ safe_assert_block(matcher.failure_message_when_negated) { false }
84
87
  end
85
88
  end
86
89
 
@@ -0,0 +1,19 @@
1
+ module Shoulda
2
+ module Context
3
+ def self.configure
4
+ yield self
5
+ end
6
+
7
+ def self.include(mod)
8
+ test_framework_test_cases.each do |test_case|
9
+ test_case.class_eval { include mod }
10
+ end
11
+ end
12
+
13
+ def self.extend(mod)
14
+ test_framework_test_cases.each do |test_case|
15
+ test_case.extend(mod)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,290 +1,6 @@
1
1
  module Shoulda
2
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
-
22
- module ClassMethods
23
- # == Should statements
24
- #
25
- # Should statements are just syntactic sugar over normal Test::Unit test
26
- # methods. A should block contains all the normal code and assertions
27
- # you're used to seeing, with the added benefit that they can be wrapped
28
- # inside context blocks (see below).
29
- #
30
- # === Example:
31
- #
32
- # class UserTest < Test::Unit::TestCase
33
- #
34
- # def setup
35
- # @user = User.new("John", "Doe")
36
- # end
37
- #
38
- # should "return its full name"
39
- # assert_equal 'John Doe', @user.full_name
40
- # end
41
- #
42
- # end
43
- #
44
- # ...will produce the following test:
45
- # * <tt>"test: User should return its full name. "</tt>
46
- #
47
- # Note: The part before <tt>should</tt> in the test name is gleamed from the name of the Test::Unit class.
48
- #
49
- # Should statements can also take a Proc as a <tt>:before </tt>option. This proc runs after any
50
- # parent context's setups but before the current context's setup.
51
- #
52
- # === Example:
53
- #
54
- # context "Some context" do
55
- # setup { puts("I run after the :before proc") }
56
- #
57
- # should "run a :before proc", :before => lambda { puts("I run before the setup") } do
58
- # assert true
59
- # end
60
- # end
61
- #
62
- # Should statements can also wrap matchers, making virtually any matcher
63
- # usable in a macro style. The matcher's description is used to generate a
64
- # test name and failure message, and the test will pass if the matcher
65
- # matches the subject.
66
- #
67
- # === Example:
68
- #
69
- # should validate_presence_of(:first_name).with_message(/gotta be there/)
70
- #
71
-
72
- def should(name_or_matcher, options = {}, &blk)
73
- if Shoulda::Context.current_context
74
- Shoulda::Context.current_context.should(name_or_matcher, options, &blk)
75
- else
76
- context_name = self.name.gsub(/Test/, "") if self.name
77
- context = Shoulda::Context::Context.new(context_name, self) do
78
- should(name_or_matcher, options, &blk)
79
- end
80
- context.build
81
- end
82
- end
83
-
84
- # Allows negative tests using matchers. The matcher's description is used
85
- # to generate a test name and negative failure message, and the test will
86
- # pass unless the matcher matches the subject.
87
- #
88
- # === Example:
89
- #
90
- # should_not set_the_flash
91
- def should_not(matcher)
92
- if Shoulda::Context.current_context
93
- Shoulda::Context.current_context.should_not(matcher)
94
- else
95
- context_name = self.name.gsub(/Test/, "") if self.name
96
- context = Shoulda::Context::Context.new(context_name, self) do
97
- should_not(matcher)
98
- end
99
- context.build
100
- end
101
- end
102
-
103
- # == Before statements
104
- #
105
- # Before statements are should statements that run before the current
106
- # context's setup. These are especially useful when setting expectations.
107
- #
108
- # === Example:
109
- #
110
- # class UserControllerTest < Test::Unit::TestCase
111
- # context "the index action" do
112
- # setup do
113
- # @users = [Factory(:user)]
114
- # User.stubs(:find).returns(@users)
115
- # end
116
- #
117
- # context "on GET" do
118
- # setup { get :index }
119
- #
120
- # should respond_with(:success)
121
- #
122
- # # runs before "get :index"
123
- # before_should "find all users" do
124
- # User.expects(:find).with(:all).returns(@users)
125
- # end
126
- # end
127
- # end
128
- # end
129
- def before_should(name, &blk)
130
- should(name, :before => blk) { assert true }
131
- end
132
-
133
- # Just like should, but never runs, and instead prints an 'X' in the Test::Unit output.
134
- def should_eventually(name, options = {}, &blk)
135
- context_name = self.name.gsub(/Test/, "")
136
- context = Shoulda::Context::Context.new(context_name, self) do
137
- should_eventually(name, &blk)
138
- end
139
- context.build
140
- end
141
-
142
- # == Contexts
143
- #
144
- # A context block groups should statements under a common set of setup/teardown methods.
145
- # Context blocks can be arbitrarily nested, and can do wonders for improving the maintainability
146
- # and readability of your test code.
147
- #
148
- # A context block can contain setup, should, should_eventually, and teardown blocks.
149
- #
150
- # class UserTest < Test::Unit::TestCase
151
- # context "A User instance" do
152
- # setup do
153
- # @user = User.find(:first)
154
- # end
155
- #
156
- # should "return its full name"
157
- # assert_equal 'John Doe', @user.full_name
158
- # end
159
- # end
160
- # end
161
- #
162
- # This code will produce the method <tt>"test: A User instance should return its full name. "</tt>.
163
- #
164
- # Contexts may be nested. Nested contexts run their setup blocks from out to in before each
165
- # should statement. They then run their teardown blocks from in to out after each should statement.
166
- #
167
- # class UserTest < Test::Unit::TestCase
168
- # context "A User instance" do
169
- # setup do
170
- # @user = User.find(:first)
171
- # end
172
- #
173
- # should "return its full name"
174
- # assert_equal 'John Doe', @user.full_name
175
- # end
176
- #
177
- # context "with a profile" do
178
- # setup do
179
- # @user.profile = Profile.find(:first)
180
- # end
181
- #
182
- # should "return true when sent :has_profile?"
183
- # assert @user.has_profile?
184
- # end
185
- # end
186
- # end
187
- # end
188
- #
189
- # This code will produce the following methods
190
- # * <tt>"test: A User instance should return its full name. "</tt>
191
- # * <tt>"test: A User instance with a profile should return true when sent :has_profile?. "</tt>
192
- #
193
- # <b>Just like should statements, a context block can exist next to normal <tt>def test_the_old_way; end</tt>
194
- # tests</b>. This means you do not have to fully commit to the context/should syntax in a test file.
195
-
196
- def context(name, &blk)
197
- if Shoulda::Context.current_context
198
- Shoulda::Context.current_context.context(name, &blk)
199
- else
200
- context = Shoulda::Context::Context.new(name, self, &blk)
201
- context.build
202
- end
203
- end
204
-
205
- # Returns the class being tested, as determined by the test class name.
206
- #
207
- # class UserTest; described_type; end
208
- # # => User
209
- def described_type
210
- @described_type ||= self.name.
211
- gsub(/Test$/, '').
212
- split('::').
213
- inject(Object) do |parent, local_name|
214
- parent.const_get(local_name, false)
215
- end
216
- end
217
-
218
- # Sets the return value of the subject instance method:
219
- #
220
- # class UserTest < Test::Unit::TestCase
221
- # subject { User.first }
222
- #
223
- # # uses the existing user
224
- # should validate_uniqueness_of(:email)
225
- # end
226
- def subject(&block)
227
- @subject_block = block
228
- end
229
-
230
- def subject_block # :nodoc:
231
- @subject_block ||= nil
232
- end
233
- end
234
-
235
- module InstanceMethods
236
- # Returns an instance of the class under test.
237
- #
238
- # class UserTest
239
- # should "be a user" do
240
- # assert_kind_of User, subject # passes
241
- # end
242
- # end
243
- #
244
- # The subject can be explicitly set using the subject class method:
245
- #
246
- # class UserTest
247
- # subject { User.first }
248
- # should "be an existing user" do
249
- # assert !subject.new_record? # uses the first user
250
- # end
251
- # end
252
- #
253
- # The subject is used by all macros that require an instance of the class
254
- # being tested.
255
- def subject
256
- @shoulda_subject ||= construct_subject
257
- end
258
-
259
- def subject_block # :nodoc:
260
- (@shoulda_context && @shoulda_context.subject_block) || self.class.subject_block
261
- end
262
-
263
- def get_instance_of(object_or_klass) # :nodoc:
264
- if object_or_klass.is_a?(Class)
265
- object_or_klass.new
266
- else
267
- object_or_klass
268
- end
269
- end
270
-
271
- def instance_variable_name_for(klass) # :nodoc:
272
- klass.to_s.split('::').last.underscore
273
- end
274
-
275
- private
276
-
277
- def construct_subject
278
- if subject_block
279
- instance_eval(&subject_block)
280
- else
281
- get_instance_of(self.class.described_type)
282
- end
283
- end
284
- end
285
-
286
3
  class Context # :nodoc:
287
-
288
4
  attr_accessor :name # my name
289
5
  attr_accessor :parent # may be another context, or the original test::unit class.
290
6
  attr_accessor :subcontexts # array of contexts nested under myself
@@ -389,38 +105,38 @@ module Shoulda
389
105
  end
390
106
 
391
107
  def create_test_from_should_hash(should)
392
- test_name = [test_name_prefix, full_name, "should", "#{should[:name]}. "].flatten.join(' ').to_sym
108
+ test_name = build_test_name_from(should)
393
109
 
394
- if test_methods[test_unit_class][test_name.to_s] then
395
- raise DuplicateTestError, "'#{test_name}' is defined more than once."
110
+ if test_methods[test_unit_class][test_name.to_s]
111
+ raise Shoulda::Context::DuplicateTestError.new(
112
+ "'#{test_name}' is defined more than once."
113
+ )
396
114
  end
397
-
398
115
  test_methods[test_unit_class][test_name.to_s] = true
399
- file, line_no = should[:block].source_location
116
+
400
117
  context = self
401
- test_unit_class.class_eval <<-end_eval, file, line_no
402
- define_method test_name do
118
+ test_unit_class.__send__(:define_method, test_name) do
403
119
  @shoulda_context = context
404
120
  begin
405
121
  context.run_parent_setup_blocks(self)
406
122
  if should[:before]
407
- if self.respond_to?(:instance_exec)
408
- self.instance_exec(&should[:before])
409
- else
410
- should[:before].bind(self).call
411
- end
123
+ instance_exec(&should[:before])
412
124
  end
413
125
  context.run_current_setup_blocks(self)
414
- if self.respond_to?(:instance_exec)
415
- self.instance_exec(&should[:block])
416
- else
417
- should[:block].bind(self).call
418
- end
126
+ instance_exec(&should[:block])
419
127
  ensure
420
128
  context.run_all_teardown_blocks(self)
421
129
  end
422
- end
423
- end_eval
130
+ end
131
+ end
132
+
133
+ def build_test_name_from(should)
134
+ [
135
+ test_name_prefix,
136
+ full_name,
137
+ "should",
138
+ "#{should[:name]}. "
139
+ ].flatten.join(' ').to_sym
424
140
  end
425
141
 
426
142
  def run_all_setup_blocks(binding)
@@ -473,7 +189,7 @@ module Shoulda
473
189
  end
474
190
 
475
191
  def test_name_prefix
476
- if defined?(Minitest) || defined?(MiniTest)
192
+ if defined?(Minitest)
477
193
  'test_:'
478
194
  else
479
195
  'test:'
@@ -484,7 +200,8 @@ module Shoulda
484
200
  test_unit_class.send(method, *args, &blk)
485
201
  end
486
202
  end
203
+
204
+ class DuplicateTestError < RuntimeError; end
487
205
  end
488
206
  end
489
207
 
490
- class DuplicateTestError < RuntimeError; end