required_scopes 1.0.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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +29 -0
- data/Gemfile +17 -0
- data/LICENSE.txt +22 -0
- data/README.md +277 -0
- data/Rakefile +6 -0
- data/lib/required_scopes.rb +17 -0
- data/lib/required_scopes/active_record/base.rb +235 -0
- data/lib/required_scopes/active_record/relation.rb +121 -0
- data/lib/required_scopes/active_record/version_compatibility.rb +157 -0
- data/lib/required_scopes/errors.rb +48 -0
- data/lib/required_scopes/version.rb +3 -0
- data/required_scopes.gemspec +56 -0
- data/spec/required_scopes/helpers/database_helper.rb +174 -0
- data/spec/required_scopes/helpers/system_helpers.rb +98 -0
- data/spec/required_scopes/system/associations_system_spec.rb +150 -0
- data/spec/required_scopes/system/base_scope_system_spec.rb +71 -0
- data/spec/required_scopes/system/basic_system_spec.rb +121 -0
- data/spec/required_scopes/system/inheritance_system_spec.rb +67 -0
- data/spec/required_scopes/system/methods_system_spec.rb +312 -0
- data/spec/required_scopes/system/static_scopes_system_spec.rb +31 -0
- metadata +141 -0
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'required_scopes/errors'
|
3
|
+
require 'required_scopes/active_record/version_compatibility'
|
4
|
+
|
5
|
+
# This file simply adds a few small methods to ::ActiveRecord::Relation to allow tracking which scope categories have
|
6
|
+
# been satisfied on a relation.
|
7
|
+
::ActiveRecord::Relation.class_eval do
|
8
|
+
# Call this method inline, exactly as you would any class-defined scope, to indicate that a particular category
|
9
|
+
# or categories have been satisfied. It's really intended for use in a class method, but both of these will
|
10
|
+
# work:
|
11
|
+
#
|
12
|
+
# class User < ActiveRecord::Base
|
13
|
+
# must_scope_by :client, :deleted
|
14
|
+
#
|
15
|
+
# class << self
|
16
|
+
# def active_for_client_named(client_name)
|
17
|
+
# client_id = CLIENT_MAP[client_name]
|
18
|
+
# where(:client_id => client_id).where(:deleted => false).scope_categories_satisfied(:client)
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# User.active_for_client_named('foo').first
|
24
|
+
# User.where(:client_id => client_id).where(:deleted => false).scope_categories_satisfied(:client, :deleted).first
|
25
|
+
def scope_categories_satisfied(*categories, &block)
|
26
|
+
categories = categories.flatten
|
27
|
+
|
28
|
+
new_scope = if categories.length == 0
|
29
|
+
self
|
30
|
+
else
|
31
|
+
out = clone
|
32
|
+
out.scope_categories_satisfied!(categories)
|
33
|
+
out
|
34
|
+
end
|
35
|
+
|
36
|
+
if block
|
37
|
+
new_scope.scoping(&block)
|
38
|
+
else
|
39
|
+
new_scope
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Alias for #scope_categories_satisfied.
|
44
|
+
def scope_category_satisfied(category, &block)
|
45
|
+
scope_categories_satisfied(category, &block)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Tells this Relation that one or more categories have been satisfied.
|
49
|
+
def scope_categories_satisfied!(categories)
|
50
|
+
categories = categories.flatten
|
51
|
+
|
52
|
+
@satisfied_scope_categories ||= [ ]
|
53
|
+
@satisfied_scope_categories |= categories
|
54
|
+
end
|
55
|
+
|
56
|
+
# Tells this Relation that _all_ categories have been satisfied.
|
57
|
+
def all_scope_categories_satisfied!
|
58
|
+
scope_categories_satisfied!(required_scope_categories)
|
59
|
+
end
|
60
|
+
|
61
|
+
def all_scope_categories_satisfied(&block)
|
62
|
+
scope_categories_satisfied(required_scope_categories, &block)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns the set of scope categories that have been satisfied.
|
66
|
+
def satisfied_scope_categories
|
67
|
+
@satisfied_scope_categories ||= [ ]
|
68
|
+
end
|
69
|
+
|
70
|
+
# Overrides #merge to merge the information about which scope categories have been satisfied, too.
|
71
|
+
def merge(other_relation)
|
72
|
+
super.scope_categories_satisfied(satisfied_scope_categories | other_relation.satisfied_scope_categories)
|
73
|
+
end
|
74
|
+
|
75
|
+
delegate :required_scope_categories, :to => :klass
|
76
|
+
|
77
|
+
|
78
|
+
private
|
79
|
+
# Raises an exception if there is at least one required scope category that has not yet been satisfied.
|
80
|
+
# +triggering_method+ is the name of the method called that triggered this check; we include this in the error
|
81
|
+
# we raise.
|
82
|
+
def ensure_categories_satisfied!(triggering_method)
|
83
|
+
required_categories = required_scope_categories
|
84
|
+
missing_categories = required_categories - satisfied_scope_categories
|
85
|
+
|
86
|
+
if missing_categories.length > 0
|
87
|
+
# We return a special exception for the category +:base+, because we want to give a simpler, cleaner error
|
88
|
+
# message for users who are just using the #base_scope_required! syntactic sugar instead of the full categories
|
89
|
+
# system.
|
90
|
+
# $stderr.puts "RAISING AT: #{caller.join("\n ")}"
|
91
|
+
if missing_categories == [ :base ]
|
92
|
+
raise RequiredScopes::Errors::BaseScopeNotSatisfiedError.new(klass, self, triggering_method)
|
93
|
+
else
|
94
|
+
raise RequiredScopes::Errors::RequiredScopeCategoriesNotSatisfiedError.new(
|
95
|
+
klass, self, triggering_method, required_categories, satisfied_scope_categories)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Override certain key methods in ActiveRecord::Relation to make sure they check for category satisfaction before
|
101
|
+
# running.
|
102
|
+
[ :exec_queries, :perform_calculation, :update_all, :delete_all, :exists?, :pluck ].each do |method_name|
|
103
|
+
method_base_name = method_name
|
104
|
+
method_suffix = ""
|
105
|
+
|
106
|
+
if method_base_name.to_s =~ /^(.*?)([\?\!])$/
|
107
|
+
method_base_name = $1
|
108
|
+
method_suffix = $2
|
109
|
+
end
|
110
|
+
|
111
|
+
with_name = "#{method_base_name}_with_scope_categories_check#{method_suffix}"
|
112
|
+
without_name = "#{method_base_name}_without_scope_categories_check#{method_suffix}"
|
113
|
+
|
114
|
+
define_method(with_name) do |*args, &block|
|
115
|
+
ensure_categories_satisfied!(method_name) unless RequiredScopes::ActiveRecord::VersionCompatibility.is_association_relation?(self)
|
116
|
+
send(without_name, *args, &block)
|
117
|
+
end
|
118
|
+
|
119
|
+
alias_method_chain method_name, :scope_categories_check
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
module RequiredScopes
|
2
|
+
module ActiveRecord
|
3
|
+
module VersionCompatibility
|
4
|
+
class << self
|
5
|
+
delegate :is_association_relation?, :supports_references_method?, :apply_version_specific_fixes!,
|
6
|
+
:supports_find_by?, :relation_method_for_ignoring_scopes, :supports_load?, :supports_take?,
|
7
|
+
:supports_ids?, :supports_spawn?, :supports_bang_methods?, :supports_references?,
|
8
|
+
:supports_unscope?, :supports_none?, :supports_distinct?, :to => :impl
|
9
|
+
|
10
|
+
private
|
11
|
+
def impl
|
12
|
+
@impl ||= if ::ActiveRecord::VERSION::MAJOR == 4
|
13
|
+
ActiveRecord4.new
|
14
|
+
elsif ::ActiveRecord::VERSION::MAJOR == 3
|
15
|
+
ActiveRecord3.new
|
16
|
+
else
|
17
|
+
raise "RequiredScopes does not support ActiveRecord version #{ActiveRecord::VERSION::STRING} currently."
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class ActiveRecord4
|
23
|
+
def is_association_relation?(relation)
|
24
|
+
relation.kind_of?(::ActiveRecord::AssociationRelation)
|
25
|
+
end
|
26
|
+
|
27
|
+
def supports_references_method?
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
def apply_version_specific_fixes!
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
def supports_find_by?
|
36
|
+
true
|
37
|
+
end
|
38
|
+
|
39
|
+
def supports_load?
|
40
|
+
true
|
41
|
+
end
|
42
|
+
|
43
|
+
def supports_take?
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
def supports_ids?
|
48
|
+
true
|
49
|
+
end
|
50
|
+
|
51
|
+
def supports_spawn?
|
52
|
+
true
|
53
|
+
end
|
54
|
+
|
55
|
+
def supports_bang_methods?
|
56
|
+
true
|
57
|
+
end
|
58
|
+
|
59
|
+
def supports_references?
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
63
|
+
def supports_unscope?
|
64
|
+
true
|
65
|
+
end
|
66
|
+
|
67
|
+
def supports_none?
|
68
|
+
true
|
69
|
+
end
|
70
|
+
|
71
|
+
def supports_distinct?
|
72
|
+
true
|
73
|
+
end
|
74
|
+
|
75
|
+
def relation_method_for_ignoring_scopes
|
76
|
+
:all
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class ActiveRecord3
|
81
|
+
def is_association_relation?(relation)
|
82
|
+
false
|
83
|
+
end
|
84
|
+
|
85
|
+
def supports_references_method?
|
86
|
+
false
|
87
|
+
end
|
88
|
+
|
89
|
+
def apply_version_specific_fixes!
|
90
|
+
::ActiveRecord::Associations::Association.class_eval do
|
91
|
+
def target_scope_with_required_scopes_removed
|
92
|
+
out = target_scope_without_required_scopes_removed
|
93
|
+
out.all_scope_categories_satisfied!
|
94
|
+
out
|
95
|
+
end
|
96
|
+
|
97
|
+
alias_method_chain :target_scope, :required_scopes_removed
|
98
|
+
end
|
99
|
+
|
100
|
+
::ActiveRecord::Base.class_eval do
|
101
|
+
def destroy_with_required_scopes_removed
|
102
|
+
self.class.all_scope_categories_satisfied do
|
103
|
+
destroy_without_required_scopes_removed
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
alias_method_chain :destroy, :required_scopes_removed
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def supports_find_by?
|
112
|
+
false
|
113
|
+
end
|
114
|
+
|
115
|
+
def supports_load?
|
116
|
+
false
|
117
|
+
end
|
118
|
+
|
119
|
+
def supports_take?
|
120
|
+
false
|
121
|
+
end
|
122
|
+
|
123
|
+
def supports_ids?
|
124
|
+
false
|
125
|
+
end
|
126
|
+
|
127
|
+
def supports_spawn?
|
128
|
+
false
|
129
|
+
end
|
130
|
+
|
131
|
+
def supports_bang_methods?
|
132
|
+
false
|
133
|
+
end
|
134
|
+
|
135
|
+
def supports_references?
|
136
|
+
false
|
137
|
+
end
|
138
|
+
|
139
|
+
def supports_unscope?
|
140
|
+
false
|
141
|
+
end
|
142
|
+
|
143
|
+
def supports_none?
|
144
|
+
false
|
145
|
+
end
|
146
|
+
|
147
|
+
def supports_distinct?
|
148
|
+
false
|
149
|
+
end
|
150
|
+
|
151
|
+
def relation_method_for_ignoring_scopes
|
152
|
+
:relation
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module RequiredScopes
|
2
|
+
module Errors
|
3
|
+
# The parent of all errors raised by RequiredScopes.
|
4
|
+
class Base < StandardError; end
|
5
|
+
|
6
|
+
# Raised if you try to execute an operation on a model or relation without having satisfied one or more
|
7
|
+
# scopes.
|
8
|
+
class RequiredScopeCategoriesNotSatisfiedError < Base
|
9
|
+
attr_reader :model_class, :current_relation, :triggering_method, :required_categories, :satisfied_categories, :missing_categories
|
10
|
+
|
11
|
+
def initialize(model_class, current_relation, triggering_method, required_categories, satisfied_categories)
|
12
|
+
@model_class = model_class
|
13
|
+
@current_relation = current_relation
|
14
|
+
@triggering_method = triggering_method
|
15
|
+
@required_categories = required_categories
|
16
|
+
@satisfied_categories = satisfied_categories
|
17
|
+
@missing_categories = @required_categories - @satisfied_categories
|
18
|
+
|
19
|
+
super(build_message)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
def build_message
|
24
|
+
%{Model #{model_class.name} requires that you apply scope(s) satisfying the following
|
25
|
+
categories before you use it: #{missing_categories.sort_by(&:to_s).join(", ")}.
|
26
|
+
|
27
|
+
Satisfy these categories by including scopes in your query that are tagged with
|
28
|
+
:satisfies => <category name>, for each of the categories.}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Raised if you try to execute an operation on a model or relation without having satisfied the base scope.
|
33
|
+
# (We use this instead of RequiredScopeCategoriesNotSatisfiedError, above, simply to make the error message
|
34
|
+
# simpler and more comprehensible to users who only are using the "base scope" syntactic sugar.)
|
35
|
+
class BaseScopeNotSatisfiedError < RequiredScopeCategoriesNotSatisfiedError
|
36
|
+
def initialize(model_class, current_relation, triggering_method)
|
37
|
+
super(model_class, current_relation, triggering_method, [ :base ], [ ])
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
def build_message
|
42
|
+
%{Model #{model_class.name} requires specification of a base scope before using it in a query
|
43
|
+
or other such operation. (Base scopes are those declared with #base_scope rather than just #scope,
|
44
|
+
or class methods that include #base_scope_satisfied.)}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'required_scopes/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "required_scopes"
|
8
|
+
s.version = RequiredScopes::VERSION
|
9
|
+
s.authors = ["Andrew Geweke"]
|
10
|
+
s.email = ["andrew@geweke.org"]
|
11
|
+
s.description = %q{Don't let developers forget about critical scopes for queries.}
|
12
|
+
s.summary = %q{Don't let developers forget about critical scopes for queries.}
|
13
|
+
s.homepage = "https://github.com/ageweke/required_scopes"
|
14
|
+
s.license = "MIT"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split($/)
|
17
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
s.add_development_dependency "rake"
|
23
|
+
s.add_development_dependency "rspec", "~> 2.14"
|
24
|
+
|
25
|
+
if (RUBY_VERSION =~ /^1\.9\./ || RUBY_VERSION =~ /^2\./) && ((! defined?(RUBY_ENGINE)) || (RUBY_ENGINE != 'jruby'))
|
26
|
+
s.add_development_dependency "pry"
|
27
|
+
s.add_development_dependency "pry-debugger"
|
28
|
+
s.add_development_dependency "pry-stack_explorer"
|
29
|
+
end
|
30
|
+
|
31
|
+
ar_version = ENV['REQUIRED_SCOPES_AR_TEST_VERSION']
|
32
|
+
ar_version = ar_version.strip if ar_version
|
33
|
+
|
34
|
+
version_spec = case ar_version
|
35
|
+
when nil then [ ">= 3.0", "<= 4.99.99" ]
|
36
|
+
when 'master' then nil
|
37
|
+
else [ "=#{ar_version}" ]
|
38
|
+
end
|
39
|
+
|
40
|
+
if version_spec
|
41
|
+
s.add_dependency("activerecord", *version_spec)
|
42
|
+
end
|
43
|
+
|
44
|
+
s.add_dependency "activesupport", ">= 3.0", "<= 4.99.99"
|
45
|
+
|
46
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'spec', 'required_scopes', 'helpers', 'database_helper'))
|
47
|
+
database_gem_name = RequiredScopes::Helpers::DatabaseHelper.maybe_database_gem_name
|
48
|
+
|
49
|
+
# Ugh. Later versions of the 'mysql2' gem are incompatible with AR 3.0.x; so, here, we explicitly trap that case
|
50
|
+
# and use an earlier version of that Gem.
|
51
|
+
if database_gem_name && database_gem_name == 'mysql2' && ar_version && ar_version =~ /^3\.0\./
|
52
|
+
s.add_development_dependency('mysql2', '~> 0.2.0')
|
53
|
+
else
|
54
|
+
s.add_development_dependency(database_gem_name)
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
module RequiredScopes
|
2
|
+
module Helpers
|
3
|
+
class DatabaseHelper
|
4
|
+
class InvalidDatabaseConfigurationError < StandardError; end
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def maybe_database_gem_name
|
8
|
+
begin
|
9
|
+
dh = new
|
10
|
+
dh.database_gem_name
|
11
|
+
rescue InvalidDatabaseConfigurationError => idce
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
config # make sure we raise on instantiation if configuration is invalid
|
19
|
+
end
|
20
|
+
|
21
|
+
def database_type
|
22
|
+
case database_gem_name
|
23
|
+
when /mysql/i then :mysql
|
24
|
+
when /sqlite/i then :sqlite
|
25
|
+
when /pg/i, /postgres/i then :postgres
|
26
|
+
else raise "Unknown database type for Gem name: #{database_gem_name.inspect}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def setup_activerecord!
|
31
|
+
require 'active_record'
|
32
|
+
require config[:require]
|
33
|
+
::ActiveRecord::Base.establish_connection(config[:config])
|
34
|
+
|
35
|
+
require 'logger'
|
36
|
+
require 'stringio'
|
37
|
+
@logs = StringIO.new
|
38
|
+
::ActiveRecord::Base.logger = Logger.new(@logs)
|
39
|
+
|
40
|
+
if config[:config][:adapter] == 'sqlite3'
|
41
|
+
sqlite_version = ::ActiveRecord::Base.connection.send(:sqlite_version).instance_variable_get("@version").inspect rescue "unknown"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def table_name(name)
|
46
|
+
"rec_spec_#{name}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def database_gem_name
|
50
|
+
config[:database_gem_name]
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
def config
|
55
|
+
config_from_config_file || travis_ci_config_from_environment || invalid_config_file!
|
56
|
+
end
|
57
|
+
|
58
|
+
def config_from_config_file
|
59
|
+
return nil unless File.exist?(config_file_path)
|
60
|
+
require config_file_path
|
61
|
+
|
62
|
+
return nil unless defined?(REQUIRED_SCOPES_SPEC_DATABASE_CONFIG)
|
63
|
+
return nil unless REQUIRED_SCOPES_SPEC_DATABASE_CONFIG.kind_of?(Hash)
|
64
|
+
|
65
|
+
return nil unless REQUIRED_SCOPES_SPEC_DATABASE_CONFIG[:require]
|
66
|
+
return nil unless REQUIRED_SCOPES_SPEC_DATABASE_CONFIG[:database_gem_name]
|
67
|
+
|
68
|
+
return nil unless REQUIRED_SCOPES_SPEC_DATABASE_CONFIG
|
69
|
+
REQUIRED_SCOPES_SPEC_DATABASE_CONFIG
|
70
|
+
end
|
71
|
+
|
72
|
+
def travis_ci_config_from_environment
|
73
|
+
dbtype = (ENV['REQUIRED_SCOPES_TRAVIS_CI_DATABASE_TYPE'] || '').strip.downcase
|
74
|
+
is_jruby = defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
|
75
|
+
|
76
|
+
if is_jruby
|
77
|
+
case dbtype
|
78
|
+
when 'mysql'
|
79
|
+
{
|
80
|
+
:require => 'activerecord-jdbcmysql-adapter',
|
81
|
+
:database_gem_name => 'activerecord-jdbcmysql-adapter',
|
82
|
+
:config => {
|
83
|
+
:adapter => 'jdbcmysql',
|
84
|
+
:database => 'myapp_test',
|
85
|
+
:username => 'travis',
|
86
|
+
:encoding => 'utf8'
|
87
|
+
}
|
88
|
+
}
|
89
|
+
when 'postgres', 'postgresql'
|
90
|
+
{
|
91
|
+
:require => 'activerecord-jdbcpostgresql-adapter',
|
92
|
+
:database_gem_name => 'activerecord-jdbcpostgresql-adapter',
|
93
|
+
:config => {
|
94
|
+
:adapter => 'jdbcpostgresql',
|
95
|
+
:database => 'myapp_test',
|
96
|
+
:username => 'postgres'
|
97
|
+
}
|
98
|
+
}
|
99
|
+
when 'sqlite'
|
100
|
+
{
|
101
|
+
:require => 'activerecord-jdbcsqlite3-adapter',
|
102
|
+
:database_gem_name => 'activerecord-jdbcsqlite3-adapter',
|
103
|
+
:config => {
|
104
|
+
:adapter => 'jdbcsqlite3',
|
105
|
+
:database => ':memory:'
|
106
|
+
}
|
107
|
+
}
|
108
|
+
when '', nil then nil
|
109
|
+
else
|
110
|
+
raise "Unknown Travis CI database type: #{dbtype.inspect}"
|
111
|
+
end
|
112
|
+
else
|
113
|
+
case dbtype
|
114
|
+
when 'postgres', 'postgresql'
|
115
|
+
{
|
116
|
+
:require => 'pg',
|
117
|
+
:database_gem_name => 'pg',
|
118
|
+
:config => {
|
119
|
+
:adapter => 'postgresql',
|
120
|
+
:database => 'myapp_test',
|
121
|
+
:username => 'postgres',
|
122
|
+
:min_messages => 'WARNING'
|
123
|
+
}
|
124
|
+
}
|
125
|
+
when 'mysql'
|
126
|
+
{
|
127
|
+
:require => 'mysql2',
|
128
|
+
:database_gem_name => 'mysql2',
|
129
|
+
:config => {
|
130
|
+
:adapter => 'mysql2',
|
131
|
+
:database => 'myapp_test',
|
132
|
+
:username => 'travis',
|
133
|
+
:encoding => 'utf8'
|
134
|
+
}
|
135
|
+
}
|
136
|
+
when 'sqlite'
|
137
|
+
{
|
138
|
+
:require => 'sqlite3',
|
139
|
+
:database_gem_name => 'sqlite3',
|
140
|
+
:config => {
|
141
|
+
:adapter => 'sqlite3',
|
142
|
+
:database => ':memory:',
|
143
|
+
:timeout => 500
|
144
|
+
}
|
145
|
+
}
|
146
|
+
when '', nil then nil
|
147
|
+
else
|
148
|
+
raise "Unknown Travis CI database type: #{dbtype.inspect}"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def config_file_path
|
154
|
+
@config_file_path ||= File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'spec_database_config.rb'))
|
155
|
+
end
|
156
|
+
|
157
|
+
def invalid_config_file!
|
158
|
+
raise Errno::ENOENT, %{In order to run specs for required_scopes, you need to create a file at:
|
159
|
+
|
160
|
+
#{config_file_path}
|
161
|
+
|
162
|
+
...that defines a top-level REQUIRED_SCOPES_SPEC_DATABASE_CONFIG hash, with members:
|
163
|
+
|
164
|
+
:require => 'name_of_adapter_to_require',
|
165
|
+
:database_gem_name => 'name_of_gem_for_adapter',
|
166
|
+
:config => { ...whatever ActiveRecord::Base.establish_connection should be passed... }
|
167
|
+
|
168
|
+
Alternatively, if you're running under Travis CI, you can set the environment variable
|
169
|
+
REQUIRED_SCOPES_TRAVIS_CI_DATABASE_TYPE to 'postgres', 'mysql', or 'sqlite', and it will
|
170
|
+
use the correct configuration for testing on Travis CI.}
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|