consistency_fail 0.3.2 → 0.3.3
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.
- checksums.yaml +15 -0
- data/Gemfile +1 -1
- data/README.md +4 -0
- data/consistency_fail.gemspec +1 -1
- data/lib/consistency_fail/enforcer.rb +4 -3
- data/lib/consistency_fail/introspectors/has_one.rb +1 -1
- data/lib/consistency_fail/version.rb +1 -1
- data/spec/index_spec.rb +10 -7
- data/spec/introspectors/has_one_spec.rb +27 -19
- data/spec/introspectors/polymorphic_spec.rb +16 -16
- data/spec/introspectors/table_data_spec.rb +9 -9
- data/spec/introspectors/validates_uniqueness_of_spec.rb +25 -25
- data/spec/models_spec.rb +11 -11
- data/spec/reporter_spec.rb +10 -10
- metadata +10 -15
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NTdkY2IwZWQ2ZjI5Mzk1ZDc3NTMxNzFhM2IyNDllZWVhMmUwZWQ4OQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YzQzNDRjODdhN2RhN2UzZmVhMjIwYzkxMDQ5NTY3NjEyMDM2NWM5Mw==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
OGVlNzc3MTFlMDEyNzk5YmViM2UwOTI4YzAzNGMwY2U0Y2M4MGQ0MjRmMTM4
|
10
|
+
ZDgwZGM1YmE1MjhlMzA1MzVlZDU2YzJlNGJmNmQ2ZjMxNWQ0YzE4OTY5YjEx
|
11
|
+
Y2ZiNWFjMThkODRjMGNiMzY4ZjYwNDFjMzU0Yzk3MDBiNTViZWM=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MzJmNWE4YTU4MWRjMTExMDYwN2JkNGQyYzBhMWNiOWRjNGY3ZmJlYjg5MzQ0
|
14
|
+
NzBlNDY3N2I2OWJiMWU1OWEzNDFkYzliZDkzYzcwZDA1ZmY4ZWUzOTBhODky
|
15
|
+
NzI4NTA5OWM0YjY3ZDYyNmNhMmVjMjM4N2U4MWRmY2VjNzlmMzc=
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -68,6 +68,10 @@ delay the initializer until later, so that model files can be loaded only once
|
|
68
68
|
gem dependencies have been satisfied. One possible way is to move the code above
|
69
69
|
to the end of `environment.rb` or to the more specific `config/environment/*` files.
|
70
70
|
|
71
|
+
## Using with Guard
|
72
|
+
|
73
|
+
There is a guard integration plugin available. See [guard-consistency_fail](https://github.com/ptyagi16/guard-consistency_fail).
|
74
|
+
|
71
75
|
## License
|
72
76
|
|
73
77
|
Released under the MIT License. See the LICENSE file for further details.
|
data/consistency_fail.gemspec
CHANGED
@@ -22,7 +22,7 @@ EOF
|
|
22
22
|
s.license = "MIT"
|
23
23
|
|
24
24
|
s.add_development_dependency "activerecord", "~>3.0"
|
25
|
-
s.add_development_dependency "rspec"
|
25
|
+
s.add_development_dependency "rspec", "~>3.1"
|
26
26
|
|
27
27
|
s.files = `git ls-files`.split("\n")
|
28
28
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
@@ -15,7 +15,8 @@ module ConsistencyFail
|
|
15
15
|
models.preload_all
|
16
16
|
|
17
17
|
introspectors = [ConsistencyFail::Introspectors::ValidatesUniquenessOf.new,
|
18
|
-
ConsistencyFail::Introspectors::HasOne.new
|
18
|
+
ConsistencyFail::Introspectors::HasOne.new,
|
19
|
+
ConsistencyFail::Introspectors::Polymorphic.new]
|
19
20
|
|
20
21
|
problem_models_exist = models.all.detect do |model|
|
21
22
|
introspectors.any? {|i| !i.missing_indexes(model).empty?}
|
@@ -42,11 +43,11 @@ module ConsistencyFail
|
|
42
43
|
alias :count :find
|
43
44
|
end
|
44
45
|
|
45
|
-
def save
|
46
|
+
def save(*arguments)
|
46
47
|
self.class.panic
|
47
48
|
end
|
48
49
|
|
49
|
-
def save!
|
50
|
+
def save!(*arguments)
|
50
51
|
self.class.panic
|
51
52
|
end
|
52
53
|
end
|
@@ -5,7 +5,7 @@ module ConsistencyFail
|
|
5
5
|
class HasOne
|
6
6
|
def instances(model)
|
7
7
|
model.reflect_on_all_associations.select do |a|
|
8
|
-
a.macro == :has_one && a.options[:as].to_s.length == 0
|
8
|
+
a.macro == :has_one && a.options[:as].to_s.length == 0 && a.options[:through].to_s.length == 0
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
data/spec/index_spec.rb
CHANGED
@@ -7,31 +7,34 @@ describe ConsistencyFail::Index do
|
|
7
7
|
it "holds onto model, table name, and columns" do
|
8
8
|
model = double("model")
|
9
9
|
index = ConsistencyFail::Index.new(model, "addresses", ["city", "state"])
|
10
|
-
index.model.
|
11
|
-
index.table_name.
|
12
|
-
index.columns.
|
10
|
+
expect(index.model).to eq(model)
|
11
|
+
expect(index.table_name).to eq("addresses")
|
12
|
+
expect(index.columns).to eq(["city", "state"])
|
13
13
|
end
|
14
14
|
|
15
15
|
it "leaves columns in the initial order (since we only care about presence, not performance)" do
|
16
16
|
index = ConsistencyFail::Index.new(double('model'), "addresses", ["state", "city"])
|
17
|
-
index.columns.
|
17
|
+
expect(index.columns).to eq(["state", "city"])
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
21
|
describe "equality test" do
|
22
22
|
it "passes when everything matches" do
|
23
|
-
ConsistencyFail::Index.new(double('model'), "addresses", ["city", "state"]).
|
23
|
+
expect(ConsistencyFail::Index.new(double('model'), "addresses", ["city", "state"])).to eq(
|
24
24
|
ConsistencyFail::Index.new(double('model'),"addresses", ["city", "state"])
|
25
|
+
)
|
25
26
|
end
|
26
27
|
|
27
28
|
it "fails when tables are different" do
|
28
|
-
ConsistencyFail::Index.new(double('model'),"locations", ["city", "state"]).
|
29
|
+
expect(ConsistencyFail::Index.new(double('model'),"locations", ["city", "state"])).not_to eq(
|
29
30
|
ConsistencyFail::Index.new(double('model'),"addresses", ["city", "state"])
|
31
|
+
)
|
30
32
|
end
|
31
33
|
|
32
34
|
it "fails when columns are different" do
|
33
|
-
ConsistencyFail::Index.new(double('model'),"addresses", ["city", "state"]).
|
35
|
+
expect(ConsistencyFail::Index.new(double('model'),"addresses", ["city", "state"])).not_to eq(
|
34
36
|
ConsistencyFail::Index.new(double('model'),"addresses", ["state", "zip"])
|
37
|
+
)
|
35
38
|
end
|
36
39
|
end
|
37
40
|
end
|
@@ -10,33 +10,41 @@ describe ConsistencyFail::Introspectors::HasOne do
|
|
10
10
|
describe "instances of has_one" do
|
11
11
|
it "finds none" do
|
12
12
|
model = fake_ar_model("User")
|
13
|
-
model.
|
13
|
+
allow(model).to receive(:reflect_on_all_associations).and_return([])
|
14
14
|
|
15
|
-
subject.instances(model).
|
15
|
+
expect(subject.instances(model)).to eq([])
|
16
16
|
end
|
17
17
|
|
18
18
|
it "finds one" do
|
19
19
|
model = fake_ar_model("User")
|
20
20
|
association = double("association", :macro => :has_one, :options => {})
|
21
|
-
model.
|
21
|
+
allow(model).to receive(:reflect_on_all_associations).and_return([association])
|
22
22
|
|
23
|
-
subject.instances(model).
|
23
|
+
expect(subject.instances(model)).to eq([association])
|
24
24
|
end
|
25
25
|
|
26
26
|
it "finds other associations, but not has_one" do
|
27
27
|
model = fake_ar_model("User")
|
28
28
|
validation = double("validation", :macro => :has_many)
|
29
|
-
model.
|
29
|
+
allow(model).to receive(:reflect_on_all_associations).and_return([validation])
|
30
30
|
|
31
|
-
subject.instances(model).
|
31
|
+
expect(subject.instances(model)).to eq([])
|
32
32
|
end
|
33
33
|
|
34
34
|
it "finds one, but it's a polymorphic association" do
|
35
35
|
model = fake_ar_model("User")
|
36
36
|
association = double("association", :macro => :has_one, :options => {:as => "addressable"})
|
37
|
-
model.
|
37
|
+
allow(model).to receive(:reflect_on_all_associations).and_return([association])
|
38
38
|
|
39
|
-
subject.instances(model).
|
39
|
+
expect(subject.instances(model)).to eq([])
|
40
|
+
end
|
41
|
+
|
42
|
+
it "finds one, but it's a :through association" do
|
43
|
+
model = fake_ar_model("User")
|
44
|
+
association = double("association", :macro => :has_one, :options => {:through => :amodel})
|
45
|
+
allow(model).to receive(:reflect_on_all_associations).and_return([association])
|
46
|
+
|
47
|
+
expect(subject.instances(model)).to eq([])
|
40
48
|
end
|
41
49
|
end
|
42
50
|
|
@@ -49,37 +57,37 @@ describe ConsistencyFail::Introspectors::HasOne do
|
|
49
57
|
:reflect_on_all_associations => [@association])
|
50
58
|
@address_class = double("Address Class")
|
51
59
|
@address_string = "Address"
|
52
|
-
@address_string.
|
60
|
+
allow(@address_string).to receive(:constantize).and_return(@address_class)
|
53
61
|
end
|
54
62
|
|
55
63
|
it "finds one" do
|
56
|
-
@association.
|
57
|
-
@address_class.
|
64
|
+
allow(@association).to receive_messages(:table_name => :addresses, :class_name => @address_string, :foreign_key => "user_id")
|
65
|
+
allow(@address_class).to receive_message_chain(:connection, :indexes).with("addresses").and_return([])
|
58
66
|
|
59
67
|
indexes = subject.missing_indexes(@model)
|
60
|
-
indexes.
|
68
|
+
expect(indexes).to eq([ConsistencyFail::Index.new(fake_ar_model("Address"), "addresses", ["user_id"])])
|
61
69
|
end
|
62
70
|
|
63
71
|
it "finds one in Rails 3.0.x (where foreign_key is not defined)" do
|
64
|
-
@association.
|
65
|
-
@address_class.
|
72
|
+
allow(@association).to receive_messages(:table_name => :addresses, :class_name => @address_string, :primary_key_name => "user_id")
|
73
|
+
allow(@address_class).to receive_message_chain(:connection, :indexes).with("addresses").and_return([])
|
66
74
|
|
67
75
|
indexes = subject.missing_indexes(@model)
|
68
|
-
indexes.
|
76
|
+
expect(indexes).to eq([ConsistencyFail::Index.new(fake_ar_model("Address"), "addresses", ["user_id"])])
|
69
77
|
end
|
70
78
|
|
71
79
|
it "finds none when they're already in place" do
|
72
|
-
@association.
|
80
|
+
allow(@association).to receive_messages(:table_name => :addresses, :class_name => @address_string, :foreign_key => "user_id")
|
73
81
|
index = ConsistencyFail::Index.new(double('model'), "addresses", ["user_id"])
|
74
82
|
|
75
83
|
fake_connection = double("connection")
|
76
|
-
@address_class.
|
84
|
+
allow(@address_class).to receive_message_chain(:connection).and_return(fake_connection)
|
77
85
|
|
78
|
-
ConsistencyFail::Introspectors::TableData.
|
86
|
+
allow(ConsistencyFail::Introspectors::TableData).to receive_message_chain(:new, :unique_indexes_by_table).
|
79
87
|
with(@address_class, fake_connection, "addresses").
|
80
88
|
and_return([index])
|
81
89
|
|
82
|
-
subject.missing_indexes(@model).
|
90
|
+
expect(subject.missing_indexes(@model)).to eq([])
|
83
91
|
end
|
84
92
|
|
85
93
|
end
|
@@ -10,33 +10,33 @@ describe ConsistencyFail::Introspectors::Polymorphic do
|
|
10
10
|
describe "instances of polymorphic" do
|
11
11
|
it "finds none" do
|
12
12
|
model = fake_ar_model("User")
|
13
|
-
model.
|
13
|
+
allow(model).to receive(:reflect_on_all_associations).and_return([])
|
14
14
|
|
15
|
-
subject.instances(model).
|
15
|
+
expect(subject.instances(model)).to eq([])
|
16
16
|
end
|
17
17
|
|
18
18
|
it "finds one" do
|
19
19
|
model = fake_ar_model("User")
|
20
20
|
association = double("association", :macro => :has_one, :options => {:as => "addressable"})
|
21
|
-
model.
|
21
|
+
allow(model).to receive(:reflect_on_all_associations).and_return([association])
|
22
22
|
|
23
|
-
subject.instances(model).
|
23
|
+
expect(subject.instances(model)).to eq([association])
|
24
24
|
end
|
25
25
|
|
26
26
|
it "finds other has_one associations, but not polymorphic" do
|
27
27
|
model = fake_ar_model("User")
|
28
28
|
validation = double("association", :macro => :has_one, :options => {})
|
29
|
-
model.
|
29
|
+
allow(model).to receive(:reflect_on_all_associations).and_return([validation])
|
30
30
|
|
31
|
-
subject.instances(model).
|
31
|
+
expect(subject.instances(model)).to eq([])
|
32
32
|
end
|
33
33
|
|
34
34
|
it "finds other non has_one associations" do
|
35
35
|
model = fake_ar_model("User")
|
36
36
|
validation = double("association", :macro => :has_many)
|
37
|
-
model.
|
37
|
+
allow(model).to receive(:reflect_on_all_associations).and_return([validation])
|
38
38
|
|
39
|
-
subject.instances(model).
|
39
|
+
expect(subject.instances(model)).to eq([])
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -49,29 +49,29 @@ describe ConsistencyFail::Introspectors::Polymorphic do
|
|
49
49
|
:reflect_on_all_associations => [@association])
|
50
50
|
@address_class = double("Address Class")
|
51
51
|
@address_string = "Address"
|
52
|
-
@address_string.
|
52
|
+
allow(@address_string).to receive(:constantize).and_return(@address_class)
|
53
53
|
end
|
54
54
|
|
55
55
|
it "finds one" do
|
56
|
-
@association.
|
57
|
-
@address_class.
|
56
|
+
allow(@association).to receive_messages(:table_name => :addresses, :class_name => @address_string)
|
57
|
+
allow(@address_class).to receive_message_chain(:connection, :indexes).with("addresses").and_return([])
|
58
58
|
|
59
59
|
indexes = subject.missing_indexes(@model)
|
60
|
-
indexes.
|
60
|
+
expect(indexes).to eq([ConsistencyFail::Index.new(fake_ar_model("Address"), "addresses", ["addressable_type", "addressable_id"])])
|
61
61
|
end
|
62
62
|
|
63
63
|
it "finds none when they're already in place" do
|
64
|
-
@association.
|
64
|
+
allow(@association).to receive_messages(:table_name => :addresses, :class_name => @address_string)
|
65
65
|
index = ConsistencyFail::Index.new(double('model'), "addresses", ["addressable_type", "addressable_id"])
|
66
66
|
|
67
67
|
fake_connection = double("connection")
|
68
|
-
@address_class.
|
68
|
+
allow(@address_class).to receive_message_chain(:connection).and_return(fake_connection)
|
69
69
|
|
70
|
-
ConsistencyFail::Introspectors::TableData.
|
70
|
+
allow(ConsistencyFail::Introspectors::TableData).to receive_message_chain(:new, :unique_indexes_by_table).
|
71
71
|
with(@address_class, fake_connection, "addresses").
|
72
72
|
and_return([index])
|
73
73
|
|
74
|
-
subject.missing_indexes(@model).
|
74
|
+
expect(subject.missing_indexes(@model)).to eq([])
|
75
75
|
end
|
76
76
|
end
|
77
77
|
end
|
@@ -6,45 +6,45 @@ describe ConsistencyFail::Introspectors::TableData do
|
|
6
6
|
it "finds none when the table does not exist" do
|
7
7
|
model = fake_ar_model("User", :table_exists? => false)
|
8
8
|
|
9
|
-
subject.unique_indexes(model).
|
9
|
+
expect(subject.unique_indexes(model)).to eq([])
|
10
10
|
end
|
11
11
|
|
12
12
|
it "gets one" do
|
13
13
|
model = fake_ar_model("User", :table_exists? => true,
|
14
14
|
:table_name => "users")
|
15
15
|
|
16
|
-
model.
|
16
|
+
allow(model).to receive_message_chain(:connection, :indexes).
|
17
17
|
with("users").
|
18
18
|
and_return([fake_index_on(["a"], :unique => true)])
|
19
19
|
|
20
20
|
indexes = subject.unique_indexes(model)
|
21
|
-
indexes.
|
21
|
+
expect(indexes).to eq([ConsistencyFail::Index.new(double('model'), "users", ["a"])])
|
22
22
|
end
|
23
23
|
|
24
24
|
it "doesn't get non-unique indexes" do
|
25
25
|
model = fake_ar_model("User", :table_exists? => true,
|
26
26
|
:table_name => "users")
|
27
27
|
|
28
|
-
model.
|
28
|
+
allow(model).to receive_message_chain(:connection, :indexes).
|
29
29
|
with("users").
|
30
30
|
and_return([fake_index_on(["a"], :unique => false)])
|
31
31
|
|
32
|
-
subject.unique_indexes(model).
|
32
|
+
expect(subject.unique_indexes(model)).to eq([])
|
33
33
|
end
|
34
34
|
|
35
35
|
it "gets multiple unique indexes" do
|
36
36
|
model = fake_ar_model("User", :table_exists? => true,
|
37
37
|
:table_name => "users")
|
38
38
|
|
39
|
-
model.
|
39
|
+
allow(model).to receive_message_chain(:connection, :indexes).
|
40
40
|
with("users").
|
41
41
|
and_return([fake_index_on(["a"], :unique => true),
|
42
42
|
fake_index_on(["b", "c"], :unique => true)])
|
43
43
|
|
44
44
|
indexes = subject.unique_indexes(model)
|
45
|
-
indexes.size.
|
46
|
-
indexes.
|
47
|
-
ConsistencyFail::Index.new(double('model'), "users", ["b", "c"])]
|
45
|
+
expect(indexes.size).to eq(2)
|
46
|
+
expect(indexes).to eq([ConsistencyFail::Index.new(double('model'), "users", ["a"]),
|
47
|
+
ConsistencyFail::Index.new(double('model'), "users", ["b", "c"])])
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -9,25 +9,25 @@ describe ConsistencyFail::Introspectors::ValidatesUniquenessOf do
|
|
9
9
|
describe "instances of validates_uniqueness_of" do
|
10
10
|
it "finds none" do
|
11
11
|
model = fake_ar_model("User")
|
12
|
-
model.
|
12
|
+
allow(model).to receive(:validators).and_return([])
|
13
13
|
|
14
|
-
subject.instances(model).
|
14
|
+
expect(subject.instances(model)).to eq([])
|
15
15
|
end
|
16
16
|
|
17
17
|
it "finds one" do
|
18
18
|
model = fake_ar_model("User")
|
19
19
|
validation = double("validation", :class => ActiveRecord::Validations::UniquenessValidator)
|
20
|
-
model.
|
20
|
+
allow(model).to receive(:validators).and_return([validation])
|
21
21
|
|
22
|
-
subject.instances(model).
|
22
|
+
expect(subject.instances(model)).to eq([validation])
|
23
23
|
end
|
24
24
|
|
25
25
|
it "finds other validations, but not uniqueness" do
|
26
26
|
model = fake_ar_model("User")
|
27
27
|
validation = double("validation", :class => ActiveModel::Validations::FormatValidator)
|
28
|
-
model.
|
28
|
+
allow(model).to receive(:validators).and_return([validation])
|
29
29
|
|
30
|
-
subject.instances(model).
|
30
|
+
expect(subject.instances(model)).to eq([])
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -40,54 +40,54 @@ describe ConsistencyFail::Introspectors::ValidatesUniquenessOf do
|
|
40
40
|
end
|
41
41
|
|
42
42
|
it "finds one" do
|
43
|
-
@validation.
|
44
|
-
@model.
|
43
|
+
allow(@validation).to receive_messages(:attributes => [:email], :options => {})
|
44
|
+
allow(@model).to receive_message_chain(:connection, :indexes).with("users").and_return([])
|
45
45
|
|
46
46
|
indexes = subject.missing_indexes(@model)
|
47
|
-
indexes.
|
47
|
+
expect(indexes).to eq([ConsistencyFail::Index.new(double('model'), "users", ["email"])])
|
48
48
|
end
|
49
49
|
|
50
50
|
it "finds one where the validation has scoped columns" do
|
51
|
-
@validation.
|
52
|
-
@model.
|
51
|
+
allow(@validation).to receive_messages(:attributes => [:city], :options => {:scope => [:email, :state]})
|
52
|
+
allow(@model).to receive_message_chain(:connection, :indexes).with("users").and_return([])
|
53
53
|
|
54
54
|
indexes = subject.missing_indexes(@model)
|
55
|
-
indexes.
|
55
|
+
expect(indexes).to eq([ConsistencyFail::Index.new(double('model'), "users", ["city", "email", "state"])])
|
56
56
|
end
|
57
57
|
|
58
58
|
it "leaves the columns in the given order" do
|
59
|
-
@validation.
|
60
|
-
@model.
|
59
|
+
allow(@validation).to receive_messages(:attributes => [:email], :options => {:scope => [:city, :state]})
|
60
|
+
allow(@model).to receive_message_chain(:connection, :indexes).with("users").and_return([])
|
61
61
|
|
62
62
|
indexes = subject.missing_indexes(@model)
|
63
|
-
indexes.
|
63
|
+
expect(indexes).to eq([ConsistencyFail::Index.new(double('model'), "users", ["email", "city", "state"])])
|
64
64
|
end
|
65
65
|
|
66
66
|
it "finds two where there are multiple attributes" do
|
67
|
-
@validation.
|
68
|
-
@model.
|
67
|
+
allow(@validation).to receive_messages(:attributes => [:email, :name], :options => {:scope => [:city, :state]})
|
68
|
+
allow(@model).to receive_message_chain(:connection, :indexes).with("users").and_return([])
|
69
69
|
|
70
70
|
indexes = subject.missing_indexes(@model)
|
71
|
-
indexes.
|
72
|
-
ConsistencyFail::Index.new(double('model'), "users", ["name", "city", "state"])]
|
71
|
+
expect(indexes).to eq([ConsistencyFail::Index.new(double('model'), "users", ["email", "city", "state"]),
|
72
|
+
ConsistencyFail::Index.new(double('model'), "users", ["name", "city", "state"])])
|
73
73
|
end
|
74
74
|
|
75
75
|
it "finds none when they're already in place" do
|
76
|
-
@validation.
|
76
|
+
allow(@validation).to receive_messages(:attributes => [:email], :options => {})
|
77
77
|
index = fake_index_on(["email"], :unique => true)
|
78
|
-
@model.
|
78
|
+
allow(@model).to receive_message_chain(:connection, :indexes).with("users").
|
79
79
|
and_return([index])
|
80
80
|
|
81
|
-
subject.missing_indexes(@model).
|
81
|
+
expect(subject.missing_indexes(@model)).to eq([])
|
82
82
|
end
|
83
83
|
|
84
84
|
it "finds none when indexes are there but in a different order" do
|
85
|
-
@validation.
|
85
|
+
allow(@validation).to receive_messages(:attributes => [:email], :options => {:scope => [:city, :state]})
|
86
86
|
index = fake_index_on(["state", "email", "city"], :unique => true)
|
87
|
-
@model.
|
87
|
+
allow(@model).to receive_message_chain(:connection, :indexes).with("users").
|
88
88
|
and_return([index])
|
89
89
|
|
90
|
-
subject.missing_indexes(@model).
|
90
|
+
expect(subject.missing_indexes(@model)).to eq([])
|
91
91
|
end
|
92
92
|
end
|
93
93
|
end
|
data/spec/models_spec.rb
CHANGED
@@ -7,32 +7,32 @@ describe ConsistencyFail::Models do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it "gets the load path" do
|
10
|
-
models([:a, :b, :c]).load_path.
|
10
|
+
expect(models([:a, :b, :c]).load_path).to eq([:a, :b, :c])
|
11
11
|
end
|
12
12
|
|
13
13
|
it "gets the directories matching /models/" do
|
14
14
|
models = models(["foo/bar/baz", "app/models", "some/other/models"])
|
15
|
-
models.dirs.
|
15
|
+
expect(models.dirs).to eq(["app/models", "some/other/models"])
|
16
16
|
end
|
17
17
|
|
18
18
|
it "accepts and matches path names as well as strings" do
|
19
19
|
models = models([Pathname.new("app/models")])
|
20
|
-
|
21
|
-
models.dirs.
|
20
|
+
expect { models.dirs }.not_to raise_error
|
21
|
+
expect(models.dirs).to eq([Pathname.new("app/models")])
|
22
22
|
end
|
23
23
|
|
24
24
|
it "preloads models by calling require_dependency" do
|
25
25
|
models = models(["foo/bar/baz", "app/models", "some/other/models"])
|
26
|
-
Dir.
|
26
|
+
allow(Dir).to receive(:glob).
|
27
27
|
with(File.join("app/models", "**", "*.rb")).
|
28
28
|
and_return(["app/models/user.rb", "app/models/address.rb"])
|
29
|
-
Dir.
|
29
|
+
allow(Dir).to receive(:glob).
|
30
30
|
with(File.join("some/other/models", "**", "*.rb")).
|
31
31
|
and_return(["some/other/models/foo.rb"])
|
32
32
|
|
33
|
-
Kernel.
|
34
|
-
Kernel.
|
35
|
-
Kernel.
|
33
|
+
expect(Kernel).to receive(:require_dependency).with("app/models/user.rb")
|
34
|
+
expect(Kernel).to receive(:require_dependency).with("app/models/address.rb")
|
35
|
+
expect(Kernel).to receive(:require_dependency).with("some/other/models/foo.rb")
|
36
36
|
|
37
37
|
models.preload_all
|
38
38
|
end
|
@@ -42,8 +42,8 @@ describe ConsistencyFail::Models do
|
|
42
42
|
model_b = double(:name => "cat")
|
43
43
|
model_c = double(:name => "beach_ball")
|
44
44
|
|
45
|
-
ActiveRecord::Base.
|
45
|
+
allow(ActiveRecord::Base).to receive(:send).with(:descendants).and_return([model_a, model_b, model_c])
|
46
46
|
|
47
|
-
models([]).all.
|
47
|
+
expect(models([]).all).to eq([model_a, model_c, model_b])
|
48
48
|
end
|
49
49
|
end
|
data/spec/reporter_spec.rb
CHANGED
@@ -16,7 +16,7 @@ describe ConsistencyFail::Reporter do
|
|
16
16
|
it "says everything's good" do
|
17
17
|
subject.report_validates_uniqueness_problems([])
|
18
18
|
|
19
|
-
@fake_out.string.
|
19
|
+
expect(@fake_out.string).to match(/Hooray!/)
|
20
20
|
end
|
21
21
|
|
22
22
|
it "shows a missing single-column index on a single model" do
|
@@ -24,7 +24,7 @@ describe ConsistencyFail::Reporter do
|
|
24
24
|
|
25
25
|
subject.report_validates_uniqueness_problems(fake_ar_model("User", :table_name => "users") => missing_indexes)
|
26
26
|
|
27
|
-
@fake_out.string.
|
27
|
+
expect(@fake_out.string).to match(/users\s+\(email\)/)
|
28
28
|
end
|
29
29
|
|
30
30
|
it "shows a missing multiple-column index on a single model" do
|
@@ -32,7 +32,7 @@ describe ConsistencyFail::Reporter do
|
|
32
32
|
|
33
33
|
subject.report_validates_uniqueness_problems(fake_ar_model("Address", :table_name => "addresses") => missing_indexes)
|
34
34
|
|
35
|
-
@fake_out.string.
|
35
|
+
expect(@fake_out.string).to match(/addresses\s+\(number, street, zip\)/)
|
36
36
|
end
|
37
37
|
|
38
38
|
context "with problems on multiple models" do
|
@@ -46,12 +46,12 @@ describe ConsistencyFail::Reporter do
|
|
46
46
|
end
|
47
47
|
|
48
48
|
it "shows all problems" do
|
49
|
-
@fake_out.string.
|
50
|
-
@fake_out.string.
|
49
|
+
expect(@fake_out.string).to match(/users\s+\(email\)/m)
|
50
|
+
expect(@fake_out.string).to match(/citizens\s+\(ssn\)/m)
|
51
51
|
end
|
52
52
|
|
53
53
|
it "orders the models alphabetically" do
|
54
|
-
@fake_out.string.
|
54
|
+
expect(@fake_out.string).to match(/citizens\s+\(ssn\).*users\s+\(email\)/m)
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
@@ -60,7 +60,7 @@ describe ConsistencyFail::Reporter do
|
|
60
60
|
it "says everything's good" do
|
61
61
|
subject.report_has_one_problems([])
|
62
62
|
|
63
|
-
@fake_out.string.
|
63
|
+
expect(@fake_out.string).to match(/Hooray!/)
|
64
64
|
end
|
65
65
|
|
66
66
|
it "shows a missing single-column index on a single model" do
|
@@ -68,7 +68,7 @@ describe ConsistencyFail::Reporter do
|
|
68
68
|
|
69
69
|
subject.report_has_one_problems(fake_ar_model("Friend", :table_name => "users") => missing_indexes)
|
70
70
|
|
71
|
-
@fake_out.string.
|
71
|
+
expect(@fake_out.string).to match(/Friend\s+users\s+\(email\)/m)
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
@@ -76,7 +76,7 @@ describe ConsistencyFail::Reporter do
|
|
76
76
|
it "says everything's good" do
|
77
77
|
subject.report_polymorphic_problems([])
|
78
78
|
|
79
|
-
@fake_out.string.
|
79
|
+
expect(@fake_out.string).to match(/Hooray!/)
|
80
80
|
end
|
81
81
|
|
82
82
|
it "shows a missing compound index on a single model" do
|
@@ -84,7 +84,7 @@ describe ConsistencyFail::Reporter do
|
|
84
84
|
|
85
85
|
subject.report_polymorphic_problems(fake_ar_model("Address", :table_name => "addresses") => missing_indexes)
|
86
86
|
|
87
|
-
@fake_out.string.
|
87
|
+
expect(@fake_out.string).to match(/Address\s+addresses\s+\(addressable_type, addressable_id\)/m)
|
88
88
|
end
|
89
89
|
end
|
90
90
|
end
|
metadata
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: consistency_fail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
5
|
-
prerelease:
|
4
|
+
version: 0.3.3
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Colin Jones
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-12-12 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: activerecord
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - ~>
|
20
18
|
- !ruby/object:Gem::Version
|
@@ -22,7 +20,6 @@ dependencies:
|
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - ~>
|
28
25
|
- !ruby/object:Gem::Version
|
@@ -30,19 +27,17 @@ dependencies:
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rspec
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - ~>
|
36
32
|
- !ruby/object:Gem::Version
|
37
|
-
version: '
|
33
|
+
version: '3.1'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - ~>
|
44
39
|
- !ruby/object:Gem::Version
|
45
|
-
version: '
|
40
|
+
version: '3.1'
|
46
41
|
description: ! 'With more than one application server, validates_uniqueness_of becomes
|
47
42
|
a lie.
|
48
43
|
|
@@ -98,27 +93,26 @@ files:
|
|
98
93
|
homepage: http://github.com/trptcolin/consistency_fail
|
99
94
|
licenses:
|
100
95
|
- MIT
|
96
|
+
metadata: {}
|
101
97
|
post_install_message:
|
102
98
|
rdoc_options: []
|
103
99
|
require_paths:
|
104
100
|
- lib
|
105
101
|
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
-
none: false
|
107
102
|
requirements:
|
108
103
|
- - ! '>='
|
109
104
|
- !ruby/object:Gem::Version
|
110
105
|
version: '0'
|
111
106
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
-
none: false
|
113
107
|
requirements:
|
114
108
|
- - ! '>='
|
115
109
|
- !ruby/object:Gem::Version
|
116
110
|
version: '0'
|
117
111
|
requirements: []
|
118
112
|
rubyforge_project:
|
119
|
-
rubygems_version:
|
113
|
+
rubygems_version: 2.4.2
|
120
114
|
signing_key:
|
121
|
-
specification_version:
|
115
|
+
specification_version: 4
|
122
116
|
summary: A tool to detect missing unique indexes
|
123
117
|
test_files:
|
124
118
|
- spec/index_spec.rb
|
@@ -129,3 +123,4 @@ test_files:
|
|
129
123
|
- spec/models_spec.rb
|
130
124
|
- spec/reporter_spec.rb
|
131
125
|
- spec/spec_helper.rb
|
126
|
+
has_rdoc:
|