required_scopes 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,312 @@
1
+ require 'required_scopes'
2
+ require 'required_scopes/helpers/database_helper'
3
+ require 'required_scopes/helpers/system_helpers'
4
+
5
+ describe "RequiredScopes method coverage" do
6
+ include RequiredScopes::Helpers::SystemHelpers
7
+
8
+ before :each do
9
+ @dh = RequiredScopes::Helpers::DatabaseHelper.new
10
+ @dh.setup_activerecord!
11
+
12
+ create_standard_system_spec_tables!
13
+ create_standard_system_spec_models!
14
+ create_standard_system_spec_instances!
15
+
16
+ define_color_and_taste_scopes!
17
+ end
18
+
19
+ after :each do
20
+ drop_standard_system_spec_tables!
21
+ end
22
+
23
+ # We add these methods because a number of tests are calling methods that only work on relations -- not on a model
24
+ # class directly. This gives us a new method, #to_relation, that makes sure we always have a Relation, but without
25
+ # otherwise changing the target of our call in any way.
26
+ class ActiveRecord::Base
27
+ class << self
28
+ def to_relation
29
+ relation
30
+ end
31
+ end
32
+ end
33
+
34
+ class ActiveRecord::Relation
35
+ def to_relation
36
+ self
37
+ end
38
+ end
39
+
40
+ class ShouldRaiseDescription
41
+ attr_reader :description, :block
42
+
43
+ def initialize(description, triggering_method, block)
44
+ @description = description
45
+ @triggering_method = triggering_method
46
+ @block = block
47
+ end
48
+
49
+ def go!(spec, call_on, required, satisfied)
50
+ spec.should_raise_missing_scopes(@triggering_method, required, satisfied) { @block.call(call_on) }
51
+ end
52
+ end
53
+
54
+ class << self
55
+ def srd(description, triggering_method, &block)
56
+ ShouldRaiseDescription.new(description, triggering_method, block)
57
+ end
58
+ end
59
+
60
+ describe "methods that should raise" do
61
+ should_raise_methods =
62
+ [
63
+ # ActiveRecord::Relation
64
+ srd(:first_or_create, :exec_queries) { |s| s.first_or_create(:name => 'some user') },
65
+ srd(:first_or_create!, :exec_queries) { |s| s.first_or_create!(:name => 'some user') },
66
+ srd(:first_or_initialize, :exec_queries) { |s| s.first_or_initialize(:name => 'some user') },
67
+ srd(:to_a, :exec_queries) { |s| s.to_relation.to_a },
68
+ srd(:explain, :exec_queries) { |s| s.to_relation.explain },
69
+ srd(:as_json, :exec_queries) { |s| s.to_relation.as_json },
70
+ srd(:size, :perform_calculation) { |s| s.to_relation.size },
71
+ srd(:empty?, :perform_calculation) { |s| s.to_relation.empty? },
72
+ srd(:any?, :perform_calculation) { |s| s.to_relation.any? },
73
+ srd(:many?, :perform_calculation) { |s| s.to_relation.many? },
74
+ srd(:scoping, :exec_queries) { |s| s.to_relation.scoping { ::User.all.to_a } },
75
+ srd(:update_all, :update_all) { |s| s.update_all("name = 'foo'") },
76
+ srd(:update, :exec_queries) { |s| s.update(::User.unscoped.all_scope_categories_satisfied.first.id, :name => 'foo') },
77
+ srd(:destroy_all, :exec_queries) { |s| s.destroy_all },
78
+ srd(:destroy, :exec_queries) { |s| s.destroy(::User.unscoped.all_scope_categories_satisfied.first.id) },
79
+ srd(:delete_all, :delete_all) { |s| s.delete_all },
80
+ srd(:delete, :delete_all) { |s| s.delete(::User.unscoped.all_scope_categories_satisfied.first.id) },
81
+ srd(:reload, :exec_queries) { |s| s.to_relation.reload },
82
+
83
+ # ActiveRecord::Relation::FinderMethods
84
+ srd(:find, :exec_queries) { |s| s.find(::User.unscoped.all_scope_categories_satisfied.first.id) },
85
+ srd(:first, :exec_queries) { |s| s.first },
86
+ srd(:first!, :exec_queries) { |s| s.first! },
87
+ srd(:last, :exec_queries) { |s| s.last },
88
+ srd(:last!, :exec_queries) { |s| s.last! },
89
+ srd(:exists?, :exists?) { |s| s.exists? },
90
+
91
+ # ActiveRecord::Relation::Calculations
92
+ srd(:count, :perform_calculation) { |s| s.count },
93
+ srd(:average, :perform_calculation) { |s| s.average("id") },
94
+ srd(:minimum, :perform_calculation) { |s| s.minimum("id") },
95
+ srd(:maximum, :perform_calculation) { |s| s.maximum("id") },
96
+ srd(:sum, :perform_calculation) { |s| s.sum("id") },
97
+ srd(:calculate, :perform_calculation) { |s| s.calculate("SUM", "id") },
98
+ srd(:pluck, :pluck) { |s| s.pluck("name") },
99
+
100
+ # ActiveRecord::Relation::Batches
101
+ srd(:find_each, :exec_queries) { |s| s.find_each { |o| } },
102
+ srd(:find_in_batches, :exec_queries) { |s| s.find_in_batches { |b| } },
103
+
104
+ # ActiveRecord::Relation::Delegation
105
+ srd(:to_xml, :exec_queries) { |s| s.to_relation.to_xml },
106
+ srd(:to_yaml, :exec_queries) { |s| s.to_relation.to_yaml },
107
+ srd(:length, :exec_queries) { |s| s.to_relation.length },
108
+ srd(:collect, :exec_queries) { |s| s.to_relation.collect(&:to_s) },
109
+ srd(:map, :exec_queries) { |s| s.to_relation.map(&:to_s) },
110
+ srd(:each, :exec_queries) { |s| s.to_relation.each(&:to_s) },
111
+ srd(:all?, :exec_queries) { |s| s.to_relation.all?(&:to_s) },
112
+ srd(:include?, :exec_queries) { |s| s.to_relation.include?('foo') },
113
+ srd(:to_ary, :exec_queries) { |s| s.to_relation.to_ary },
114
+ srd(:to_a, :exec_queries) { |s| s.to_relation.to_a }
115
+ ]
116
+
117
+ if ::RequiredScopes::ActiveRecord::VersionCompatibility.supports_find_by?
118
+ should_raise_methods += [
119
+ srd(:find_or_create_by, :exec_queries) { |s| s.find_or_create_by(:name => 'some user') },
120
+ srd(:find_or_create_by!, :exec_queries) { |s| s.find_or_create_by!(:name => 'some user') },
121
+ srd(:find_or_initialize_by, :exec_queries) { |s| s.find_or_initialize_by(:name => 'some user') },
122
+ srd(:find_by, :exec_queries) { |s| s.find_by(:name => 'User 1') },
123
+ srd(:find_by!, :exec_queries) { |s| s.find_by!(:name => ::User.unscoped.all_scope_categories_satisfied.first.name) },
124
+ ]
125
+ end
126
+
127
+ if ::RequiredScopes::ActiveRecord::VersionCompatibility.supports_load?
128
+ should_raise_methods += [
129
+ srd(:load, :exec_queries) { |s| x = s.to_relation.load },
130
+ ]
131
+ end
132
+
133
+ if ::RequiredScopes::ActiveRecord::VersionCompatibility.supports_take?
134
+ should_raise_methods += [
135
+ srd(:take, :exec_queries) { |s| s.take },
136
+ srd(:take!, :exec_queries) { |s| s.take! },
137
+ ]
138
+ end
139
+
140
+ if ::RequiredScopes::ActiveRecord::VersionCompatibility.supports_ids?
141
+ should_raise_methods += [
142
+ srd(:ids, :pluck) { |s| s.ids },
143
+ ]
144
+ end
145
+
146
+
147
+ should_raise_methods.each do |srd_obj|
148
+ describe "##{srd_obj.description}" do
149
+ it "should raise when invoked on the base class" do
150
+ srd_obj.go!(self, ::User, [ :color, :taste ], [ ])
151
+ end
152
+
153
+ it "should raise when invoked with just one scope" do
154
+ srd_obj.go!(self, ::User.red, [ :color, :taste ], [ :color ])
155
+ srd_obj.go!(self, ::User.salty, [ :color, :taste ], [ :taste ])
156
+ end
157
+
158
+ it "should not raise when invoked with both scopes" do
159
+ srd_obj.block.call(::User.red.salty)
160
+ end
161
+ end
162
+ end
163
+ end
164
+
165
+ class NoRaiseDescription
166
+ attr_reader :description
167
+
168
+ def initialize(description, block)
169
+ @description = description
170
+ @block = block
171
+ end
172
+
173
+ def go!(call_on)
174
+ @block.call(call_on)
175
+ end
176
+ end
177
+
178
+ class << self
179
+ def nrd(description, &block)
180
+ NoRaiseDescription.new(description, block)
181
+ end
182
+ end
183
+
184
+ describe "methods that should not raise" do
185
+ should_not_raise_methods =
186
+ [
187
+ # ActiveRecord::Relation
188
+ nrd(:new) { |s| s.new },
189
+ nrd(:create) { |s| s.create(:name => 'User 1') },
190
+ nrd(:create!) { |s| s.create!(:name => 'User 1') },
191
+ nrd(:scoping) { |s| s.to_relation.scoping { } },
192
+ nrd(:reset) { |s| s.to_relation.reset },
193
+ nrd(:to_sql) { |s| s.to_relation.to_sql },
194
+
195
+ # ActiveRecord::Relation::SpawnMethods
196
+ nrd(:merge) { |s| s.to_relation.merge(s.where(:name => 'User 1')) },
197
+ nrd(:except) { |s| s.to_relation.except(:order) },
198
+ nrd(:only) { |s| s.to_relation.only(:order) },
199
+
200
+ # ActiveRecord::Relation::QueryMethods
201
+ nrd(:includes) { |s| s.includes(:foo) },
202
+ nrd(:eager_load) { |s| s.eager_load(:foo) },
203
+ nrd(:preload) { |s| s.preload(:foo) },
204
+ nrd(:select) { |s| s.select("id, name") },
205
+ nrd(:group) { |s| s.group(:id) },
206
+ nrd(:order) { |s| s.order("id") },
207
+ nrd(:reorder) { |s| s.reorder("id") },
208
+ nrd(:joins) { |s| s.joins(:foo) },
209
+ nrd(:bind) { |s| s.to_relation.bind(:foo => 'bar') },
210
+ nrd(:where) { |s| s.where(:name => 'foo') },
211
+ nrd(:having) { |s| s.to_relation.having("id") },
212
+ nrd(:limit) { |s| s.limit(5) },
213
+ nrd(:offset) { |s| s.offset(10) },
214
+ nrd(:lock) { |s| s.lock },
215
+ nrd(:readonly) { |s| s.readonly },
216
+ nrd(:create_with) { |s| s.create_with(:name => 'foo') },
217
+ nrd(:from) { |s| s.from("USER") },
218
+ nrd(:extending) { |s| s.to_relation.extending(Module.new) },
219
+ nrd(:reverse_order) { |s| s.to_relation.reverse_order },
220
+ nrd(:arel) { |s| s.to_relation.arel },
221
+ nrd(:build_arel) { |s| s.to_relation.build_arel },
222
+
223
+ # ActiveRecord::Relation::Explain
224
+ nrd(:collecting_queries_for_explain) { |s| s.collecting_queries_for_explain { } },
225
+ nrd(:exec_explain) { |s| s.exec_explain([ [ "SELECT * FROM #{::User.table_name}", { } ] ]) },
226
+
227
+ # ActiveRecord::Relation::Delegation
228
+ nrd(:table_name) { |s| s.table_name },
229
+ nrd(:quoted_table_name) { |s| s.quoted_table_name },
230
+ nrd(:primary_key) { |s| s.primary_key },
231
+ nrd(:quoted_primary_key) { |s| s.quoted_primary_key },
232
+ nrd(:connection) { |s| s.connection },
233
+ nrd(:columns_hash) { |s| s.columns_hash },
234
+ ]
235
+
236
+ if ::RequiredScopes::ActiveRecord::VersionCompatibility.supports_spawn?
237
+ should_not_raise_methods += [
238
+ nrd(:spawn) { |s| s.to_relation.spawn },
239
+ ]
240
+ end
241
+
242
+ if ::RequiredScopes::ActiveRecord::VersionCompatibility.supports_bang_methods?
243
+ should_not_raise_methods += [
244
+ nrd(:merge!) { |s| s.to_relation.merge!(s.where(:name => 'User 1')) },
245
+ nrd(:includes!) { |s| s.to_relation.includes!(:foo) },
246
+ nrd(:eager_load!) { |s| s.to_relation.eager_load!(:foo) },
247
+ nrd(:preload!) { |s| s.to_relation.preload!(:foo) },
248
+ nrd(:select!) { |s| s.to_relation.select!("id, name") },
249
+ nrd(:group!) { |s| s.to_relation.group!(:id) },
250
+ nrd(:order!) { |s| s.to_relation.order!("id") },
251
+ nrd(:reorder!) { |s| s.to_relation.reorder!("id") },
252
+ nrd(:joins!) { |s| s.to_relation.joins!(:foo) },
253
+ nrd(:bind!) { |s| s.to_relation.bind!(:foo => 'bar') },
254
+ nrd(:where!) { |s| s.to_relation.where!(:name => 'foo') },
255
+ nrd(:having!) { |s| s.to_relation.having!("id") },
256
+ nrd(:limit!) { |s| s.to_relation.limit!(5) },
257
+ nrd(:offset!) { |s| s.to_relation.offset!(10) },
258
+ nrd(:lock!) { |s| s.to_relation.lock! },
259
+ nrd(:readonly!) { |s| s.to_relation.readonly! },
260
+ nrd(:create_with!) { |s| s.to_relation.create_with!(:name => 'foo') },
261
+ nrd(:from!) { |s| s.to_relation.from!("USER") },
262
+ nrd(:extending!) { |s| s.to_relation.extending!(Module.new) },
263
+ nrd(:reverse_order!) { |s| s.to_relation.reverse_order! },
264
+ ]
265
+ end
266
+
267
+ if ::RequiredScopes::ActiveRecord::VersionCompatibility.supports_references?
268
+ should_not_raise_methods += [
269
+ nrd(:references) { |s| s.references(:foo) },
270
+ nrd(:references!) { |s| s.to_relation.references!(:foo) },
271
+ ]
272
+ end
273
+
274
+ if ::RequiredScopes::ActiveRecord::VersionCompatibility.supports_unscope?
275
+ should_not_raise_methods += [
276
+ nrd(:unscope) { |s| s.to_relation.unscope(:order) },
277
+ nrd(:unscope!) { |s| s.to_relation.unscope!(:order) },
278
+ ]
279
+ end
280
+
281
+ if ::RequiredScopes::ActiveRecord::VersionCompatibility.supports_none?
282
+ should_not_raise_methods += [
283
+ nrd(:none) { |s| s.none },
284
+ nrd(:none!) { |s| s.to_relation.none! },
285
+ ]
286
+ end
287
+
288
+ if ::RequiredScopes::ActiveRecord::VersionCompatibility.supports_distinct?
289
+ should_not_raise_methods += [
290
+ nrd(:distinct) { |s| s.distinct("id") },
291
+ nrd(:distinct!) { |s| s.to_relation.distinct!("id") },
292
+ ]
293
+ end
294
+
295
+
296
+ should_not_raise_methods.each do |nrd_obj|
297
+ describe "#{nrd_obj.description}" do
298
+ it "should not raise when invoked on the base class" do
299
+ nrd_obj.go!(::User)
300
+ end
301
+
302
+ it "should not raise when invoked with one scope" do
303
+ nrd_obj.go!(::User.red)
304
+ end
305
+
306
+ it "should not raise when invoked with two scopes" do
307
+ nrd_obj.go!(::User.red.salty)
308
+ end
309
+ end
310
+ end
311
+ end
312
+ end
@@ -0,0 +1,31 @@
1
+ require 'required_scopes'
2
+ require 'required_scopes/helpers/database_helper'
3
+ require 'required_scopes/helpers/system_helpers'
4
+
5
+ describe "RequiredScopes static-scope operations" do
6
+ include RequiredScopes::Helpers::SystemHelpers
7
+
8
+ before :each do
9
+ @dh = RequiredScopes::Helpers::DatabaseHelper.new
10
+ @dh.setup_activerecord!
11
+
12
+ create_standard_system_spec_tables!
13
+ create_standard_system_spec_models!
14
+ create_standard_system_spec_instances!
15
+ end
16
+
17
+ after :each do
18
+ drop_standard_system_spec_tables!
19
+ end
20
+
21
+ it "should support static scopes" do
22
+ ::User.class_eval do
23
+ must_scope_by :color
24
+
25
+ scope :red, where(:favorite_color => 'red'), :satisfies => :color
26
+ end
27
+
28
+ lambda { ::User.all.to_a }.should raise_error(RequiredScopes::Errors::RequiredScopeCategoriesNotSatisfiedError)
29
+ ::User.red.to_a.length.should >= 1
30
+ end
31
+ end
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: required_scopes
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Geweke
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2014-01-07 00:00:00 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ prerelease: false
17
+ requirement: &id001 !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: "1.3"
22
+ type: :development
23
+ version_requirements: *id001
24
+ - !ruby/object:Gem::Dependency
25
+ name: rake
26
+ prerelease: false
27
+ requirement: &id002 !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - &id006
30
+ - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id002
35
+ - !ruby/object:Gem::Dependency
36
+ name: rspec
37
+ prerelease: false
38
+ requirement: &id003 !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ~>
41
+ - !ruby/object:Gem::Version
42
+ version: "2.14"
43
+ type: :development
44
+ version_requirements: *id003
45
+ - !ruby/object:Gem::Dependency
46
+ name: activerecord
47
+ prerelease: false
48
+ requirement: &id004 !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "3.0"
53
+ - - <=
54
+ - !ruby/object:Gem::Version
55
+ version: 4.99.99
56
+ type: :runtime
57
+ version_requirements: *id004
58
+ - !ruby/object:Gem::Dependency
59
+ name: activesupport
60
+ prerelease: false
61
+ requirement: &id005 !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "3.0"
66
+ - - <=
67
+ - !ruby/object:Gem::Version
68
+ version: 4.99.99
69
+ type: :runtime
70
+ version_requirements: *id005
71
+ - !ruby/object:Gem::Dependency
72
+ name: pg
73
+ prerelease: false
74
+ requirement: &id007 !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - *id006
77
+ type: :development
78
+ version_requirements: *id007
79
+ description: Don't let developers forget about critical scopes for queries.
80
+ email:
81
+ - andrew@geweke.org
82
+ executables: []
83
+
84
+ extensions: []
85
+
86
+ extra_rdoc_files: []
87
+
88
+ files:
89
+ - .gitignore
90
+ - .travis.yml
91
+ - Gemfile
92
+ - LICENSE.txt
93
+ - README.md
94
+ - Rakefile
95
+ - lib/required_scopes.rb
96
+ - lib/required_scopes/active_record/base.rb
97
+ - lib/required_scopes/active_record/relation.rb
98
+ - lib/required_scopes/active_record/version_compatibility.rb
99
+ - lib/required_scopes/errors.rb
100
+ - lib/required_scopes/version.rb
101
+ - required_scopes.gemspec
102
+ - spec/required_scopes/helpers/database_helper.rb
103
+ - spec/required_scopes/helpers/system_helpers.rb
104
+ - spec/required_scopes/system/associations_system_spec.rb
105
+ - spec/required_scopes/system/base_scope_system_spec.rb
106
+ - spec/required_scopes/system/basic_system_spec.rb
107
+ - spec/required_scopes/system/inheritance_system_spec.rb
108
+ - spec/required_scopes/system/methods_system_spec.rb
109
+ - spec/required_scopes/system/static_scopes_system_spec.rb
110
+ homepage: https://github.com/ageweke/required_scopes
111
+ licenses:
112
+ - MIT
113
+ metadata: {}
114
+
115
+ post_install_message:
116
+ rdoc_options: []
117
+
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - *id006
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - *id006
126
+ requirements: []
127
+
128
+ rubyforge_project:
129
+ rubygems_version: 2.0.14
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: Don't let developers forget about critical scopes for queries.
133
+ test_files:
134
+ - spec/required_scopes/helpers/database_helper.rb
135
+ - spec/required_scopes/helpers/system_helpers.rb
136
+ - spec/required_scopes/system/associations_system_spec.rb
137
+ - spec/required_scopes/system/base_scope_system_spec.rb
138
+ - spec/required_scopes/system/basic_system_spec.rb
139
+ - spec/required_scopes/system/inheritance_system_spec.rb
140
+ - spec/required_scopes/system/methods_system_spec.rb
141
+ - spec/required_scopes/system/static_scopes_system_spec.rb