shoulda-matchers 2.8.0 → 3.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (171) hide show
  1. checksums.yaml +4 -4
  2. data/.hound_config/ruby.yml +7 -0
  3. data/.travis.yml +11 -54
  4. data/Appraisals +45 -100
  5. data/CONTRIBUTING.md +51 -7
  6. data/Gemfile +7 -19
  7. data/Gemfile.lock +60 -134
  8. data/Guardfile +5 -0
  9. data/NEWS.md +203 -0
  10. data/README.md +95 -50
  11. data/Rakefile +1 -0
  12. data/doc_config/yard/templates/default/layout/html/setup.rb +1 -1
  13. data/gemfiles/4.0.0.gemfile +10 -7
  14. data/gemfiles/4.0.0.gemfile.lock +103 -79
  15. data/gemfiles/4.0.1.gemfile +10 -7
  16. data/gemfiles/4.0.1.gemfile.lock +109 -83
  17. data/gemfiles/4.1.gemfile +10 -7
  18. data/gemfiles/4.1.gemfile.lock +109 -85
  19. data/gemfiles/4.2.gemfile +10 -9
  20. data/gemfiles/4.2.gemfile.lock +86 -78
  21. data/lib/shoulda/matchers.rb +13 -18
  22. data/lib/shoulda/matchers/action_controller.rb +4 -1
  23. data/lib/shoulda/matchers/action_controller/flash_store.rb +95 -0
  24. data/lib/shoulda/matchers/action_controller/{strong_parameters_matcher.rb → permit_matcher.rb} +147 -30
  25. data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +1 -1
  26. data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +1 -1
  27. data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +1 -1
  28. data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +1 -1
  29. data/lib/shoulda/matchers/action_controller/route_matcher.rb +5 -1
  30. data/lib/shoulda/matchers/action_controller/route_params.rb +15 -6
  31. data/lib/shoulda/matchers/action_controller/session_store.rb +34 -0
  32. data/lib/shoulda/matchers/action_controller/set_flash_matcher.rb +30 -136
  33. data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +28 -109
  34. data/lib/shoulda/matchers/action_controller/set_session_or_flash_matcher.rb +103 -0
  35. data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +1 -12
  36. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +79 -10
  37. data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +10 -0
  38. data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +21 -0
  39. data/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +24 -0
  40. data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +22 -5
  41. data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +29 -10
  42. data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +27 -10
  43. data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +27 -12
  44. data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +56 -20
  45. data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +3 -11
  46. data/lib/shoulda/matchers/active_model/validation_message_finder.rb +65 -0
  47. data/lib/shoulda/matchers/active_record/association_matcher.rb +40 -6
  48. data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +21 -7
  49. data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +11 -40
  50. data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +1 -1
  51. data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +2 -6
  52. data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +137 -22
  53. data/lib/shoulda/matchers/configuration.rb +20 -0
  54. data/lib/shoulda/matchers/doublespeak.rb +11 -1
  55. data/lib/shoulda/matchers/doublespeak/double.rb +29 -11
  56. data/lib/shoulda/matchers/doublespeak/double_collection.rb +4 -3
  57. data/lib/shoulda/matchers/doublespeak/method_call.rb +35 -0
  58. data/lib/shoulda/matchers/doublespeak/object_double.rb +7 -2
  59. data/lib/shoulda/matchers/doublespeak/proxy_implementation.rb +4 -3
  60. data/lib/shoulda/matchers/doublespeak/stub_implementation.rb +3 -3
  61. data/lib/shoulda/matchers/doublespeak/world.rb +21 -1
  62. data/lib/shoulda/matchers/integrations.rb +43 -0
  63. data/lib/shoulda/matchers/integrations/configuration.rb +68 -0
  64. data/lib/shoulda/matchers/integrations/configuration_error.rb +9 -0
  65. data/lib/shoulda/matchers/integrations/inclusion.rb +20 -0
  66. data/lib/shoulda/matchers/integrations/libraries.rb +15 -0
  67. data/lib/shoulda/matchers/integrations/libraries/action_controller.rb +31 -0
  68. data/lib/shoulda/matchers/integrations/libraries/active_model.rb +26 -0
  69. data/lib/shoulda/matchers/integrations/libraries/active_record.rb +26 -0
  70. data/lib/shoulda/matchers/integrations/libraries/missing_library.rb +19 -0
  71. data/lib/shoulda/matchers/integrations/libraries/rails.rb +30 -0
  72. data/lib/shoulda/matchers/integrations/rails.rb +12 -0
  73. data/lib/shoulda/matchers/integrations/registry.rb +28 -0
  74. data/lib/shoulda/matchers/integrations/test_frameworks.rb +16 -0
  75. data/lib/shoulda/matchers/integrations/test_frameworks/active_support_test_case.rb +37 -0
  76. data/lib/shoulda/matchers/integrations/test_frameworks/minitest_4.rb +36 -0
  77. data/lib/shoulda/matchers/integrations/test_frameworks/minitest_5.rb +37 -0
  78. data/lib/shoulda/matchers/integrations/test_frameworks/missing_test_framework.rb +40 -0
  79. data/lib/shoulda/matchers/integrations/test_frameworks/rspec.rb +29 -0
  80. data/lib/shoulda/matchers/integrations/test_frameworks/test_unit.rb +36 -0
  81. data/lib/shoulda/matchers/rails_shim.rb +0 -40
  82. data/lib/shoulda/matchers/version.rb +1 -1
  83. data/script/SUPPORTED_VERSIONS +1 -1
  84. data/script/update_gems_in_all_appraisals +14 -0
  85. data/shoulda-matchers.gemspec +2 -2
  86. data/spec/acceptance/active_model_integration_spec.rb +4 -1
  87. data/spec/acceptance/independent_matchers_spec.rb +6 -6
  88. data/spec/acceptance/multiple_libraries_integration_spec.rb +52 -0
  89. data/spec/acceptance/rails_integration_spec.rb +15 -5
  90. data/spec/acceptance_spec_helper.rb +8 -0
  91. data/spec/doublespeak_spec_helper.rb +14 -0
  92. data/spec/support/acceptance/adds_shoulda_matchers_to_project.rb +110 -0
  93. data/spec/support/acceptance/helpers.rb +2 -0
  94. data/spec/support/acceptance/helpers/base_helpers.rb +6 -1
  95. data/spec/support/acceptance/helpers/command_helpers.rb +6 -2
  96. data/spec/support/acceptance/helpers/minitest_helpers.rb +0 -8
  97. data/spec/support/acceptance/helpers/n_unit_helpers.rb +25 -0
  98. data/spec/support/acceptance/helpers/rspec_helpers.rb +2 -0
  99. data/spec/support/acceptance/helpers/step_helpers.rb +13 -19
  100. data/spec/support/acceptance/matchers/have_output.rb +1 -1
  101. data/spec/support/tests/bundle.rb +1 -1
  102. data/spec/support/tests/command_runner.rb +25 -13
  103. data/spec/support/tests/current_bundle.rb +47 -0
  104. data/spec/support/tests/database.rb +28 -0
  105. data/spec/support/tests/database_adapters/postgresql.rb +25 -0
  106. data/spec/support/tests/database_adapters/sqlite3.rb +26 -0
  107. data/spec/support/tests/database_configuration.rb +33 -0
  108. data/spec/support/tests/database_configuration_registry.rb +28 -0
  109. data/spec/support/tests/filesystem.rb +25 -2
  110. data/spec/support/unit/helpers/active_record_versions.rb +12 -0
  111. data/spec/support/unit/helpers/class_builder.rb +6 -2
  112. data/spec/support/unit/helpers/column_type_helpers.rb +26 -0
  113. data/spec/support/unit/helpers/controller_builder.rb +0 -28
  114. data/spec/support/unit/helpers/database_helpers.rb +18 -0
  115. data/spec/support/unit/helpers/model_builder.rb +38 -6
  116. data/spec/support/unit/helpers/rails_versions.rb +2 -2
  117. data/spec/support/unit/matchers/fail_with_message_including_matcher.rb +9 -8
  118. data/spec/support/unit/matchers/fail_with_message_matcher.rb +1 -1
  119. data/spec/support/unit/rails_application.rb +29 -13
  120. data/spec/support/unit/record_validating_confirmation_builder.rb +1 -2
  121. data/spec/support/unit/shared_examples/set_session_or_flash.rb +355 -0
  122. data/spec/unit/shoulda/matchers/action_controller/permit_matcher_spec.rb +433 -0
  123. data/spec/unit/shoulda/matchers/action_controller/render_with_layout_matcher_spec.rb +1 -5
  124. data/spec/unit/shoulda/matchers/action_controller/route_matcher_spec.rb +37 -0
  125. data/spec/unit/shoulda/matchers/action_controller/set_flash_matcher_spec.rb +23 -147
  126. data/spec/unit/shoulda/matchers/action_controller/set_session_matcher_spec.rb +8 -285
  127. data/spec/unit/shoulda/matchers/action_controller/set_session_or_flash_matcher_spec.rb +562 -0
  128. data/spec/unit/shoulda/matchers/active_model/allow_value_matcher_spec.rb +81 -14
  129. data/spec/unit/shoulda/matchers/active_model/disallow_value_matcher_spec.rb +16 -8
  130. data/spec/unit/shoulda/matchers/active_model/numericality_matchers/comparison_matcher_spec.rb +101 -9
  131. data/spec/unit/shoulda/matchers/active_model/numericality_matchers/even_number_matcher_spec.rb +39 -1
  132. data/spec/unit/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher_spec.rb +39 -1
  133. data/spec/unit/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher_spec.rb +39 -0
  134. data/spec/unit/shoulda/matchers/active_model/validate_exclusion_of_matcher_spec.rb +0 -17
  135. data/spec/unit/shoulda/matchers/active_model/validate_inclusion_of_matcher_spec.rb +0 -17
  136. data/spec/unit/shoulda/matchers/active_model/validate_length_of_matcher_spec.rb +0 -17
  137. data/spec/unit/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +838 -271
  138. data/spec/unit/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +0 -19
  139. data/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb +93 -0
  140. data/spec/unit/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb +3 -3
  141. data/spec/unit/shoulda/matchers/active_record/define_enum_for_matcher_spec.rb +25 -0
  142. data/spec/unit/shoulda/matchers/active_record/validate_uniqueness_of_matcher_spec.rb +905 -0
  143. data/spec/unit/shoulda/matchers/doublespeak/double_collection_spec.rb +17 -11
  144. data/spec/unit/shoulda/matchers/doublespeak/double_implementation_registry_spec.rb +1 -1
  145. data/spec/unit/shoulda/matchers/doublespeak/double_spec.rb +144 -43
  146. data/spec/unit/shoulda/matchers/doublespeak/object_double_spec.rb +1 -1
  147. data/spec/unit/shoulda/matchers/doublespeak/proxy_implementation_spec.rb +36 -11
  148. data/spec/unit/shoulda/matchers/doublespeak/stub_implementation_spec.rb +29 -16
  149. data/spec/unit/shoulda/matchers/doublespeak/world_spec.rb +8 -5
  150. data/spec/unit/shoulda/matchers/doublespeak_spec.rb +1 -1
  151. data/spec/unit_spec_helper.rb +15 -14
  152. data/spec/warnings_spy.rb +1 -1
  153. metadata +68 -29
  154. data/docs.watchr +0 -5
  155. data/gemfiles/3.0.gemfile +0 -26
  156. data/gemfiles/3.0.gemfile.lock +0 -173
  157. data/gemfiles/3.1.gemfile +0 -32
  158. data/gemfiles/3.1.gemfile.lock +0 -212
  159. data/gemfiles/3.1_1.9.2.gemfile +0 -32
  160. data/gemfiles/3.1_1.9.2.gemfile.lock +0 -212
  161. data/gemfiles/3.2.gemfile +0 -33
  162. data/gemfiles/3.2.gemfile.lock +0 -212
  163. data/gemfiles/3.2_1.9.2.gemfile +0 -31
  164. data/gemfiles/3.2_1.9.2.gemfile.lock +0 -207
  165. data/lib/shoulda/matchers/assertion_error.rb +0 -27
  166. data/lib/shoulda/matchers/doublespeak/structs.rb +0 -10
  167. data/lib/shoulda/matchers/integrations/nunit_test_case_detection.rb +0 -39
  168. data/lib/shoulda/matchers/integrations/rspec.rb +0 -19
  169. data/lib/shoulda/matchers/integrations/test_unit.rb +0 -34
  170. data/spec/unit/shoulda/matchers/action_controller/strong_parameters_matcher_spec.rb +0 -331
  171. data/spec/unit/shoulda/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +0 -564
@@ -0,0 +1,47 @@
1
+ require 'bundler'
2
+ require 'appraisal'
3
+
4
+ module Tests
5
+ class CurrentBundle
6
+ AppraisalNotSpecified = Class.new(ArgumentError)
7
+
8
+ include Singleton
9
+
10
+ def assert_appraisal!
11
+ unless appraisal?
12
+ message = <<EOT
13
+
14
+
15
+ Please run tests starting with `appraisal <appraisal_name>`.
16
+ Possible appraisals are: #{possible_appraisals}
17
+
18
+ EOT
19
+ raise AppraisalNotSpecified, message
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def possible_appraisals
26
+ appraisals = []
27
+
28
+ Appraisal::File.each do |appraisal|
29
+ appraisals << appraisal.name
30
+ end
31
+
32
+ appraisals
33
+ end
34
+
35
+ def path
36
+ Bundler.default_gemfile
37
+ end
38
+
39
+ def appraisal?
40
+ path.dirname == root.join('gemfiles')
41
+ end
42
+
43
+ def root
44
+ Pathname.new('../../../..').expand_path(__FILE__)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,28 @@
1
+ require_relative 'database_configuration'
2
+
3
+ module Tests
4
+ class Database
5
+ NAME = 'shoulda-matchers-test'
6
+ ADAPTER_NAME = ENV.fetch('DATABASE_ADAPTER', 'sqlite3').to_sym
7
+
8
+ include Singleton
9
+
10
+ attr_reader :config
11
+
12
+ def initialize
13
+ @config = Tests::DatabaseConfiguration.for(NAME, ADAPTER_NAME)
14
+ end
15
+
16
+ def name
17
+ config.database
18
+ end
19
+
20
+ def adapter_name
21
+ config.adapter
22
+ end
23
+
24
+ def adapter_class
25
+ config.adapter_class
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,25 @@
1
+ module Tests
2
+ module DatabaseAdapters
3
+ class PostgreSQL
4
+ def self.name
5
+ :postgresql
6
+ end
7
+
8
+ attr_reader :database
9
+
10
+ def initialize(database)
11
+ @database = database
12
+ end
13
+
14
+ def adapter
15
+ self.class.name
16
+ end
17
+
18
+ def require_dependencies
19
+ require 'pg'
20
+ end
21
+ end
22
+
23
+ DatabaseConfigurationRegistry.instance.register(PostgreSQL)
24
+ end
25
+ end
@@ -0,0 +1,26 @@
1
+ module Tests
2
+ module DatabaseAdapters
3
+ class SQLite3
4
+ def self.name
5
+ :sqlite3
6
+ end
7
+
8
+ def initialize(_database)
9
+ end
10
+
11
+ def adapter
12
+ self.class.name
13
+ end
14
+
15
+ def database
16
+ 'db/db.sqlite3'
17
+ end
18
+
19
+ def require_dependencies
20
+ require 'sqlite3'
21
+ end
22
+ end
23
+
24
+ DatabaseConfigurationRegistry.instance.register(SQLite3)
25
+ end
26
+ end
@@ -0,0 +1,33 @@
1
+ require_relative 'database_configuration_registry'
2
+ require 'delegate'
3
+
4
+ module Tests
5
+ class DatabaseConfiguration < SimpleDelegator
6
+ ENVIRONMENTS = %w(development test production)
7
+
8
+ attr_reader :adapter_class
9
+
10
+ def self.for(database_name, adapter_name)
11
+ config_class = DatabaseConfigurationRegistry.instance.get(adapter_name)
12
+ config = config_class.new(database_name)
13
+ new(config)
14
+ end
15
+
16
+ def initialize(config)
17
+ @adapter_class = config.class.to_s.split('::').last
18
+ super(config)
19
+ end
20
+
21
+ def to_hash
22
+ ENVIRONMENTS.each_with_object({}) do |env, config_as_hash|
23
+ config_as_hash[env] = inner_config_as_hash
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def inner_config_as_hash
30
+ { 'adapter' => adapter.to_s, 'database' => database.to_s }
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ require 'singleton'
2
+
3
+ module Tests
4
+ class DatabaseConfigurationRegistry
5
+ include Singleton
6
+
7
+ def initialize
8
+ @registry = {}
9
+ end
10
+
11
+ def register(config_class)
12
+ registry[config_class.name] = config_class
13
+ end
14
+
15
+ def get(name)
16
+ registry.fetch(name) do
17
+ raise KeyError, "No such adapter registered: #{name}"
18
+ end
19
+ end
20
+
21
+ protected
22
+
23
+ attr_reader :registry
24
+ end
25
+ end
26
+
27
+ require_relative 'database_adapters/postgresql'
28
+ require_relative 'database_adapters/sqlite3'
@@ -69,9 +69,32 @@ module Tests
69
69
  end
70
70
 
71
71
  def remove_from_file(path, pattern)
72
+ unless pattern.is_a?(Regexp)
73
+ pattern = Regexp.new('^' + Regexp.escape(pattern) + '$')
74
+ end
75
+
76
+ transform(path) do |lines|
77
+ lines.reject { |line| line =~ pattern }
78
+ end
79
+ end
80
+
81
+ def comment_lines_matching(path, pattern)
82
+ transform(path) do |lines|
83
+ lines.map do |line|
84
+ if line =~ pattern
85
+ "###{line}"
86
+ else
87
+ line
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ def transform(path)
72
94
  content = read(path)
73
- content.sub!(/#{pattern}\n/, '')
74
- write(path, content)
95
+ lines = content.split(/\n/)
96
+ transformed_lines = yield lines
97
+ write(path, transformed_lines.join("\n") + "\n")
75
98
  end
76
99
  end
77
100
  end
@@ -12,5 +12,17 @@ module UnitTests
12
12
  def active_record_can_raise_range_error?
13
13
  active_record_version >= 4.2
14
14
  end
15
+
16
+ def active_record_supports_enum?
17
+ defined?(::ActiveRecord::Enum)
18
+ end
19
+
20
+ def active_record_supports_has_secure_password?
21
+ active_record_version >= 3.1
22
+ end
23
+
24
+ def active_record_supports_array_columns?
25
+ active_record_version > 4.2
26
+ end
15
27
  end
16
28
  end
@@ -57,8 +57,12 @@ module UnitTests
57
57
  namespace.const_get(name_without_namespace).tap do |constant|
58
58
  constant.unloadable
59
59
 
60
- if block_given?
61
- constant.class_eval(&block)
60
+ if block
61
+ if block.arity == 0
62
+ constant.class_eval(&block)
63
+ else
64
+ block.call(constant)
65
+ end
62
66
  end
63
67
  end
64
68
  end
@@ -0,0 +1,26 @@
1
+ module UnitTests
2
+ module ColumnTypeHelpers
3
+ def self.configure_example_group(example_group)
4
+ example_group.include(self)
5
+ end
6
+
7
+ def column_type_class_namespace
8
+ if database_adapter == :postgresql
9
+ ActiveRecord::ConnectionAdapters::PostgreSQL
10
+ else
11
+ ActiveRecord::Type
12
+ end
13
+ end
14
+
15
+ def column_type_class_for(type)
16
+ namespace =
17
+ if type == :integer && database_adapter == :postgresql
18
+ column_type_class_namespace::OID
19
+ else
20
+ column_type_class_namespace
21
+ end
22
+
23
+ namespace.const_get(type.to_s.camelize)
24
+ end
25
+ end
26
+ end
@@ -52,34 +52,6 @@ module UnitTests
52
52
  $test_app.create_temp_view(path, contents)
53
53
  end
54
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
55
  def delete_temporary_views
84
56
  $test_app.delete_temp_views
85
57
  end
@@ -0,0 +1,18 @@
1
+ module UnitTests
2
+ module DatabaseHelpers
3
+ def self.configure_example_group(example_group)
4
+ example_group.include(self)
5
+ example_group.extend(self)
6
+ end
7
+
8
+ def database_adapter
9
+ Tests::Database.instance.adapter_name
10
+ end
11
+
12
+ def database_supports_uuid_columns?
13
+ database_adapter == :postgresql
14
+ end
15
+ alias_method :database_supports_array_columns?,
16
+ :database_supports_uuid_columns?
17
+ end
18
+ end
@@ -32,10 +32,18 @@ module UnitTests
32
32
  end
33
33
 
34
34
  def define_active_model_class(class_name, options = {}, &block)
35
+ accessors = options.fetch(:accessors, [])
36
+
35
37
  define_class(class_name) do
36
38
  include ActiveModel::Validations
37
39
 
38
- options[:accessors].each do |column|
40
+ def initialize(attributes = {})
41
+ attributes.each do |name, value|
42
+ __send__("#{name}=", value)
43
+ end
44
+ end
45
+
46
+ accessors.each do |column|
39
47
  attr_accessor column.to_sym
40
48
  end
41
49
 
@@ -52,9 +60,17 @@ module UnitTests
52
60
  table_block = lambda do |table|
53
61
  columns.each do |column_name, specification|
54
62
  if specification.is_a?(Hash)
55
- table.column column_name, specification[:type], specification[:options]
63
+ column_type = specification[:type]
64
+ column_options = specification.fetch(:options, {})
56
65
  else
57
- table.column column_name, specification
66
+ column_type = specification
67
+ column_options = {}
68
+ end
69
+
70
+ begin
71
+ table.__send__(column_type, column_name, column_options)
72
+ rescue NoMethodError
73
+ raise NoMethodError, "#{Tests::Database.instance.adapter_class} does not support :#{column_type} columns"
58
74
  end
59
75
  end
60
76
  end
@@ -66,13 +82,21 @@ module UnitTests
66
82
  create_table(table_name, &table_block)
67
83
  end
68
84
 
69
- define_model_class(class_name).tap do |model|
85
+ model = define_model_class(class_name).tap do |m|
70
86
  if block
71
- model.class_eval(&block)
87
+ if block.arity == 0
88
+ m.class_eval(&block)
89
+ else
90
+ block.call(m)
91
+ end
72
92
  end
73
93
 
74
- model.table_name = table_name
94
+ m.table_name = table_name
75
95
  end
96
+
97
+ defined_models << model
98
+
99
+ model
76
100
  end
77
101
 
78
102
  private
@@ -85,6 +109,10 @@ module UnitTests
85
109
  elsif ActiveRecord::Base.connection_pool.respond_to?(:clear_cache!)
86
110
  ActiveRecord::Base.connection_pool.clear_cache!
87
111
  end
112
+
113
+ defined_models.each do |model|
114
+ model.reset_column_information
115
+ end
88
116
  end
89
117
 
90
118
  def drop_created_tables
@@ -98,5 +126,9 @@ module UnitTests
98
126
  def created_tables
99
127
  @_created_tables ||= []
100
128
  end
129
+
130
+ def defined_models
131
+ @_defined_models ||= []
132
+ end
101
133
  end
102
134
  end
@@ -21,8 +21,8 @@ module UnitTests
21
21
  rails_version >= 4.1
22
22
  end
23
23
 
24
- def active_record_supports_enum?
25
- defined?(::ActiveRecord::Enum)
24
+ def rails_gte_4_2?
25
+ rails_version >= 4.2
26
26
  end
27
27
  end
28
28
  end
@@ -20,15 +20,17 @@ module UnitTests
20
20
  end
21
21
 
22
22
  def failure_message
23
- msg = "Expectation should have failed with message including '#{expected}'"
23
+ lines = ['Expectation should have failed with message including:']
24
+ lines << Shoulda::Matchers::Util.indent(expected, 2)
24
25
 
25
26
  if @actual
26
- msg << ",\nactually failed with '#{@actual}'"
27
+ lines << 'Actually failed with:'
28
+ lines << Shoulda::Matchers::Util.indent(@actual, 2)
27
29
  else
28
- msg << ", but did not fail."
30
+ lines << 'However, the expectation did not fail.'
29
31
  end
30
32
 
31
- msg
33
+ lines.join("\n")
32
34
  end
33
35
 
34
36
  def failure_message_for_should
@@ -36,10 +38,9 @@ module UnitTests
36
38
  end
37
39
 
38
40
  def failure_message_when_negated
39
- msg = "Expectation should not have failed with message including '#{expected}'"
40
- msg << ", but did."
41
-
42
- msg
41
+ lines = ['Expectation should not have failed with message including:']
42
+ lines << Shoulda::Matchers::Util.indent(expected, 2)
43
+ lines.join("\n")
43
44
  end
44
45
 
45
46
  def failure_message_for_should_not