shoulda-context 1.2.2 → 2.0.0.rc1

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.
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