active_record_change_matchers 1.0.0 → 1.1.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.
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_change_matchers
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maxim Krizhanovski
8
8
  - Nathan Wallace
9
- autorequire:
10
9
  bindir: exe
11
10
  cert_chain: []
12
- date: 2024-07-03 00:00:00.000000000 Z
11
+ date: 2026-01-27 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: activerecord
@@ -17,14 +16,14 @@ dependencies:
17
16
  requirements:
18
17
  - - ">="
19
18
  - !ruby/object:Gem::Version
20
- version: 3.2.0
19
+ version: '7.0'
21
20
  type: :runtime
22
21
  prerelease: false
23
22
  version_requirements: !ruby/object:Gem::Requirement
24
23
  requirements:
25
24
  - - ">="
26
25
  - !ruby/object:Gem::Version
27
- version: 3.2.0
26
+ version: '7.0'
28
27
  - !ruby/object:Gem::Dependency
29
28
  name: rspec-expectations
30
29
  requirement: !ruby/object:Gem::Requirement
@@ -40,103 +39,103 @@ dependencies:
40
39
  - !ruby/object:Gem::Version
41
40
  version: 3.0.0
42
41
  - !ruby/object:Gem::Dependency
43
- name: rake
42
+ name: database_cleaner
44
43
  requirement: !ruby/object:Gem::Requirement
45
44
  requirements:
46
- - - "~>"
45
+ - - ">="
47
46
  - !ruby/object:Gem::Version
48
- version: '10.0'
47
+ version: '0'
49
48
  type: :development
50
49
  prerelease: false
51
50
  version_requirements: !ruby/object:Gem::Requirement
52
51
  requirements:
53
- - - "~>"
52
+ - - ">="
54
53
  - !ruby/object:Gem::Version
55
- version: '10.0'
54
+ version: '0'
56
55
  - !ruby/object:Gem::Dependency
57
- name: rspec
56
+ name: pry
58
57
  requirement: !ruby/object:Gem::Requirement
59
58
  requirements:
60
- - - "~>"
59
+ - - ">="
61
60
  - !ruby/object:Gem::Version
62
- version: '3.6'
61
+ version: '0'
63
62
  type: :development
64
63
  prerelease: false
65
64
  version_requirements: !ruby/object:Gem::Requirement
66
65
  requirements:
67
- - - "~>"
66
+ - - ">="
68
67
  - !ruby/object:Gem::Version
69
- version: '3.6'
68
+ version: '0'
70
69
  - !ruby/object:Gem::Dependency
71
- name: pry
70
+ name: rake
72
71
  requirement: !ruby/object:Gem::Requirement
73
72
  requirements:
74
- - - "~>"
73
+ - - ">="
75
74
  - !ruby/object:Gem::Version
76
- version: '0.10'
75
+ version: '0'
77
76
  type: :development
78
77
  prerelease: false
79
78
  version_requirements: !ruby/object:Gem::Requirement
80
79
  requirements:
81
- - - "~>"
80
+ - - ">="
82
81
  - !ruby/object:Gem::Version
83
- version: '0.10'
82
+ version: '0'
84
83
  - !ruby/object:Gem::Dependency
85
- name: sqlite3
84
+ name: rspec
86
85
  requirement: !ruby/object:Gem::Requirement
87
86
  requirements:
88
- - - "~>"
87
+ - - ">="
89
88
  - !ruby/object:Gem::Version
90
- version: '1.3'
89
+ version: '0'
91
90
  type: :development
92
91
  prerelease: false
93
92
  version_requirements: !ruby/object:Gem::Requirement
94
93
  requirements:
95
- - - "~>"
94
+ - - ">="
96
95
  - !ruby/object:Gem::Version
97
- version: '1.3'
96
+ version: '0'
98
97
  - !ruby/object:Gem::Dependency
99
- name: database_cleaner
98
+ name: sqlite3
100
99
  requirement: !ruby/object:Gem::Requirement
101
100
  requirements:
102
- - - "~>"
101
+ - - ">="
103
102
  - !ruby/object:Gem::Version
104
- version: '1.6'
103
+ version: '0'
105
104
  type: :development
106
105
  prerelease: false
107
106
  version_requirements: !ruby/object:Gem::Requirement
108
107
  requirements:
109
- - - "~>"
108
+ - - ">="
110
109
  - !ruby/object:Gem::Version
111
- version: '1.6'
110
+ version: '0'
112
111
  - !ruby/object:Gem::Dependency
113
112
  name: standalone_migrations
114
113
  requirement: !ruby/object:Gem::Requirement
115
114
  requirements:
116
- - - "~>"
115
+ - - ">="
117
116
  - !ruby/object:Gem::Version
118
- version: '5.2'
117
+ version: '0'
119
118
  type: :development
120
119
  prerelease: false
121
120
  version_requirements: !ruby/object:Gem::Requirement
122
121
  requirements:
123
- - - "~>"
122
+ - - ">="
124
123
  - !ruby/object:Gem::Version
125
- version: '5.2'
124
+ version: '0'
126
125
  - !ruby/object:Gem::Dependency
127
126
  name: timecop
128
127
  requirement: !ruby/object:Gem::Requirement
129
128
  requirements:
130
- - - "~>"
129
+ - - ">="
131
130
  - !ruby/object:Gem::Version
132
- version: '0.9'
131
+ version: '0'
133
132
  type: :development
134
133
  prerelease: false
135
134
  version_requirements: !ruby/object:Gem::Requirement
136
135
  requirements:
137
- - - "~>"
136
+ - - ">="
138
137
  - !ruby/object:Gem::Version
139
- version: '0.9'
138
+ version: '0'
140
139
  description: This gem adds custom block expectation matchers for RSpec, such as `expect
141
140
  { ... }.to create_a_new(User)`
142
141
  email:
@@ -145,6 +144,7 @@ executables: []
145
144
  extensions: []
146
145
  extra_rdoc_files: []
147
146
  files:
147
+ - ".github/workflows/main.yml"
148
148
  - ".gitignore"
149
149
  - ".rspec"
150
150
  - ".travis.yml"
@@ -153,19 +153,20 @@ files:
153
153
  - LICENSE.txt
154
154
  - README.md
155
155
  - Rakefile
156
- - active_record_block_matchers.gemspec
157
156
  - active_record_change_matchers.gemspec
158
157
  - bin/console
159
158
  - bin/setup
160
159
  - db/config.yml
161
160
  - db/migrate/20150225014908_create_people.rb
162
161
  - db/migrate/20151017231107_create_dogs.rb
162
+ - db/migrate/20160101000000_create_pets.rb
163
163
  - db/schema.rb
164
- - lib/active_record_block_matchers.rb
165
164
  - lib/active_record_change_matchers.rb
166
165
  - lib/active_record_change_matchers/config.rb
167
- - lib/active_record_change_matchers/create_a_new_matcher.rb
168
- - lib/active_record_change_matchers/create_records_matcher.rb
166
+ - lib/active_record_change_matchers/hash_format.rb
167
+ - lib/active_record_change_matchers/matchers/create_a_new_matcher.rb
168
+ - lib/active_record_change_matchers/matchers/create_associated_matcher.rb
169
+ - lib/active_record_change_matchers/matchers/create_records_matcher.rb
169
170
  - lib/active_record_change_matchers/strategies.rb
170
171
  - lib/active_record_change_matchers/strategies/id_strategy.rb
171
172
  - lib/active_record_change_matchers/strategies/timestamp_strategy.rb
@@ -174,7 +175,6 @@ homepage: https://github.com/Darhazer/active_record_change_matchers
174
175
  licenses:
175
176
  - MIT
176
177
  metadata: {}
177
- post_install_message:
178
178
  rdoc_options: []
179
179
  require_paths:
180
180
  - lib
@@ -182,15 +182,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
182
182
  requirements:
183
183
  - - ">="
184
184
  - !ruby/object:Gem::Version
185
- version: 1.9.3
185
+ version: 3.3.0
186
186
  required_rubygems_version: !ruby/object:Gem::Requirement
187
187
  requirements:
188
188
  - - ">="
189
189
  - !ruby/object:Gem::Version
190
190
  version: '0'
191
191
  requirements: []
192
- rubygems_version: 3.0.3.1
193
- signing_key:
192
+ rubygems_version: 3.6.2
194
193
  specification_version: 4
195
194
  summary: Additional RSpec custom matchers for ActiveRecord
196
195
  test_files: []
@@ -1,33 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path("../lib", __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "active_record_change_matchers/version"
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "active_record_change_matchers"
8
- spec.version = ActiveRecordChangeMatchers::VERSION
9
- spec.authors = ["Maxim Krizhanovski", "Nathan Wallace"]
10
- spec.email = ["maxim.krizhanovski@hey.com"]
11
-
12
- spec.summary = %q{Additional RSpec custom matchers for ActiveRecord}
13
- spec.description = %q{This gem adds custom block expectation matchers for RSpec, such as `expect { ... }.to create_a_new(User)`}
14
- spec.homepage = "https://github.com/Darhazer/active_record_change_matchers"
15
- spec.license = "MIT"
16
-
17
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
- spec.bindir = "exe"
19
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
- spec.require_paths = ["lib"]
21
- spec.required_ruby_version = ">= 1.9.3"
22
-
23
- spec.add_dependency "activerecord", ">= 3.2.0"
24
- spec.add_dependency "rspec-expectations", ">= 3.0.0"
25
-
26
- spec.add_development_dependency "rake", "~> 10.0"
27
- spec.add_development_dependency "rspec", "~> 3.6"
28
- spec.add_development_dependency "pry", "~> 0.10"
29
- spec.add_development_dependency "sqlite3", "~> 1.3"
30
- spec.add_development_dependency "database_cleaner", "~> 1.6"
31
- spec.add_development_dependency "standalone_migrations", "~> 5.2"
32
- spec.add_development_dependency "timecop", "~> 0.9"
33
- end
@@ -1,7 +0,0 @@
1
- require "rspec/expectations"
2
- require "active_record"
3
-
4
- Dir[File.dirname(__FILE__) + "/active_record_change_matchers/**/*.rb"].each {|file| require file }
5
-
6
- module ActiveRecordChangeMatchers
7
- end
@@ -1,94 +0,0 @@
1
- RSpec::Matchers.define :create_a_new do |klass|
2
- supports_block_expectations
3
-
4
- description do
5
- "create a #{klass}, optionally verifying attributes"
6
- end
7
-
8
- chain(:with_attributes) do |attributes|
9
- @attributes = attributes
10
- end
11
-
12
- chain(:which) do |&block|
13
- @which_block = block
14
- end
15
-
16
- chain(:which_is_expected_to) do |matcher|
17
- @which_matcher = matcher
18
- end
19
-
20
- match do |options={}, block|
21
- fetching_strategy =
22
- ActiveRecordChangeMatchers::Strategies.for_key(options[:strategy]).new(block)
23
-
24
- @created_records = fetching_strategy.new_records([klass])[klass]
25
-
26
- return false unless @created_records.count == 1 # ? this shouldn't be necessary for all strategies...
27
-
28
- record = @created_records.first
29
-
30
- @attribute_mismatches = []
31
-
32
- @attributes && @attributes.each do |field, value|
33
- unless values_match?(value, record.public_send(field))
34
- @attribute_mismatches << [field, value, record.public_send(field)]
35
- end
36
- end
37
-
38
- if @attribute_mismatches.none? && @which_block
39
- begin
40
- @which_block.call(record)
41
- rescue RSpec::Expectations::ExpectationNotMetError => e
42
- @which_failure = e
43
- end
44
- end
45
-
46
- if @attribute_mismatches.none? && @which_matcher
47
- unless @which_matcher.matches?(record)
48
- @matcher_failure = @which_matcher.failure_message
49
- end
50
- end
51
-
52
- @attribute_mismatches.empty? && @which_failure.nil? && @matcher_failure.nil?
53
- end
54
-
55
- failure_message do
56
- if @created_records.count != 1
57
- "the block should have created 1 #{klass}, but created #{@created_records.count}"
58
- elsif @attribute_mismatches.any?
59
- @attribute_mismatches.map do |field, expected, actual|
60
- expected_description = is_composable_matcher?(expected) ? expected.description : expected.inspect
61
- "Expected #{field.inspect} to be #{expected_description}, but was #{actual.inspect}"
62
- end.join("\n")
63
- elsif @which_failure
64
- @which_failure.message
65
- else
66
- @matcher_failure
67
- end
68
- end
69
-
70
- failure_message_when_negated do
71
- if @created_records.count == 1 && @attributes && @attribute_mismatches.none?
72
- "the block should not have created a #{klass} with attributes #{format_attributes_hash(@attributes).inspect}, but did"
73
- elsif @created_records.count == 1 && @which_block && !@which_failure
74
- "the newly created #{klass} should have failed an expectation in the given block, but didn't"
75
- elsif @created_records.count == 1
76
- "the block should not have created a #{klass}, but created #{@created_records.count}: #{@created_records.inspect}"
77
- else
78
- "the block created a #{klass} that matched all given criteria"
79
- end
80
- end
81
-
82
- def is_composable_matcher?(value)
83
- value.respond_to?(:failure_message_when_negated)
84
- end
85
-
86
- def format_attributes_hash(attributes)
87
- attributes.each_with_object({}) do |(field,value), memo|
88
- memo[field] = is_composable_matcher?(value) ? value.description : value
89
- end
90
- end
91
- end
92
-
93
- RSpec::Matchers.alias_matcher :create_a, :create_a_new
94
- RSpec::Matchers.alias_matcher :create_an, :create_a_new
@@ -1,112 +0,0 @@
1
- RSpec::Matchers.define :create_records do |record_counts|
2
- include ActiveSupport::Inflector
3
-
4
- supports_block_expectations
5
-
6
- description do
7
- counts_strs = record_counts.map { |klass, count| count_str(klass, count) }
8
- "create #{counts_strs.join(", ")}"
9
- end
10
-
11
- chain(:with_attributes) do |attributes|
12
- if mismatch=attributes.find {|klass, hashes| hashes.size != record_counts[klass]}
13
- mismatched_class, hashes = mismatch
14
- raise ArgumentError, "Specified the block should create #{record_counts[mismatched_class]} #{mismatched_class}, but provided #{hashes.size} #{mismatched_class} attribute specifications"
15
- end
16
- @expected_attributes = attributes
17
- end
18
-
19
- chain(:which) do |&block|
20
- @which_block = block
21
- end
22
-
23
- match do |options={}, block|
24
- fetching_strategy =
25
- ActiveRecordChangeMatchers::Strategies.for_key(options[:strategy]).new(block)
26
-
27
- @new_records = fetching_strategy.new_records(record_counts.keys)
28
-
29
- @incorrect_counts =
30
- @new_records.each_with_object({}) do |(klass, new_records), incorrect|
31
- actual_count = new_records.count
32
- expected_count = record_counts[klass]
33
- if actual_count != expected_count
34
- incorrect[klass] = { expected: expected_count, actual: actual_count }
35
- end
36
- end
37
-
38
- return false if @incorrect_counts.any?
39
-
40
- if @expected_attributes
41
- @matched_records = Hash.new {|hash, key| hash[key] = []}
42
- @all_attributes = Hash.new {|hash, key| hash[key] = []}
43
- @incorrect_attributes =
44
- @expected_attributes.each_with_object(Hash.new {|hash, key| hash[key] = []}) do |(klass, expected_attributes), incorrect|
45
- @all_attributes[klass] = expected_attributes.map(&:keys).flatten.uniq
46
- expected_attributes.each do |expected_attrs|
47
- matched_record = (@new_records.fetch(klass) - @matched_records[klass]).find do |record|
48
- expected_attrs.all? {|k,v| values_match?(v, record.public_send(k))}
49
- end
50
- if matched_record
51
- @matched_records[klass] << matched_record
52
- else
53
- incorrect[klass] << expected_attrs
54
- end
55
- end
56
- end
57
- @unmatched_records = @matched_records.map {|klass, records| [klass, @new_records[klass] - records]}.to_h.reject {|k,v| v.empty?}
58
- return false if @incorrect_attributes.any?
59
- end
60
-
61
-
62
- begin
63
- @which_block && @which_block.call(@new_records)
64
- rescue RSpec::Expectations::ExpectationNotMetError => e
65
- @which_failure = e
66
- end
67
-
68
- @which_failure.nil?
69
- end
70
-
71
- failure_message do
72
- if @incorrect_counts.present?
73
- @incorrect_counts.map do |klass, counts|
74
- "The block should have created #{count_str(klass, counts[:expected])}, but created #{counts[:actual]}."
75
- end.join(" ")
76
- elsif @incorrect_attributes.present?
77
- "The block should have created:\n" +
78
- @expected_attributes.map do |klass, attrs|
79
- " #{attrs.count} #{klass} with these attributes:\n" +
80
- attrs.map{|a| " #{a.inspect}"}.join("\n")
81
- end.join("\n") +
82
- "\nDiff:" +
83
- @incorrect_attributes.map do |klass, attrs|
84
- "\n Missing #{attrs.count} #{klass} with these attributes:\n" +
85
- attrs.map{|a| " #{a.inspect}"}.join("\n")
86
- end.join("\n") +
87
- @unmatched_records.map do |klass, records|
88
- "\n Extra #{records.count} #{klass} with these attributes:\n" +
89
- records.map do |r|
90
- attrs = @all_attributes[klass].each_with_object({}) {|attr, attrs| attrs[attr] = r.public_send(attr)}
91
- " #{attrs.inspect}"
92
- end.join("\n")
93
- end.join("\n")
94
- elsif @which_failure
95
- @which_failure
96
- else
97
- "Unknown error"
98
- end
99
- end
100
-
101
- failure_message_when_negated do
102
- record_counts.map do |klass, expected_count|
103
- "The block should not have created #{count_str(klass, expected_count)}, but created #{expected_count}."
104
- end.join(" ")
105
- end
106
-
107
- def count_str(klass, count)
108
- "#{count} #{klass.name.pluralize(count)}"
109
- end
110
- end
111
-
112
- RSpec::Matchers.alias_matcher :create, :create_records