remockable 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/.travis.yml +2 -3
- data/CHANGELOG.md +6 -0
- data/README.markdown +18 -4
- data/lib/remockable/active_model/allow_values_for.rb +14 -13
- data/lib/remockable/active_model/helpers.rb +7 -6
- data/lib/remockable/active_model/validate_acceptance_of.rb +9 -11
- data/lib/remockable/active_model/validate_confirmation_of.rb +9 -11
- data/lib/remockable/active_model/validate_exclusion_of.rb +9 -11
- data/lib/remockable/active_model/validate_format_of.rb +9 -11
- data/lib/remockable/active_model/validate_inclusion_of.rb +9 -11
- data/lib/remockable/active_model/validate_length_of.rb +32 -19
- data/lib/remockable/active_model/validate_numericality_of.rb +23 -12
- data/lib/remockable/active_model/validate_presence_of.rb +9 -11
- data/lib/remockable/active_record/accept_nested_attributes_for.rb +10 -13
- data/lib/remockable/active_record/belong_to.rb +21 -13
- data/lib/remockable/active_record/have_and_belong_to_many.rb +16 -13
- data/lib/remockable/active_record/have_column.rb +14 -11
- data/lib/remockable/active_record/have_default_scope.rb +38 -20
- data/lib/remockable/active_record/have_index.rb +12 -13
- data/lib/remockable/active_record/have_many.rb +22 -13
- data/lib/remockable/active_record/have_one.rb +21 -13
- data/lib/remockable/active_record/have_scope.rb +40 -25
- data/lib/remockable/active_record/helpers.rb +3 -0
- data/lib/remockable/active_record/validate_associated.rb +9 -11
- data/lib/remockable/active_record/validate_uniqueness_of.rb +19 -11
- data/lib/remockable/helpers.rb +58 -6
- data/lib/remockable/version.rb +1 -1
- data/remockable.gemspec +3 -3
- data/spec/active_model/allow_values_for_spec.rb +19 -13
- data/spec/active_model/validate_acceptance_of_spec.rb +0 -2
- data/spec/active_model/validate_confirmation_of_spec.rb +0 -2
- data/spec/active_model/validate_exclusion_of_spec.rb +7 -9
- data/spec/active_model/validate_format_of_spec.rb +9 -11
- data/spec/active_model/validate_inclusion_of_spec.rb +7 -9
- data/spec/active_model/validate_length_of_spec.rb +16 -18
- data/spec/active_model/validate_numericality_of_spec.rb +14 -16
- data/spec/active_model/validate_presence_of_spec.rb +0 -2
- data/spec/active_record/accept_nested_attributes_for_spec.rb +22 -18
- data/spec/active_record/belong_to_spec.rb +26 -26
- data/spec/active_record/have_and_belong_to_many_spec.rb +22 -20
- data/spec/active_record/have_column_spec.rb +32 -35
- data/spec/active_record/have_default_scope_spec.rb +54 -55
- data/spec/active_record/have_index_spec.rb +24 -27
- data/spec/active_record/have_many_spec.rb +10 -11
- data/spec/active_record/have_one_spec.rb +26 -25
- data/spec/active_record/have_scope_spec.rb +75 -75
- data/spec/active_record/validate_associated_spec.rb +11 -11
- data/spec/active_record/validate_uniqueness_of_spec.rb +11 -13
- data/spec/spec_helper.rb +2 -4
- data/spec/support/active_record_example_group.rb +3 -4
- data/spec/support/class_builder.rb +15 -11
- data/spec/support/shared/a_validation_matcher.rb +25 -25
- data/spec/support/shared/an_active_record_matcher.rb +14 -12
- metadata +60 -84
@@ -1,168 +1,167 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
1
|
describe :have_default_scope do
|
4
2
|
let(:options) { :one }
|
5
3
|
|
6
4
|
it_behaves_like 'an Active Record matcher' do
|
7
5
|
let(:model) { build_class(:User, ActiveRecord::Base) }
|
8
6
|
|
7
|
+
subject(:instance) { model.new }
|
8
|
+
|
9
9
|
before do
|
10
|
-
create_table
|
10
|
+
create_table :users do |table|
|
11
|
+
table.string :one
|
12
|
+
end
|
11
13
|
end
|
12
14
|
|
13
|
-
subject { model.new }
|
14
|
-
|
15
15
|
context 'description' do
|
16
16
|
let(:matcher) { send(matcher_name, *options) }
|
17
17
|
|
18
18
|
it 'has a custom description' do
|
19
|
-
|
20
|
-
with = " with #{matcher.expected}" if matcher.expected.any?
|
19
|
+
with = " with #{matcher.options}" if matcher.options.any?
|
21
20
|
|
22
|
-
matcher.description.
|
21
|
+
expect(matcher.description).to eq "have a default scope#{with}"
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
26
25
|
context 'without arguments' do
|
27
26
|
it 'matches if a default scope exists' do
|
28
|
-
model.instance_eval { default_scope
|
29
|
-
model.
|
27
|
+
model.instance_eval { default_scope -> { order :id } }
|
28
|
+
expect(model).to have_default_scope
|
30
29
|
end
|
31
30
|
|
32
31
|
it 'does not match if a default scope does not exist' do
|
33
|
-
model.
|
32
|
+
expect(model).to_not have_default_scope
|
34
33
|
end
|
35
34
|
end
|
36
35
|
|
37
36
|
context 'with a from value' do
|
38
37
|
it 'matches if the scope exists and the query matches' do
|
39
|
-
model.instance_eval { default_scope
|
40
|
-
model.
|
38
|
+
model.instance_eval { default_scope-> { from 'users' } }
|
39
|
+
expect(model).to have_default_scope.from 'users'
|
41
40
|
end
|
42
41
|
|
43
42
|
it 'does not match if the query does not match' do
|
44
|
-
model.instance_eval { default_scope
|
45
|
-
model.
|
43
|
+
model.instance_eval { default_scope -> { from 'users' } }
|
44
|
+
expect(model).to_not have_default_scope.from 'friends'
|
46
45
|
end
|
47
46
|
end
|
48
47
|
|
49
48
|
context 'with a group value' do
|
50
49
|
it 'matches if the scope exists and the query matches' do
|
51
|
-
model.instance_eval { default_scope
|
52
|
-
model.
|
50
|
+
model.instance_eval { default_scope -> { group 'one' } }
|
51
|
+
expect(model).to have_default_scope.group 'one'
|
53
52
|
end
|
54
53
|
|
55
54
|
it 'does not match if the query does not match' do
|
56
|
-
model.instance_eval { default_scope
|
57
|
-
model.
|
55
|
+
model.instance_eval { default_scope -> { group 'one' } }
|
56
|
+
expect(model).to_not have_default_scope.group 'two'
|
58
57
|
end
|
59
58
|
end
|
60
59
|
|
61
60
|
context 'with a having value' do
|
62
61
|
it 'matches if the scope exists and the query matches' do
|
63
|
-
model.instance_eval { default_scope
|
64
|
-
model.
|
62
|
+
model.instance_eval { default_scope -> { having 'COUNT(*) > 1' } }
|
63
|
+
expect(model).to have_default_scope.having('COUNT(*) > 1')
|
65
64
|
end
|
66
65
|
|
67
66
|
it 'does not match if the query does not match' do
|
68
|
-
model.instance_eval { default_scope
|
69
|
-
model.
|
67
|
+
model.instance_eval { default_scope -> { having 'COUNT(*) > 1' } }
|
68
|
+
expect(model).to_not have_default_scope.having 'COUNT(*) > 2'
|
70
69
|
end
|
71
70
|
end
|
72
71
|
|
73
72
|
context 'with a having value' do
|
74
73
|
it 'matches if the scope exists and the query matches' do
|
75
|
-
model.instance_eval { default_scope
|
76
|
-
model.
|
74
|
+
model.instance_eval { default_scope -> { having 'COUNT(*) > 1' } }
|
75
|
+
expect(model).to have_default_scope.having 'COUNT(*) > 1'
|
77
76
|
end
|
78
77
|
|
79
78
|
it 'does not match if the query does not match' do
|
80
|
-
model.instance_eval { default_scope
|
81
|
-
model.
|
79
|
+
model.instance_eval { default_scope -> { having 'COUNT(*) > 1' } }
|
80
|
+
expect(model).to_not have_default_scope.having 'COUNT(*) > 2'
|
82
81
|
end
|
83
82
|
end
|
84
83
|
|
85
84
|
context 'with a joins value' do
|
86
85
|
it 'matches if the scope exists and the query matches' do
|
87
|
-
model.instance_eval { default_scope
|
88
|
-
model.
|
86
|
+
model.instance_eval { default_scope -> { joins 'INNER JOIN friends' } }
|
87
|
+
expect(model).to have_default_scope.joins 'INNER JOIN friends'
|
89
88
|
end
|
90
89
|
|
91
90
|
it 'does not match if the query does not match' do
|
92
|
-
model.instance_eval { default_scope
|
93
|
-
model.
|
91
|
+
model.instance_eval { default_scope -> { joins 'INNER JOIN friends' } }
|
92
|
+
expect(model).to_not have_default_scope.joins 'INNER JOIN enemies'
|
94
93
|
end
|
95
94
|
end
|
96
95
|
|
97
96
|
context 'with a limit value' do
|
98
97
|
it 'matches if the scope exists and the query matches' do
|
99
|
-
model.instance_eval { default_scope
|
100
|
-
model.
|
98
|
+
model.instance_eval { default_scope -> { limit 10 } }
|
99
|
+
expect(model).to have_default_scope.limit 10
|
101
100
|
end
|
102
101
|
|
103
102
|
it 'does not match if the query does not match' do
|
104
|
-
model.instance_eval { default_scope
|
105
|
-
model.
|
103
|
+
model.instance_eval { default_scope -> { limit 10 } }
|
104
|
+
expect(model).to_not have_default_scope.limit 15
|
106
105
|
end
|
107
106
|
end
|
108
107
|
|
109
108
|
context 'with an offset value' do
|
110
109
|
it 'matches if the scope exists and the query matches' do
|
111
|
-
model.instance_eval { default_scope
|
112
|
-
model.
|
110
|
+
model.instance_eval { default_scope -> { offset 10 } }
|
111
|
+
expect(model).to have_default_scope.offset 10
|
113
112
|
end
|
114
113
|
|
115
114
|
it 'does not match if the query does not match' do
|
116
|
-
model.instance_eval { default_scope
|
117
|
-
model.
|
115
|
+
model.instance_eval { default_scope -> { offset 10 } }
|
116
|
+
expect(model).to_not have_default_scope.offset 15
|
118
117
|
end
|
119
118
|
end
|
120
119
|
|
121
120
|
context 'with an order value' do
|
122
121
|
it 'matches if the scope exists and the query matches' do
|
123
|
-
model.instance_eval { default_scope
|
124
|
-
model.
|
122
|
+
model.instance_eval { default_scope -> { order 'one' } }
|
123
|
+
expect(model).to have_default_scope.order 'one'
|
125
124
|
end
|
126
125
|
|
127
126
|
it 'does not match if the query does not match' do
|
128
|
-
model.instance_eval { default_scope
|
129
|
-
model.
|
127
|
+
model.instance_eval { default_scope -> { order 'one' } }
|
128
|
+
expect(model).to_not have_default_scope.order 'id'
|
130
129
|
end
|
131
130
|
end
|
132
131
|
|
133
132
|
context 'with a reorder value' do
|
134
133
|
it 'matches if the scope exists and the query matches' do
|
135
|
-
model.instance_eval { default_scope
|
136
|
-
model.
|
134
|
+
model.instance_eval { default_scope -> { reorder 'one' } }
|
135
|
+
expect(model).to have_default_scope.reorder 'one'
|
137
136
|
end
|
138
137
|
|
139
138
|
it 'does not match if the query does not match' do
|
140
|
-
model.instance_eval { default_scope
|
141
|
-
model.
|
139
|
+
model.instance_eval { default_scope -> { reorder 'one' } }
|
140
|
+
expect(model).to_not have_default_scope.reorder 'id'
|
142
141
|
end
|
143
142
|
end
|
144
143
|
|
145
144
|
context 'with a select value' do
|
146
145
|
it 'matches if the scope exists and the query matches' do
|
147
|
-
model.instance_eval { default_scope
|
148
|
-
model.
|
146
|
+
model.instance_eval { default_scope -> { select 'one' } }
|
147
|
+
expect(model).to have_default_scope.select 'one'
|
149
148
|
end
|
150
149
|
|
151
150
|
it 'does not match if the query does not match' do
|
152
|
-
model.instance_eval { default_scope
|
153
|
-
model.
|
151
|
+
model.instance_eval { default_scope -> { select 'one' } }
|
152
|
+
expect(model).to_not have_default_scope.select 'id'
|
154
153
|
end
|
155
154
|
end
|
156
155
|
|
157
156
|
context 'with a where value' do
|
158
157
|
it 'matches if the scope exists and the query matches' do
|
159
|
-
model.instance_eval { default_scope
|
160
|
-
model.
|
158
|
+
model.instance_eval { default_scope -> { where one: nil } }
|
159
|
+
expect(model).to have_default_scope.where one: nil
|
161
160
|
end
|
162
161
|
|
163
162
|
it 'does not match if the query does not match' do
|
164
|
-
model.instance_eval { default_scope
|
165
|
-
model.
|
163
|
+
model.instance_eval { default_scope -> { where one: nil } }
|
164
|
+
expect(model).to_not have_default_scope.where one: 1
|
166
165
|
end
|
167
166
|
end
|
168
167
|
end
|
@@ -1,88 +1,85 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
1
|
describe :have_index do
|
4
2
|
let(:options) { :one }
|
5
3
|
|
6
4
|
it_behaves_like 'an Active Record matcher' do
|
7
5
|
let(:model) { build_class(:User, ActiveRecord::Base) }
|
8
6
|
|
7
|
+
subject(:instance) { model.new }
|
8
|
+
|
9
9
|
before do
|
10
|
-
create_table
|
11
|
-
table.string
|
12
|
-
table.string
|
10
|
+
create_table :users do |table|
|
11
|
+
table.string :one
|
12
|
+
table.string :two
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
subject { model.new }
|
17
|
-
|
18
16
|
context 'description' do
|
19
17
|
let(:matcher) { send(matcher_name, *options) }
|
20
18
|
|
21
19
|
it 'has a custom description' do
|
22
|
-
|
23
|
-
with = " with #{matcher.expected}" if matcher.expected.any?
|
20
|
+
with = " with #{matcher.options}" if matcher.options.any?
|
24
21
|
|
25
|
-
matcher.description.
|
22
|
+
expect(matcher.description).to eq "have index on #{options}#{with}"
|
26
23
|
end
|
27
24
|
end
|
28
25
|
|
29
26
|
context 'with a single column' do
|
30
27
|
it 'matches if the index exists' do
|
31
|
-
ActiveRecord::Base.connection.add_index
|
32
|
-
model.
|
28
|
+
ActiveRecord::Base.connection.add_index :users, :one
|
29
|
+
expect(model).to have_index :one
|
33
30
|
end
|
34
31
|
|
35
32
|
it 'does not match if the index does not exist' do
|
36
|
-
model.
|
33
|
+
expect(model).to_not have_index :one
|
37
34
|
end
|
38
35
|
end
|
39
36
|
|
40
37
|
context 'with multiple columns' do
|
41
38
|
it 'matches if the index exists' do
|
42
|
-
ActiveRecord::Base.connection.add_index
|
43
|
-
model.
|
39
|
+
ActiveRecord::Base.connection.add_index :users, [:one, :two]
|
40
|
+
expect(model).to have_index [:one, :two]
|
44
41
|
end
|
45
42
|
|
46
43
|
it 'does not match if the index does not exist' do
|
47
|
-
model.
|
44
|
+
expect(model).to_not have_index [:one, :two]
|
48
45
|
end
|
49
46
|
end
|
50
47
|
|
51
48
|
context 'with option :unique' do
|
52
49
|
it 'matches if the index exists' do
|
53
|
-
ActiveRecord::Base.connection.add_index
|
54
|
-
model.
|
50
|
+
ActiveRecord::Base.connection.add_index :users, :one, unique: true
|
51
|
+
expect(model).to have_index :one, unique: true
|
55
52
|
end
|
56
53
|
|
57
54
|
it 'does not match if the index is not unique' do
|
58
|
-
ActiveRecord::Base.connection.add_index
|
59
|
-
model.
|
55
|
+
ActiveRecord::Base.connection.add_index :users, :one
|
56
|
+
expect(model).to_not have_index :one, unique: true
|
60
57
|
end
|
61
58
|
|
62
59
|
it 'does not match if the index does not exist' do
|
63
|
-
model.
|
60
|
+
expect(model).to_not have_index :one, unique: true
|
64
61
|
end
|
65
62
|
end
|
66
63
|
|
67
64
|
context 'with option :name' do
|
68
65
|
it 'matches if the index exists' do
|
69
|
-
ActiveRecord::Base.connection.add_index
|
70
|
-
model.
|
66
|
+
ActiveRecord::Base.connection.add_index :users, :one, name: :oneness
|
67
|
+
expect(model).to have_index :one, name: :oneness
|
71
68
|
end
|
72
69
|
|
73
70
|
it 'does not match if the index does not exist' do
|
74
|
-
model.
|
71
|
+
expect(model).to_not have_index :one, name: :oneness
|
75
72
|
end
|
76
73
|
end
|
77
74
|
|
78
75
|
context 'with option :name and without :one' do
|
79
76
|
it 'matches if the index exists' do
|
80
|
-
ActiveRecord::Base.connection.add_index
|
81
|
-
model.
|
77
|
+
ActiveRecord::Base.connection.add_index :users, :one, name: :oneness
|
78
|
+
expect(model).to have_index name: :oneness
|
82
79
|
end
|
83
80
|
|
84
81
|
it 'does not match if the index does not exist' do
|
85
|
-
model.
|
82
|
+
expect(model).to_not have_index name: :oneness
|
86
83
|
end
|
87
84
|
end
|
88
85
|
end
|
@@ -1,25 +1,24 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
1
|
describe :have_many do
|
4
2
|
let(:macro) { :has_many }
|
5
|
-
let(:options) { [:posts, { :
|
3
|
+
let(:options) { [:posts, { dependent: :destroy }] }
|
6
4
|
|
7
5
|
it_behaves_like 'an Active Record matcher' do
|
8
6
|
let(:model) { build_class(:User, ActiveRecord::Base) }
|
9
7
|
|
8
|
+
subject(:instance) { model.new }
|
9
|
+
|
10
10
|
before do
|
11
11
|
create_table(:users) { |table| table.string(:name) }
|
12
12
|
end
|
13
13
|
|
14
|
-
subject { model.new }
|
15
|
-
|
16
14
|
context 'description' do
|
17
15
|
let(:matcher) { send(matcher_name, *options) }
|
18
16
|
|
19
17
|
it 'has a custom description' do
|
20
|
-
association = matcher.
|
21
|
-
with = " with #{matcher.
|
22
|
-
|
18
|
+
association = matcher.attribute
|
19
|
+
with = " with #{matcher.options.inspect}" if matcher.options.any?
|
20
|
+
|
21
|
+
expect(matcher.description).to eq "have many #{association}#{with}"
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
@@ -28,16 +27,16 @@ describe :have_many do
|
|
28
27
|
|
29
28
|
it 'matches if the association exists' do
|
30
29
|
model.has_many(*options)
|
31
|
-
model.
|
30
|
+
expect(model).to have_many(*options)
|
32
31
|
end
|
33
32
|
|
34
33
|
it 'does not match if the association does not exist' do
|
35
|
-
model.
|
34
|
+
expect(model).to_not have_many(*options)
|
36
35
|
end
|
37
36
|
|
38
37
|
it 'does not match if the association is of the wrong type' do
|
39
38
|
model.belongs_to(*options)
|
40
|
-
model.
|
39
|
+
expect(model).to_not have_many(*options)
|
41
40
|
end
|
42
41
|
end
|
43
42
|
|
@@ -1,25 +1,26 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
1
|
describe :have_one do
|
4
2
|
let(:macro) { :has_one }
|
5
|
-
let(:options) { [:address, { :
|
3
|
+
let(:options) { [:address, { dependent: :destroy }] }
|
6
4
|
|
7
5
|
it_behaves_like 'an Active Record matcher' do
|
8
6
|
let(:model) { build_class(:User, ActiveRecord::Base) }
|
9
7
|
|
8
|
+
subject(:instance) { model.new }
|
9
|
+
|
10
10
|
before do
|
11
|
-
create_table
|
11
|
+
create_table :users do |table|
|
12
|
+
table.string :name
|
13
|
+
end
|
12
14
|
end
|
13
15
|
|
14
|
-
subject { model.new }
|
15
|
-
|
16
16
|
context 'description' do
|
17
17
|
let(:matcher) { send(matcher_name, *options) }
|
18
18
|
|
19
19
|
it 'has a custom description' do
|
20
|
-
association = matcher.
|
21
|
-
with = " with #{matcher.
|
22
|
-
|
20
|
+
association = matcher.attribute
|
21
|
+
with = " with #{matcher.options.inspect}" if matcher.options.any?
|
22
|
+
|
23
|
+
expect(matcher.description).to eq "have a #{association}#{with}"
|
23
24
|
end
|
24
25
|
end
|
25
26
|
|
@@ -27,30 +28,30 @@ describe :have_one do
|
|
27
28
|
let(:options) { :address }
|
28
29
|
|
29
30
|
it 'matches if the association exists' do
|
30
|
-
model.has_one
|
31
|
-
model.
|
31
|
+
model.has_one *options
|
32
|
+
expect(model).to have_one *options
|
32
33
|
end
|
33
34
|
|
34
35
|
it 'does not match if the association does not exist' do
|
35
|
-
model.
|
36
|
+
expect(model).to_not have_one *options
|
36
37
|
end
|
37
38
|
|
38
39
|
it 'does not match if the association is of the wrong type' do
|
39
|
-
model.has_many
|
40
|
-
model.
|
40
|
+
model.has_many *options
|
41
|
+
expect(model).to_not have_one *options
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
44
|
-
with_option
|
45
|
-
with_option
|
46
|
-
with_option
|
47
|
-
with_option
|
48
|
-
with_option
|
49
|
-
with_option
|
50
|
-
with_option
|
51
|
-
with_option
|
52
|
-
with_option
|
53
|
-
with_option
|
54
|
-
with_option
|
45
|
+
with_option :class_name, 'Address', 'Location'
|
46
|
+
with_option :dependent, :destroy, :nullify
|
47
|
+
with_option :foreign_key, :address_id, :location_id
|
48
|
+
with_option :primary_key, :id, :address_id
|
49
|
+
with_option :as, :addressable, :locatable
|
50
|
+
with_option :through, :offices, :locations
|
51
|
+
with_option :source, :addressable, :contactable, through: :offices
|
52
|
+
with_option :source_type, 'Company', 'Organization', through: :offices
|
53
|
+
with_option :validate, true, false
|
54
|
+
with_option :autosave, true, false
|
55
|
+
with_option :inverse_of, :user, :employee
|
55
56
|
end
|
56
57
|
end
|