shoulda-matchers 2.7.0 → 2.8.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (190) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +13 -3
  3. data/Appraisals +18 -0
  4. data/CONTRIBUTING.md +13 -29
  5. data/Gemfile +1 -4
  6. data/Gemfile.lock +2 -10
  7. data/NEWS.md +100 -14
  8. data/README.md +62 -58
  9. data/Rakefile +9 -16
  10. data/gemfiles/3.0.gemfile +11 -12
  11. data/gemfiles/3.0.gemfile.lock +15 -10
  12. data/gemfiles/3.1.gemfile +11 -12
  13. data/gemfiles/3.1.gemfile.lock +14 -10
  14. data/gemfiles/3.1_1.9.2.gemfile +12 -11
  15. data/gemfiles/3.1_1.9.2.gemfile.lock +14 -3
  16. data/gemfiles/3.2.gemfile +11 -12
  17. data/gemfiles/3.2.gemfile.lock +15 -10
  18. data/gemfiles/3.2_1.9.2.gemfile +12 -11
  19. data/gemfiles/3.2_1.9.2.gemfile.lock +14 -2
  20. data/gemfiles/4.0.0.gemfile +10 -12
  21. data/gemfiles/4.0.0.gemfile.lock +13 -10
  22. data/gemfiles/4.0.1.gemfile +10 -12
  23. data/gemfiles/4.0.1.gemfile.lock +13 -10
  24. data/gemfiles/4.1.gemfile +13 -15
  25. data/gemfiles/4.1.gemfile.lock +45 -50
  26. data/gemfiles/4.2.gemfile +36 -0
  27. data/gemfiles/4.2.gemfile.lock +245 -0
  28. data/lib/shoulda/matchers.rb +3 -1
  29. data/lib/shoulda/matchers/action_controller.rb +1 -1
  30. data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +1 -1
  31. data/lib/shoulda/matchers/action_controller/route_params.rb +9 -4
  32. data/lib/shoulda/matchers/action_controller/{set_the_flash_matcher.rb → set_flash_matcher.rb} +34 -26
  33. data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +125 -69
  34. data/lib/shoulda/matchers/active_model.rb +1 -2
  35. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +18 -5
  36. data/lib/shoulda/matchers/active_model/exception_message_finder.rb +2 -2
  37. data/lib/shoulda/matchers/active_model/helpers.rb +4 -4
  38. data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +10 -3
  39. data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +1 -1
  40. data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +3 -1
  41. data/lib/shoulda/matchers/active_model/{ensure_length_of_matcher.rb → validate_length_of_matcher.rb} +30 -20
  42. data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +21 -0
  43. data/lib/shoulda/matchers/active_model/validation_message_finder.rb +2 -2
  44. data/lib/shoulda/matchers/active_record.rb +2 -0
  45. data/lib/shoulda/matchers/active_record/association_matcher.rb +96 -2
  46. data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +1 -1
  47. data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +3 -3
  48. data/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +22 -2
  49. data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +30 -4
  50. data/lib/shoulda/matchers/active_record/serialize_matcher.rb +19 -3
  51. data/lib/shoulda/matchers/active_record/uniqueness.rb +14 -0
  52. data/lib/shoulda/matchers/active_record/uniqueness/model.rb +45 -0
  53. data/lib/shoulda/matchers/active_record/uniqueness/namespace.rb +36 -0
  54. data/lib/shoulda/matchers/active_record/uniqueness/test_model_creator.rb +50 -0
  55. data/lib/shoulda/matchers/active_record/uniqueness/test_models.rb +24 -0
  56. data/lib/shoulda/matchers/{active_model → active_record}/validate_uniqueness_of_matcher.rb +76 -16
  57. data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +117 -51
  58. data/lib/shoulda/matchers/independent/delegate_method_matcher/target_not_defined_error.rb +1 -1
  59. data/lib/shoulda/matchers/matcher_context.rb +35 -0
  60. data/lib/shoulda/matchers/rails_shim.rb +23 -0
  61. data/lib/shoulda/matchers/util.rb +28 -0
  62. data/lib/shoulda/matchers/version.rb +1 -1
  63. data/script/SUPPORTED_VERSIONS +1 -1
  64. data/spec/acceptance/active_model_integration_spec.rb +20 -0
  65. data/spec/acceptance/independent_matchers_spec.rb +64 -0
  66. data/spec/acceptance/rails_integration_spec.rb +142 -0
  67. data/spec/acceptance_spec_helper.rb +23 -0
  68. data/spec/support/acceptance/helpers.rb +29 -0
  69. data/spec/support/acceptance/helpers/active_model_helpers.rb +11 -0
  70. data/spec/support/acceptance/helpers/array_helpers.rb +13 -0
  71. data/spec/support/acceptance/helpers/base_helpers.rb +14 -0
  72. data/spec/support/acceptance/helpers/command_helpers.rb +51 -0
  73. data/spec/support/acceptance/helpers/file_helpers.rb +19 -0
  74. data/spec/support/acceptance/helpers/gem_helpers.rb +31 -0
  75. data/spec/support/acceptance/helpers/minitest_helpers.rb +19 -0
  76. data/spec/support/acceptance/helpers/pluralization_helpers.rb +13 -0
  77. data/spec/support/acceptance/helpers/rails_version_helpers.rb +11 -0
  78. data/spec/support/acceptance/helpers/rspec_helpers.rb +26 -0
  79. data/spec/support/acceptance/helpers/ruby_version_helpers.rb +9 -0
  80. data/spec/support/acceptance/helpers/step_helpers.rb +117 -0
  81. data/spec/support/acceptance/matchers/have_output.rb +31 -0
  82. data/spec/support/acceptance/matchers/indicate_number_of_tests_was_run_matcher.rb +55 -0
  83. data/spec/support/acceptance/matchers/indicate_that_tests_were_run_matcher.rb +103 -0
  84. data/spec/support/tests/bundle.rb +94 -0
  85. data/spec/support/tests/command_runner.rb +214 -0
  86. data/spec/support/tests/filesystem.rb +77 -0
  87. data/spec/support/tests/version.rb +45 -0
  88. data/spec/support/unit/capture.rb +34 -0
  89. data/spec/support/unit/helpers/active_model_helpers.rb +25 -0
  90. data/spec/support/unit/helpers/active_model_versions.rb +20 -0
  91. data/spec/support/unit/helpers/active_resource_builder.rb +27 -0
  92. data/spec/support/unit/helpers/allow_value_matcher_helpers.rb +15 -0
  93. data/spec/support/unit/helpers/class_builder.rb +72 -0
  94. data/spec/support/unit/helpers/confirmation_matcher_helpers.rb +17 -0
  95. data/spec/support/unit/helpers/controller_builder.rb +91 -0
  96. data/spec/support/unit/helpers/i18n_faker.rb +15 -0
  97. data/spec/support/unit/helpers/mailer_builder.rb +12 -0
  98. data/spec/support/unit/helpers/model_builder.rb +102 -0
  99. data/spec/support/unit/helpers/rails_versions.rb +28 -0
  100. data/spec/support/unit/i18n.rb +7 -0
  101. data/spec/support/unit/matchers/deprecate.rb +60 -0
  102. data/spec/support/unit/matchers/fail_with_message_including_matcher.rb +50 -0
  103. data/spec/support/unit/matchers/fail_with_message_matcher.rb +50 -0
  104. data/spec/support/unit/matchers/print_warning_including.rb +59 -0
  105. data/spec/support/unit/rails_application.rb +110 -0
  106. data/spec/support/unit/record_builder_with_i18n_validation_message.rb +69 -0
  107. data/spec/support/unit/record_validating_confirmation_builder.rb +56 -0
  108. data/spec/support/unit/record_with_different_error_attribute_builder.rb +92 -0
  109. data/spec/support/{shared_examples → unit/shared_examples}/numerical_submatcher.rb +0 -2
  110. data/spec/support/{shared_examples → unit/shared_examples}/numerical_type_submatcher.rb +0 -2
  111. data/spec/{shoulda → unit/shoulda}/matchers/action_controller/callback_matcher_spec.rb +2 -2
  112. data/spec/{shoulda → unit/shoulda}/matchers/action_controller/filter_param_matcher_spec.rb +2 -2
  113. data/spec/{shoulda → unit/shoulda}/matchers/action_controller/redirect_to_matcher_spec.rb +3 -3
  114. data/spec/{shoulda → unit/shoulda}/matchers/action_controller/render_template_matcher_spec.rb +2 -4
  115. data/spec/{shoulda → unit/shoulda}/matchers/action_controller/render_with_layout_matcher_spec.rb +9 -6
  116. data/spec/{shoulda → unit/shoulda}/matchers/action_controller/rescue_from_matcher_spec.rb +2 -2
  117. data/spec/{shoulda → unit/shoulda}/matchers/action_controller/respond_with_matcher_spec.rb +2 -2
  118. data/spec/unit/shoulda/matchers/action_controller/route_matcher_spec.rb +126 -0
  119. data/spec/{shoulda → unit/shoulda}/matchers/action_controller/route_params_spec.rb +2 -2
  120. data/spec/unit/shoulda/matchers/action_controller/set_flash_matcher_spec.rb +167 -0
  121. data/spec/unit/shoulda/matchers/action_controller/set_session_matcher_spec.rb +294 -0
  122. data/spec/{shoulda → unit/shoulda}/matchers/action_controller/strong_parameters_matcher_spec.rb +19 -11
  123. data/spec/{shoulda → unit/shoulda}/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +2 -2
  124. data/spec/{shoulda → unit/shoulda}/matchers/active_model/allow_value_matcher_spec.rb +49 -21
  125. data/spec/{shoulda → unit/shoulda}/matchers/active_model/disallow_value_matcher_spec.rb +8 -4
  126. data/spec/{shoulda → unit/shoulda}/matchers/active_model/exception_message_finder_spec.rb +4 -4
  127. data/spec/{shoulda → unit/shoulda}/matchers/active_model/have_secure_password_matcher_spec.rb +2 -2
  128. data/spec/{shoulda → unit/shoulda}/matchers/active_model/helpers_spec.rb +7 -3
  129. data/spec/{shoulda → unit/shoulda}/matchers/active_model/numericality_matchers/comparison_matcher_spec.rb +1 -1
  130. data/spec/{shoulda → unit/shoulda}/matchers/active_model/numericality_matchers/even_number_matcher_spec.rb +1 -1
  131. data/spec/{shoulda → unit/shoulda}/matchers/active_model/numericality_matchers/odd_number_matcher_spec.rb +1 -1
  132. data/spec/{shoulda → unit/shoulda}/matchers/active_model/numericality_matchers/only_integer_matcher_spec.rb +1 -1
  133. data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_absence_of_matcher_spec.rb +3 -3
  134. data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_acceptance_of_matcher_spec.rb +2 -2
  135. data/spec/unit/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +63 -0
  136. data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_exclusion_of_matcher_spec.rb +5 -4
  137. data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_inclusion_of_matcher_spec.rb +7 -14
  138. data/spec/{shoulda/matchers/active_model/ensure_length_of_matcher_spec.rb → unit/shoulda/matchers/active_model/validate_length_of_matcher_spec.rb} +43 -23
  139. data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_numericality_of_matcher_spec.rb +3 -4
  140. data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_presence_of_matcher_spec.rb +3 -3
  141. data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +127 -2
  142. data/spec/{shoulda → unit/shoulda}/matchers/active_model/validation_message_finder_spec.rb +8 -6
  143. data/spec/{shoulda → unit/shoulda}/matchers/active_record/accept_nested_attributes_for_matcher_spec.rb +2 -2
  144. data/spec/{shoulda → unit/shoulda}/matchers/active_record/association_matcher_spec.rb +217 -26
  145. data/spec/{shoulda → unit/shoulda}/matchers/active_record/association_matchers/model_reflection_spec.rb +2 -2
  146. data/spec/{shoulda → unit/shoulda}/matchers/active_record/define_enum_for_matcher_spec.rb +2 -2
  147. data/spec/{shoulda → unit/shoulda}/matchers/active_record/have_db_column_matcher_spec.rb +2 -2
  148. data/spec/{shoulda → unit/shoulda}/matchers/active_record/have_db_index_matcher_spec.rb +8 -5
  149. data/spec/{shoulda → unit/shoulda}/matchers/active_record/have_readonly_attributes_matcher_spec.rb +2 -2
  150. data/spec/{shoulda → unit/shoulda}/matchers/active_record/serialize_matcher_spec.rb +3 -3
  151. data/spec/{shoulda → unit/shoulda}/matchers/doublespeak/double_collection_spec.rb +29 -7
  152. data/spec/{shoulda → unit/shoulda}/matchers/doublespeak/double_implementation_registry_spec.rb +1 -1
  153. data/spec/{shoulda → unit/shoulda}/matchers/doublespeak/double_spec.rb +20 -10
  154. data/spec/{shoulda → unit/shoulda}/matchers/doublespeak/object_double_spec.rb +1 -1
  155. data/spec/{shoulda → unit/shoulda}/matchers/doublespeak/proxy_implementation_spec.rb +13 -6
  156. data/spec/{shoulda → unit/shoulda}/matchers/doublespeak/stub_implementation_spec.rb +2 -2
  157. data/spec/unit/shoulda/matchers/doublespeak/world_spec.rb +77 -0
  158. data/spec/{shoulda → unit/shoulda}/matchers/doublespeak_spec.rb +11 -3
  159. data/spec/{shoulda → unit/shoulda}/matchers/independent/delegate_method_matcher/stubbed_target_spec.rb +1 -1
  160. data/spec/unit/shoulda/matchers/independent/delegate_method_matcher_spec.rb +517 -0
  161. data/spec/unit_spec_helper.rb +66 -0
  162. data/spec/warnings_spy/partitioner.rb +10 -3
  163. data/spec/warnings_spy/reader.rb +9 -20
  164. data/spec/warnings_spy/reporter.rb +2 -1
  165. metadata +212 -149
  166. data/features/activemodel_integration.feature +0 -15
  167. data/features/rails_integration.feature +0 -160
  168. data/features/step_definitions/activemodel_steps.rb +0 -21
  169. data/features/step_definitions/rails_steps.rb +0 -227
  170. data/features/support/env.rb +0 -6
  171. data/spec/shoulda/matchers/action_controller/route_matcher_spec.rb +0 -70
  172. data/spec/shoulda/matchers/action_controller/set_session_matcher_spec.rb +0 -113
  173. data/spec/shoulda/matchers/action_controller/set_the_flash_matcher_spec.rb +0 -153
  174. data/spec/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +0 -47
  175. data/spec/shoulda/matchers/doublespeak/world_spec.rb +0 -70
  176. data/spec/shoulda/matchers/independent/delegate_method_matcher_spec.rb +0 -309
  177. data/spec/spec_helper.rb +0 -42
  178. data/spec/support/active_model_versions.rb +0 -13
  179. data/spec/support/active_resource_builder.rb +0 -29
  180. data/spec/support/activemodel_helpers.rb +0 -23
  181. data/spec/support/capture_helpers.rb +0 -19
  182. data/spec/support/class_builder.rb +0 -46
  183. data/spec/support/controller_builder.rb +0 -102
  184. data/spec/support/fail_with_message_including_matcher.rb +0 -44
  185. data/spec/support/fail_with_message_matcher.rb +0 -44
  186. data/spec/support/i18n_faker.rb +0 -10
  187. data/spec/support/mailer_builder.rb +0 -10
  188. data/spec/support/model_builder.rb +0 -81
  189. data/spec/support/rails_versions.rb +0 -26
  190. data/spec/support/test_application.rb +0 -120
@@ -0,0 +1,15 @@
1
+ require_relative '../record_with_different_error_attribute_builder'
2
+ require_relative '../record_builder_with_i18n_validation_message'
3
+
4
+ module UnitTests
5
+ module AllowValueMatcherHelpers
6
+ def builder_for_record_with_different_error_attribute(options = {})
7
+ RecordWithDifferentErrorAttributeBuilder.new(options)
8
+ end
9
+
10
+ def builder_for_record_with_different_error_attribute_using_i18n(options = {})
11
+ builder = builder_for_record_with_different_error_attribute(options)
12
+ RecordBuilderWithI18nValidationMessage.new(builder)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,72 @@
1
+ module UnitTests
2
+ module ClassBuilder
3
+ def self.parse_constant_name(name)
4
+ namespace = Shoulda::Matchers::Util.deconstantize(name)
5
+ qualified_namespace = (namespace.presence || 'Object').constantize
6
+ name_without_namespace = name.to_s.demodulize
7
+ [qualified_namespace, name_without_namespace]
8
+ end
9
+
10
+ def self.configure_example_group(example_group)
11
+ example_group.include(self)
12
+
13
+ example_group.after do
14
+ teardown_defined_constants
15
+ end
16
+ end
17
+
18
+ def define_module(module_name, &block)
19
+ module_name = module_name.to_s.camelize
20
+
21
+ namespace, name_without_namespace =
22
+ ClassBuilder.parse_constant_name(module_name)
23
+
24
+ if namespace.const_defined?(name_without_namespace, false)
25
+ namespace.__send__(:remove_const, name_without_namespace)
26
+ end
27
+
28
+ eval <<-RUBY
29
+ module #{namespace}::#{name_without_namespace}
30
+ end
31
+ RUBY
32
+
33
+ namespace.const_get(name_without_namespace).tap do |constant|
34
+ constant.unloadable
35
+
36
+ if block
37
+ constant.module_eval(&block)
38
+ end
39
+ end
40
+ end
41
+
42
+ def define_class(class_name, parent_class = Object, &block)
43
+ class_name = class_name.to_s.camelize
44
+
45
+ namespace, name_without_namespace =
46
+ ClassBuilder.parse_constant_name(class_name)
47
+
48
+ if namespace.const_defined?(name_without_namespace, false)
49
+ namespace.__send__(:remove_const, name_without_namespace)
50
+ end
51
+
52
+ eval <<-RUBY
53
+ class #{namespace}::#{name_without_namespace} < #{parent_class}
54
+ end
55
+ RUBY
56
+
57
+ namespace.const_get(name_without_namespace).tap do |constant|
58
+ constant.unloadable
59
+
60
+ if block_given?
61
+ constant.class_eval(&block)
62
+ end
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ def teardown_defined_constants
69
+ ActiveSupport::Dependencies.clear
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,17 @@
1
+ require_relative '../record_validating_confirmation_builder'
2
+ require_relative '../record_builder_with_i18n_validation_message'
3
+
4
+ module UnitTests
5
+ module ConfirmationMatcherHelpers
6
+ def builder_for_record_validating_confirmation(options = {})
7
+ RecordValidatingConfirmationBuilder.new(options)
8
+ end
9
+
10
+ def builder_for_record_validating_confirmation_with_18n_message(options = {})
11
+ builder = builder_for_record_validating_confirmation(options)
12
+ RecordBuilderWithI18nValidationMessage.new(builder,
13
+ validation_message_key: :confirmation
14
+ )
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,91 @@
1
+ module UnitTests
2
+ module ControllerBuilder
3
+ def self.configure_example_group(example_group)
4
+ example_group.include(self)
5
+
6
+ example_group.after do
7
+ delete_temporary_views
8
+ restore_original_routes
9
+ end
10
+ end
11
+
12
+ def define_controller(class_name, &block)
13
+ class_name = class_name.to_s
14
+ class_name << 'Controller' unless class_name =~ /Controller$/
15
+ define_class(class_name, ActionController::Base, &block)
16
+ end
17
+
18
+ def define_routes(&block)
19
+ self.routes = $test_app.draw_routes(&block)
20
+ end
21
+
22
+ def build_fake_response(opts = {}, &block)
23
+ action = opts[:action] || 'example'
24
+ partial = opts[:partial] || '_partial'
25
+ block ||= lambda { render nothing: true }
26
+ controller_class = define_controller('Examples') do
27
+ layout false
28
+ define_method(action, &block)
29
+ end
30
+ controller_class.view_paths = [ $test_app.temp_views_directory.to_s ]
31
+
32
+ define_routes do
33
+ get 'examples', to: "examples##{action}"
34
+ end
35
+
36
+ create_view("examples/#{action}.html.erb", 'action')
37
+ create_view("examples/#{partial}.html.erb", 'partial')
38
+
39
+ setup_rails_controller_test(controller_class)
40
+ self.class.render_views(true)
41
+
42
+ get action
43
+
44
+ controller
45
+ end
46
+
47
+ def setup_rails_controller_test(controller_class)
48
+ @controller = controller_class.new
49
+ end
50
+
51
+ def create_view(path, contents)
52
+ $test_app.create_temp_view(path, contents)
53
+ end
54
+
55
+ def controller_for_resource_with_strong_parameters(options = {}, &action_body)
56
+ model_name = options.fetch(:model_name, 'User')
57
+ controller_name = options.fetch(:controller_name, 'UsersController')
58
+ collection_name = controller_name.
59
+ to_s.sub(/Controller$/, '').underscore.
60
+ to_sym
61
+ action_name = options.fetch(:action, :some_action)
62
+ routes ||= options.fetch(:routes, -> { resources collection_name })
63
+
64
+ define_model(model_name)
65
+
66
+ controller_class = define_controller(controller_name) do
67
+ define_method action_name do
68
+ if action_body
69
+ instance_eval(&action_body)
70
+ end
71
+
72
+ render nothing: true
73
+ end
74
+ end
75
+
76
+ setup_rails_controller_test(controller_class)
77
+
78
+ define_routes(&routes)
79
+
80
+ controller_class
81
+ end
82
+
83
+ def delete_temporary_views
84
+ $test_app.delete_temp_views
85
+ end
86
+
87
+ def restore_original_routes
88
+ Rails.application.reload_routes!
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,15 @@
1
+ module UnitTests
2
+ module I18nFaker
3
+ extend self
4
+
5
+ def self.configure_example_group(example_group)
6
+ example_group.include(self)
7
+ end
8
+
9
+ def stub_translation(key_or_keys, message)
10
+ keys = [key_or_keys].flatten.join('.').split('.')
11
+ tree = keys.reverse.inject(message) { |data, key| { key => data } }
12
+ I18n.backend.store_translations(:en, tree)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ module UnitTests
2
+ module MailerBuilder
3
+ def self.configure_example_group(example_group)
4
+ example_group.include(self)
5
+ end
6
+
7
+ def define_mailer(name, paths, &block)
8
+ class_name = name.to_s.pluralize.classify
9
+ define_class(class_name, ActionMailer::Base, &block)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,102 @@
1
+ require_relative 'class_builder'
2
+
3
+ module UnitTests
4
+ module ModelBuilder
5
+ include ClassBuilder
6
+
7
+ def self.configure_example_group(example_group)
8
+ example_group.include(self)
9
+
10
+ example_group.after do
11
+ clear_column_caches
12
+ drop_created_tables
13
+ end
14
+ end
15
+
16
+ def create_table(table_name, options = {}, &block)
17
+ connection = ActiveRecord::Base.connection
18
+
19
+ begin
20
+ connection.execute("DROP TABLE IF EXISTS #{table_name}")
21
+ connection.create_table(table_name, options, &block)
22
+ created_tables << table_name
23
+ connection
24
+ rescue Exception => e
25
+ connection.execute("DROP TABLE IF EXISTS #{table_name}")
26
+ raise e
27
+ end
28
+ end
29
+
30
+ def define_model_class(class_name, &block)
31
+ define_class(class_name, ActiveRecord::Base, &block)
32
+ end
33
+
34
+ def define_active_model_class(class_name, options = {}, &block)
35
+ define_class(class_name) do
36
+ include ActiveModel::Validations
37
+
38
+ options[:accessors].each do |column|
39
+ attr_accessor column.to_sym
40
+ end
41
+
42
+ if block_given?
43
+ class_eval(&block)
44
+ end
45
+ end
46
+ end
47
+
48
+ def define_model(name, columns = {}, &block)
49
+ class_name = name.to_s.pluralize.classify
50
+ table_name = class_name.tableize.gsub('/', '_')
51
+
52
+ table_block = lambda do |table|
53
+ columns.each do |column_name, specification|
54
+ if specification.is_a?(Hash)
55
+ table.column column_name, specification[:type], specification[:options]
56
+ else
57
+ table.column column_name, specification
58
+ end
59
+ end
60
+ end
61
+
62
+ if columns.key?(:id) && columns[:id] == false
63
+ columns.delete(:id)
64
+ create_table(table_name, id: false, &table_block)
65
+ else
66
+ create_table(table_name, &table_block)
67
+ end
68
+
69
+ define_model_class(class_name).tap do |model|
70
+ if block
71
+ model.class_eval(&block)
72
+ end
73
+
74
+ model.table_name = table_name
75
+ end
76
+ end
77
+
78
+ private
79
+
80
+ def clear_column_caches
81
+ # Rails 4.x
82
+ if ActiveRecord::Base.connection.respond_to?(:schema_cache)
83
+ ActiveRecord::Base.connection.schema_cache.clear!
84
+ # Rails 3.1 - 4.0
85
+ elsif ActiveRecord::Base.connection_pool.respond_to?(:clear_cache!)
86
+ ActiveRecord::Base.connection_pool.clear_cache!
87
+ end
88
+ end
89
+
90
+ def drop_created_tables
91
+ connection = ActiveRecord::Base.connection
92
+
93
+ created_tables.each do |table_name|
94
+ connection.execute("DROP TABLE IF EXISTS #{table_name}")
95
+ end
96
+ end
97
+
98
+ def created_tables
99
+ @_created_tables ||= []
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,28 @@
1
+ module UnitTests
2
+ module RailsVersions
3
+ def self.configure_example_group(example_group)
4
+ example_group.include(self)
5
+ example_group.extend(self)
6
+ end
7
+
8
+ def rails_version
9
+ Gem::Version.new(Rails::VERSION::STRING)
10
+ end
11
+
12
+ def rails_3_x?
13
+ Gem::Requirement.new('~> 3.0').satisfied_by?(rails_version)
14
+ end
15
+
16
+ def rails_4_x?
17
+ Gem::Requirement.new('~> 4.0').satisfied_by?(rails_version)
18
+ end
19
+
20
+ def rails_gte_4_1?
21
+ Gem::Requirement.new('>= 4.1').satisfied_by?(rails_version)
22
+ end
23
+
24
+ def active_record_supports_enum?
25
+ defined?(::ActiveRecord::Enum)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,7 @@
1
+ RSpec.configure do |config|
2
+ config.after do
3
+ # Clear any translations added during tests by telling the backend to
4
+ # replace its translations with whatever is in the YAML files.
5
+ I18n.backend.reload!
6
+ end
7
+ end
@@ -0,0 +1,60 @@
1
+ module UnitTests
2
+ module Matchers
3
+ def deprecate(old_method, new_method)
4
+ DeprecateMatcher.new(old_method, new_method)
5
+ end
6
+
7
+ class DeprecateMatcher
8
+ def initialize(old_method, new_method)
9
+ @old_method = old_method
10
+ @new_method = new_method
11
+ end
12
+
13
+ def matches?(block)
14
+ @captured_stderr = capture(:stderr, &block).gsub(/\n+/, ' ')
15
+ captured_stderr.include?(expected_message)
16
+ end
17
+
18
+ def failure_message
19
+ "Expected block to #{expectation}, but it did not.\nActual warning: #{actual_warning}"
20
+ end
21
+ alias_method :failure_message_for_should, :failure_message
22
+
23
+ def failure_message_when_negated
24
+ "Expected block not to #{expectation}, but it did."
25
+ end
26
+ alias_method :failure_message_for_should_not,
27
+ :failure_message_when_negated
28
+
29
+ def description
30
+ "should #{expectation}"
31
+ end
32
+
33
+ def supports_block_expectations?
34
+ true
35
+ end
36
+
37
+ protected
38
+
39
+ attr_reader :old_method, :new_method, :captured_stderr
40
+
41
+ private
42
+
43
+ def expected_message
44
+ "#{old_method} is deprecated and will be removed in the next major release. Please use #{new_method} instead."
45
+ end
46
+
47
+ def expectation
48
+ "print a warning deprecating #{old_method} in favor of #{new_method}"
49
+ end
50
+
51
+ def actual_warning
52
+ if captured_stderr.empty?
53
+ "nothing"
54
+ else
55
+ "\n #{captured_stderr}"
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,50 @@
1
+ module UnitTests
2
+ module Matchers
3
+ extend RSpec::Matchers::DSL
4
+
5
+ matcher :fail_with_message_including do |expected|
6
+ def supports_block_expectations?
7
+ true
8
+ end
9
+
10
+ match do |block|
11
+ @actual = nil
12
+
13
+ begin
14
+ block.call
15
+ rescue RSpec::Expectations::ExpectationNotMetError => ex
16
+ @actual = ex.message
17
+ end
18
+
19
+ @actual && @actual.include?(expected)
20
+ end
21
+
22
+ def failure_message
23
+ msg = "Expectation should have failed with message including '#{expected}'"
24
+
25
+ if @actual
26
+ msg << ",\nactually failed with '#{@actual}'"
27
+ else
28
+ msg << ", but did not fail."
29
+ end
30
+
31
+ msg
32
+ end
33
+
34
+ def failure_message_for_should
35
+ failure_message
36
+ end
37
+
38
+ def failure_message_when_negated
39
+ msg = "Expectation should not have failed with message including '#{expected}'"
40
+ msg << ", but did."
41
+
42
+ msg
43
+ end
44
+
45
+ def failure_message_for_should_not
46
+ failure_message_when_negated
47
+ end
48
+ end
49
+ end
50
+ end