database_cleaner 1.6.2 → 1.8.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (170) hide show
  1. checksums.yaml +5 -5
  2. data/CONTRIBUTE.markdown +1 -2
  3. data/Gemfile.lock +132 -93
  4. data/History.rdoc +67 -0
  5. data/README.markdown +88 -217
  6. data/Rakefile +12 -8
  7. data/{lib → adapters/database_cleaner-active_record/lib}/database_cleaner/active_record/base.rb +14 -5
  8. data/{lib → adapters/database_cleaner-active_record/lib}/database_cleaner/active_record/deletion.rb +19 -17
  9. data/{lib → adapters/database_cleaner-active_record/lib}/database_cleaner/active_record/truncation.rb +25 -20
  10. data/adapters/database_cleaner-active_record/lib/database_cleaner/active_record/version.rb +5 -0
  11. data/adapters/database_cleaner-active_record/lib/database_cleaner/active_record.rb +6 -0
  12. data/adapters/database_cleaner-active_record/lib/database_cleaner-active_record.rb +1 -0
  13. data/adapters/database_cleaner-couch_potato/lib/database_cleaner/couch_potato/version.rb +5 -0
  14. data/adapters/database_cleaner-couch_potato/lib/database_cleaner/couch_potato.rb +11 -0
  15. data/adapters/database_cleaner-couch_potato/lib/database_cleaner-couch_potato.rb +1 -0
  16. data/{lib → adapters/database_cleaner-data_mapper/lib}/database_cleaner/data_mapper/base.rb +4 -0
  17. data/{lib → adapters/database_cleaner-data_mapper/lib}/database_cleaner/data_mapper/truncation.rb +4 -3
  18. data/adapters/database_cleaner-data_mapper/lib/database_cleaner/data_mapper/version.rb +5 -0
  19. data/adapters/database_cleaner-data_mapper/lib/database_cleaner/data_mapper.rb +4 -0
  20. data/adapters/database_cleaner-data_mapper/lib/database_cleaner-data_mapper.rb +1 -0
  21. data/{lib → adapters/database_cleaner-mongo/lib}/database_cleaner/mongo/truncation.rb +2 -0
  22. data/adapters/database_cleaner-mongo/lib/database_cleaner/mongo/version.rb +5 -0
  23. data/adapters/database_cleaner-mongo/lib/database_cleaner/mongo.rb +10 -0
  24. data/adapters/database_cleaner-mongo/lib/database_cleaner-mongo.rb +1 -0
  25. data/{lib → adapters/database_cleaner-mongo_mapper/lib}/database_cleaner/mongo_mapper/base.rb +4 -0
  26. data/adapters/database_cleaner-mongo_mapper/lib/database_cleaner/mongo_mapper/truncation.rb +35 -0
  27. data/adapters/database_cleaner-mongo_mapper/lib/database_cleaner/mongo_mapper/version.rb +5 -0
  28. data/adapters/database_cleaner-mongo_mapper/lib/database_cleaner/mongo_mapper.rb +4 -0
  29. data/adapters/database_cleaner-mongo_mapper/lib/database_cleaner-mongo_mapper.rb +1 -0
  30. data/adapters/database_cleaner-mongoid/lib/database_cleaner/mongoid/mongo1_truncation_mixin.rb +26 -0
  31. data/{lib/database_cleaner/mongo2/truncation_mixin.rb → adapters/database_cleaner-mongoid/lib/database_cleaner/mongoid/mongo2_truncation_mixin.rb} +3 -4
  32. data/adapters/database_cleaner-mongoid/lib/database_cleaner/mongoid/mongoid_truncation_mixin.rb +65 -0
  33. data/{lib → adapters/database_cleaner-mongoid/lib}/database_cleaner/mongoid/truncation.rb +6 -6
  34. data/adapters/database_cleaner-mongoid/lib/database_cleaner/mongoid/version.rb +5 -0
  35. data/adapters/database_cleaner-mongoid/lib/database_cleaner/mongoid.rb +10 -0
  36. data/adapters/database_cleaner-mongoid/lib/database_cleaner-mongoid.rb +1 -0
  37. data/{lib → adapters/database_cleaner-moped/lib}/database_cleaner/moped/base.rb +1 -1
  38. data/{lib → adapters/database_cleaner-moped/lib}/database_cleaner/moped/truncation_base.rb +4 -0
  39. data/adapters/database_cleaner-moped/lib/database_cleaner/moped/version.rb +5 -0
  40. data/adapters/database_cleaner-moped/lib/database_cleaner/moped.rb +10 -0
  41. data/adapters/database_cleaner-moped/lib/database_cleaner-moped.rb +1 -0
  42. data/{lib → adapters/database_cleaner-neo4j/lib}/database_cleaner/neo4j/base.rb +4 -0
  43. data/adapters/database_cleaner-neo4j/lib/database_cleaner/neo4j/version.rb +5 -0
  44. data/adapters/database_cleaner-neo4j/lib/database_cleaner/neo4j.rb +6 -0
  45. data/adapters/database_cleaner-neo4j/lib/database_cleaner-neo4j.rb +1 -0
  46. data/adapters/database_cleaner-ohm/lib/database_cleaner/ohm/truncation.rb +24 -0
  47. data/adapters/database_cleaner-ohm/lib/database_cleaner/ohm/version.rb +5 -0
  48. data/adapters/database_cleaner-ohm/lib/database_cleaner/ohm.rb +12 -0
  49. data/adapters/database_cleaner-ohm/lib/database_cleaner-ohm.rb +1 -0
  50. data/{lib → adapters/database_cleaner-redis/lib}/database_cleaner/redis/base.rb +4 -0
  51. data/adapters/database_cleaner-redis/lib/database_cleaner/redis/version.rb +5 -0
  52. data/adapters/database_cleaner-redis/lib/database_cleaner/redis.rb +4 -0
  53. data/adapters/database_cleaner-redis/lib/database_cleaner-redis.rb +1 -0
  54. data/{lib → adapters/database_cleaner-sequel/lib}/database_cleaner/sequel/base.rb +4 -0
  55. data/{lib → adapters/database_cleaner-sequel/lib}/database_cleaner/sequel/truncation.rb +16 -15
  56. data/adapters/database_cleaner-sequel/lib/database_cleaner/sequel/version.rb +5 -0
  57. data/adapters/database_cleaner-sequel/lib/database_cleaner/sequel.rb +6 -0
  58. data/adapters/database_cleaner-sequel/lib/database_cleaner-sequel.rb +1 -0
  59. data/lib/database_cleaner/base.rb +94 -105
  60. data/lib/database_cleaner/configuration.rb +87 -83
  61. data/lib/database_cleaner/deprecation.rb +26 -0
  62. data/lib/database_cleaner/null_strategy.rb +6 -6
  63. data/lib/database_cleaner/orm_autodetector.rb +41 -0
  64. data/lib/database_cleaner/safeguard.rb +107 -0
  65. data/lib/database_cleaner/spec/database_helper.rb +82 -0
  66. data/lib/database_cleaner/spec/shared_examples.rb +15 -0
  67. data/lib/database_cleaner/spec.rb +2 -0
  68. data/lib/database_cleaner/version.rb +3 -0
  69. data/lib/database_cleaner.rb +41 -2
  70. metadata +113 -126
  71. data/VERSION.yml +0 -4
  72. data/examples/Gemfile +0 -1
  73. data/examples/Gemfile.lock +0 -1
  74. data/examples/config/database.yml.example +0 -8
  75. data/examples/config/redis.yml +0 -8
  76. data/examples/db/sqlite_databases_go_here +0 -0
  77. data/examples/features/example.feature +0 -11
  78. data/examples/features/example_multiple_db.feature +0 -23
  79. data/examples/features/example_multiple_orm.feature +0 -22
  80. data/examples/features/step_definitions/activerecord_steps.rb +0 -31
  81. data/examples/features/step_definitions/couchpotato_steps.rb +0 -31
  82. data/examples/features/step_definitions/datamapper_steps.rb +0 -37
  83. data/examples/features/step_definitions/mongoid_steps.rb +0 -23
  84. data/examples/features/step_definitions/mongomapper_steps.rb +0 -31
  85. data/examples/features/step_definitions/neo4j_steps.rb +0 -23
  86. data/examples/features/step_definitions/ohm_steps.rb +0 -31
  87. data/examples/features/step_definitions/redis_steps.rb +0 -31
  88. data/examples/features/step_definitions/translation_steps.rb +0 -55
  89. data/examples/features/support/env.rb +0 -61
  90. data/examples/lib/activerecord_models.rb +0 -41
  91. data/examples/lib/couchpotato_models.rb +0 -61
  92. data/examples/lib/datamapper_models.rb +0 -50
  93. data/examples/lib/mongoid_models.rb +0 -44
  94. data/examples/lib/mongomapper_models.rb +0 -51
  95. data/examples/lib/neo4j_models.rb +0 -17
  96. data/examples/lib/ohm_models.rb +0 -43
  97. data/examples/lib/redis_models.rb +0 -65
  98. data/examples/lib/sequel_models.rb +0 -9
  99. data/features/cleaning.feature +0 -30
  100. data/features/cleaning_default_strategy.feature +0 -23
  101. data/features/cleaning_multiple_dbs.feature +0 -22
  102. data/features/cleaning_multiple_orms.feature +0 -67
  103. data/features/step_definitions/database_cleaner_steps.rb +0 -33
  104. data/features/support/env.rb +0 -4
  105. data/features/support/feature_runner.rb +0 -39
  106. data/lib/database_cleaner/mongo2/base.rb +0 -16
  107. data/lib/database_cleaner/mongo_mapper/truncation.rb +0 -19
  108. data/lib/database_cleaner/ohm/truncation.rb +0 -15
  109. data/spec/database_cleaner/active_record/base_spec.rb +0 -188
  110. data/spec/database_cleaner/active_record/transaction_spec.rb +0 -176
  111. data/spec/database_cleaner/active_record/truncation/mysql2_spec.rb +0 -38
  112. data/spec/database_cleaner/active_record/truncation/mysql_spec.rb +0 -38
  113. data/spec/database_cleaner/active_record/truncation/postgresql_spec.rb +0 -75
  114. data/spec/database_cleaner/active_record/truncation/shared_fast_truncation.rb +0 -40
  115. data/spec/database_cleaner/active_record/truncation/sqlite3_spec.rb +0 -40
  116. data/spec/database_cleaner/active_record/truncation_spec.rb +0 -180
  117. data/spec/database_cleaner/base_spec.rb +0 -617
  118. data/spec/database_cleaner/configuration_spec.rb +0 -345
  119. data/spec/database_cleaner/couch_potato/truncation_spec.rb +0 -41
  120. data/spec/database_cleaner/data_mapper/base_spec.rb +0 -30
  121. data/spec/database_cleaner/data_mapper/transaction_spec.rb +0 -23
  122. data/spec/database_cleaner/data_mapper/truncation/sqlite3_spec.rb +0 -41
  123. data/spec/database_cleaner/data_mapper/truncation_spec.rb +0 -11
  124. data/spec/database_cleaner/generic/base_spec.rb +0 -61
  125. data/spec/database_cleaner/generic/truncation_spec.rb +0 -118
  126. data/spec/database_cleaner/mongo/mongo_examples.rb +0 -26
  127. data/spec/database_cleaner/mongo/truncation_spec.rb +0 -72
  128. data/spec/database_cleaner/mongo_mapper/base_spec.rb +0 -33
  129. data/spec/database_cleaner/mongo_mapper/mongo_examples.rb +0 -8
  130. data/spec/database_cleaner/mongo_mapper/truncation_spec.rb +0 -74
  131. data/spec/database_cleaner/moped/moped_examples.rb +0 -32
  132. data/spec/database_cleaner/moped/truncation_spec.rb +0 -80
  133. data/spec/database_cleaner/neo4j/base_spec.rb +0 -43
  134. data/spec/database_cleaner/neo4j/transaction_spec.rb +0 -25
  135. data/spec/database_cleaner/null_strategy_spec.rb +0 -28
  136. data/spec/database_cleaner/ohm/truncation_spec.rb +0 -70
  137. data/spec/database_cleaner/redis/base_spec.rb +0 -43
  138. data/spec/database_cleaner/redis/truncation_spec.rb +0 -63
  139. data/spec/database_cleaner/sequel/base_spec.rb +0 -32
  140. data/spec/database_cleaner/sequel/deletion_spec.rb +0 -58
  141. data/spec/database_cleaner/sequel/transaction_spec.rb +0 -21
  142. data/spec/database_cleaner/sequel/truncation/sqlite3_spec.rb +0 -0
  143. data/spec/database_cleaner/sequel/truncation_spec.rb +0 -182
  144. data/spec/database_cleaner/shared_strategy.rb +0 -15
  145. data/spec/rcov.opts +0 -1
  146. data/spec/spec_helper.rb +0 -21
  147. data/spec/support/active_record/database_setup.rb +0 -6
  148. data/spec/support/active_record/migrations/20150101010000_create_users.rb +0 -14
  149. data/spec/support/active_record/migrations/20150101020000_create_agents.rb +0 -14
  150. data/spec/support/active_record/mysql2_setup.rb +0 -39
  151. data/spec/support/active_record/mysql_setup.rb +0 -38
  152. data/spec/support/active_record/postgresql_setup.rb +0 -48
  153. data/spec/support/active_record/schema_setup.rb +0 -17
  154. data/spec/support/active_record/sqlite3_setup.rb +0 -40
  155. data/spec/support/data_mapper/schema_setup.rb +0 -15
  156. data/spec/support/data_mapper/sqlite3_setup.rb +0 -39
  157. /data/{lib → adapters/database_cleaner-active_record/lib}/database_cleaner/active_record/transaction.rb +0 -0
  158. /data/{lib → adapters/database_cleaner-couch_potato/lib}/database_cleaner/couch_potato/base.rb +0 -0
  159. /data/{lib → adapters/database_cleaner-couch_potato/lib}/database_cleaner/couch_potato/truncation.rb +0 -0
  160. /data/{lib → adapters/database_cleaner-data_mapper/lib}/database_cleaner/data_mapper/transaction.rb +0 -0
  161. /data/{lib → adapters/database_cleaner-mongo/lib}/database_cleaner/mongo/base.rb +0 -0
  162. /data/{lib → adapters/database_cleaner-mongo/lib}/database_cleaner/mongo/truncation_mixin.rb +0 -0
  163. /data/{lib → adapters/database_cleaner-mongoid/lib}/database_cleaner/mongoid/base.rb +0 -0
  164. /data/{lib → adapters/database_cleaner-moped/lib}/database_cleaner/moped/truncation.rb +0 -0
  165. /data/{lib → adapters/database_cleaner-neo4j/lib}/database_cleaner/neo4j/deletion.rb +0 -0
  166. /data/{lib → adapters/database_cleaner-neo4j/lib}/database_cleaner/neo4j/transaction.rb +0 -0
  167. /data/{lib → adapters/database_cleaner-neo4j/lib}/database_cleaner/neo4j/truncation.rb +0 -0
  168. /data/{lib → adapters/database_cleaner-redis/lib}/database_cleaner/redis/truncation.rb +0 -0
  169. /data/{lib → adapters/database_cleaner-sequel/lib}/database_cleaner/sequel/deletion.rb +0 -0
  170. /data/{lib → adapters/database_cleaner-sequel/lib}/database_cleaner/sequel/transaction.rb +0 -0
@@ -1,164 +1,153 @@
1
+ require 'database_cleaner/deprecation'
1
2
  require 'database_cleaner/null_strategy'
3
+ require 'database_cleaner/safeguard'
4
+ require 'database_cleaner/orm_autodetector'
5
+ require 'forwardable'
6
+
2
7
  module DatabaseCleaner
3
8
  class Base
4
9
  include Comparable
5
10
 
6
11
  def <=>(other)
7
- (self.orm <=> other.orm) == 0 ? self.db <=> other.db : self.orm <=> other.orm
12
+ [orm, db] <=> [other.orm, other.db]
8
13
  end
9
14
 
10
- def initialize(desired_orm = nil,opts = {})
11
- if [:autodetect, nil, "autodetect"].include?(desired_orm)
12
- autodetect
13
- else
14
- self.orm = desired_orm
15
- end
15
+ def initialize(desired_orm = nil, opts = {})
16
+ @orm_autodetector = ORMAutodetector.new
17
+ self.orm = desired_orm
16
18
  self.db = opts[:connection] || opts[:model] if opts.has_key?(:connection) || opts.has_key?(:model)
17
- set_default_orm_strategy
19
+ self.strategy = orm_module && orm_module.default_strategy
20
+ Safeguard.new.run
18
21
  end
19
22
 
20
23
  def db=(desired_db)
21
- self.strategy_db = desired_db
22
- @db = desired_db
23
- end
24
-
25
- def strategy_db=(desired_db)
26
- if strategy.respond_to? :db=
27
- strategy.db = desired_db
28
- elsif desired_db!= :default
29
- raise ArgumentError, "You must provide a strategy object that supports non default databases when you specify a database"
30
- end
24
+ @db = self.strategy_db = desired_db
31
25
  end
32
26
 
33
27
  def db
34
28
  @db ||= :default
35
29
  end
36
30
 
37
- def create_strategy(*args)
31
+ def strategy=(args)
38
32
  strategy, *strategy_args = args
39
- orm_strategy(strategy).new(*strategy_args)
40
- end
33
+ @strategy = if strategy.is_a?(Symbol)
34
+ create_strategy(*args)
35
+ elsif strategy_args.empty?
36
+ strategy
37
+ else
38
+ raise ArgumentError, "You must provide a strategy object, or a symbol for a known strategy along with initialization params."
39
+ end
41
40
 
42
- def clean_with(*args)
43
- strategy = create_strategy(*args)
44
- set_strategy_db strategy, self.db
41
+ set_strategy_db @strategy, db
42
+ end
45
43
 
46
- strategy.clean
47
- strategy
44
+ def strategy
45
+ @strategy ||= NullStrategy.new
48
46
  end
49
47
 
50
- alias clean_with! clean_with
48
+ attr_reader :orm
51
49
 
52
- def set_strategy_db(strategy, desired_db)
53
- if strategy.respond_to? :db=
54
- strategy.db = desired_db
55
- elsif desired_db != :default
56
- raise ArgumentError, "You must provide a strategy object that supports non default databases when you specify a database"
57
- end
50
+ def orm=(desired_orm)
51
+ @orm = (desired_orm || :autodetect).to_sym
52
+ @orm = @orm_autodetector.orm if @orm == :autodetect
58
53
  end
59
54
 
60
- def strategy=(args)
61
- strategy, *strategy_args = args
62
- if strategy.is_a?(Symbol)
63
- @strategy = create_strategy(*args)
64
- elsif strategy_args.empty?
65
- @strategy = strategy
66
- else
67
- raise ArgumentError, "You must provide a strategy object, or a symbol for a known strategy along with initialization params."
68
- end
55
+ extend Forwardable
56
+ delegate [:start, :clean, :cleaning] => :strategy
69
57
 
70
- set_strategy_db @strategy, self.db
71
-
72
- @strategy
58
+ def clean_with(*args)
59
+ strategy = create_strategy(*args)
60
+ set_strategy_db strategy, db
61
+ strategy.clean
62
+ strategy
73
63
  end
74
64
 
75
- def strategy
76
- @strategy ||= NullStrategy
77
- end
65
+ # TODO remove the following methods in 2.0
78
66
 
79
- def orm=(desired_orm)
80
- @orm = desired_orm.to_sym
67
+ def auto_detected?
68
+ DatabaseCleaner.deprecate "Calling `DatabaseCleaner[...].auto_detected?` is deprecated, and will be removed in database_cleaner 2.0 with no replacement."
69
+ @orm_autodetector.autodetected?
81
70
  end
82
71
 
83
- def orm
84
- @orm || autodetect
72
+ def autodetect_orm
73
+ DatabaseCleaner.deprecate "Calling `DatabaseCleaner[...].autodetect_orm` is deprecated, and will be removed in database_cleaner 2.0 with no replacement."
74
+ @orm_autodetector.orm
85
75
  end
86
76
 
87
- def start
88
- strategy.start
77
+ def clean!
78
+ DatabaseCleaner.deprecate "Calling `DatabaseCleaner[...].clean!` is deprecated, and will be removed in database_cleaner 2.0. Use `DatabaseCleaner[...].clean instead."
79
+ clean
89
80
  end
90
81
 
91
- def clean
92
- strategy.clean
82
+ def clean_with!
83
+ DatabaseCleaner.deprecate "Calling `DatabaseCleaner[...].clean_with!` is deprecated, and will be removed in database_cleaner 2.0. Use `DatabaseCleaner[...].clean_with instead."
84
+ clean_with
93
85
  end
94
86
 
95
- alias clean! clean
87
+ # TODO privatize the following methods in 2.0
96
88
 
97
- def cleaning(&block)
98
- strategy.cleaning(&block)
89
+ def strategy_db=(desired_db)
90
+ if DatabaseCleaner.called_externally?(__FILE__, caller)
91
+ DatabaseCleaner.deprecate "Calling `DatabaseCleaner[...].strategy_db=` is deprecated, and will be removed in database_cleaner 2.0. Use `DatabaseCleaner[...].db=` instead."
92
+ end
93
+ set_strategy_db(strategy, desired_db)
99
94
  end
100
95
 
101
- def auto_detected?
102
- !!@autodetected
96
+ def set_strategy_db(strategy, desired_db)
97
+ if DatabaseCleaner.called_externally?(__FILE__, caller)
98
+ DatabaseCleaner.deprecate "Calling `DatabaseCleaner[...].set_strategy_db=` is deprecated, and will be removed in database_cleaner 2.0. Use `DatabaseCleaner[...].db=` instead."
99
+ end
100
+ if strategy.respond_to? :db=
101
+ strategy.db = desired_db
102
+ elsif desired_db != :default
103
+ raise ArgumentError, "You must provide a strategy object that supports non default databases when you specify a database"
104
+ end
103
105
  end
104
106
 
105
- def autodetect_orm
106
- if defined? ::ActiveRecord
107
- :active_record
108
- elsif defined? ::DataMapper
109
- :data_mapper
110
- elsif defined? ::MongoMapper
111
- :mongo_mapper
112
- elsif defined? ::Mongoid
113
- :mongoid
114
- elsif defined? ::CouchPotato
115
- :couch_potato
116
- elsif defined? ::Sequel
117
- :sequel
118
- elsif defined? ::Moped
119
- :moped
120
- elsif defined? ::Ohm
121
- :ohm
122
- elsif defined? ::Redis
123
- :redis
124
- elsif defined? ::Neo4j
125
- :neo4j
107
+ def create_strategy(*args)
108
+ if DatabaseCleaner.called_externally?(__FILE__, caller)
109
+ DatabaseCleaner.deprecate "Calling `DatabaseCleaner[...].create_strategy` is deprecated, and will be removed in database_cleaner 2.0. Use `DatabaseCleaner[...].strategy=` instead."
126
110
  end
111
+ strategy, *strategy_args = args
112
+ orm_strategy(strategy).new(*strategy_args)
127
113
  end
128
114
 
129
115
  private
130
116
 
131
117
  def orm_module
132
- ::DatabaseCleaner.orm_module(orm)
118
+ return unless [:active_record, :data_mapper, :mongo, :mongoid, :mongo_mapper, :moped, :couch_potato, :sequel, :ohm, :redis, :neo4j].include?(orm)
119
+ load_adapter(orm) if !adapter_loaded?(orm)
120
+ orm_module_name = ORMAutodetector::ORMS[orm]
121
+ DatabaseCleaner.const_get(orm_module_name, false)
133
122
  end
134
123
 
135
- def orm_strategy(strategy)
136
- require "database_cleaner/#{orm.to_s}/#{strategy.to_s}"
137
- orm_module.const_get(strategy.to_s.capitalize)
138
- rescue LoadError
139
- if orm_module.respond_to? :available_strategies
140
- raise UnknownStrategySpecified, "The '#{strategy}' strategy does not exist for the #{orm} ORM! Available strategies: #{orm_module.available_strategies.join(', ')}"
141
- else
142
- raise UnknownStrategySpecified, "The '#{strategy}' strategy does not exist for the #{orm} ORM!"
143
- end
124
+ def adapter_loaded? orm
125
+ $LOADED_FEATURES.grep(%r{/lib/database_cleaner/#{orm}\.rb$}).any?
144
126
  end
145
127
 
146
- def autodetect
147
- @autodetected = true
148
-
149
- @orm ||= autodetect_orm ||
150
- raise(NoORMDetected, "No known ORM was detected! Is ActiveRecord, DataMapper, Sequel, MongoMapper, Mongoid, Moped, or CouchPotato, Redis or Ohm loaded?")
128
+ def load_adapter orm
129
+ $LOAD_PATH.unshift File.expand_path("#{File.dirname(__FILE__)}/../../adapters/database_cleaner-#{orm}/lib")
130
+ require "database_cleaner/#{orm}"
151
131
  end
152
132
 
153
- def set_default_orm_strategy
154
- case orm
155
- when :active_record, :data_mapper, :sequel
156
- self.strategy = :transaction
157
- when :mongo_mapper, :mongoid, :couch_potato, :moped, :ohm, :redis
158
- self.strategy = :truncation
159
- when :neo4j
160
- self.strategy = :transaction
133
+ def orm_strategy(strategy)
134
+ strategy_module_name = strategy.to_s.capitalize
135
+ orm_module.const_get(strategy_module_name, false)
136
+ rescue NameError
137
+ if orm != :active_record
138
+ DatabaseCleaner.deprecate <<-TEXT
139
+ The #{orm_module} adapter has been extracted to its own gem: database_cleaner-#{orm}, and will be removed from database_cleaner in 2.0. To silence this message, please replace `gem "database_cleaner"` with `gem "database_cleaner-#{orm}"` in your Gemfile.
140
+ TEXT
161
141
  end
142
+ require_orm_strategy(orm, strategy)
143
+ retry
144
+ end
145
+
146
+ def require_orm_strategy(orm, strategy)
147
+ $LOAD_PATH.unshift File.expand_path("#{File.dirname(__FILE__)}/../../adapters/database_cleaner-#{orm}/lib")
148
+ require "database_cleaner/#{orm}/#{strategy}"
149
+ rescue LoadError
150
+ raise UnknownStrategySpecified, "The '#{strategy}' strategy does not exist for the #{orm} ORM! Available strategies: #{orm_module.available_strategies.join(', ')}"
162
151
  end
163
152
  end
164
153
  end
@@ -1,74 +1,77 @@
1
1
  require 'database_cleaner/base'
2
+ require 'database_cleaner/deprecation'
3
+ require 'forwardable'
2
4
 
3
5
  module DatabaseCleaner
4
6
 
5
- class NoORMDetected < StandardError; end
6
- class UnknownStrategySpecified < ArgumentError; end
7
+ class NoORMDetected < StandardError; end
8
+ class UnknownStrategySpecified < ArgumentError; end
7
9
 
8
- class << self
9
- def init_cleaners
10
- @cleaners ||= {}
11
- # ghetto ordered hash.. maintains 1.8 compat and old API
12
- @connections ||= []
13
- end
14
-
15
- def [](orm,opts = {})
10
+ class Cleaners < Hash
11
+ # FIXME this method conflates creation with lookup... both a command and a query. yuck.
12
+ def [](orm, opts = {})
16
13
  raise NoORMDetected unless orm
17
- init_cleaners
18
- # TODO: deprecate
19
- # this method conflates creation with lookup. Both a command and a query. Yuck.
20
- if @cleaners.has_key? [orm, opts]
21
- @cleaners[[orm, opts]]
22
- else
23
- add_cleaner(orm, opts)
24
- end
25
- end
14
+ fetch([orm, opts]) { add_cleaner(orm, opts) }
15
+ end
26
16
 
27
- def add_cleaner(orm,opts = {})
28
- init_cleaners
29
- cleaner = DatabaseCleaner::Base.new(orm,opts)
30
- @cleaners[[orm, opts]] = cleaner
31
- @connections << cleaner
32
- cleaner
17
+ def strategy=(strategy)
18
+ add_cleaner(:autodetect) if none?
19
+ values.each { |cleaner| cleaner.strategy = strategy }
20
+ remove_duplicates
33
21
  end
34
22
 
35
- def app_root=(desired_root)
36
- @app_root = desired_root
23
+ def orm=(orm)
24
+ add_cleaner(:autodetect) if none?
25
+ values.each { |cleaner| cleaner.orm = orm }
26
+ remove_duplicates
37
27
  end
38
28
 
39
- def app_root
40
- @app_root ||= Dir.pwd
29
+ # TODO privatize the following methods in 2.0
30
+
31
+ def add_cleaner(orm, opts = {})
32
+ self[[orm, opts]] = ::DatabaseCleaner::Base.new(orm, opts)
41
33
  end
42
34
 
43
- def connections
44
- # double yuck.. can't wait to deprecate this whole class...
45
- unless defined?(@cleaners) && @cleaners
46
- autodetected = ::DatabaseCleaner::Base.new
47
- add_cleaner(autodetected.orm)
48
- end
49
- @connections
35
+ def remove_duplicates
36
+ replace(reduce(Cleaners.new) do |cleaners, (key, value)|
37
+ cleaners[key] = value unless cleaners.values.include?(value)
38
+ cleaners
39
+ end)
50
40
  end
41
+ end
51
42
 
52
- def logger=(log_source)
53
- @logger = log_source
43
+ class Configuration
44
+ def initialize
45
+ @cleaners ||= Cleaners.new
54
46
  end
55
47
 
56
- def logger
57
- return @logger if @logger
48
+ extend Forwardable
49
+ delegate [
50
+ :[],
51
+ :strategy=,
52
+ :orm=,
53
+ ] => :cleaners
58
54
 
59
- @logger = Logger.new(STDOUT)
60
- @logger.level = Logger::ERROR
61
- @logger
55
+ attr_accessor :cleaners
56
+
57
+ def app_root
58
+ DatabaseCleaner.deprecate "Calling `DatabaseCleaner.app_root` is deprecated, and will be removed in database_cleaner 2.0. Use `DatabaseCleaner::ActiveRecord.config_file_location`, instead."
59
+ @app_root ||= Dir.pwd
62
60
  end
63
61
 
64
- def strategy=(stratagem)
65
- connections.each { |connect| connect.strategy = stratagem }
66
- remove_duplicates
62
+ def app_root= value
63
+ DatabaseCleaner.deprecate "Calling `DatabaseCleaner.app_root=` is deprecated, and will be removed in database_cleaner 2.0. Use `DatabaseCleaner::ActiveRecord.config_file_location=`, instead."
64
+ @app_root = value
67
65
  end
68
66
 
69
- def orm=(orm)
70
- connections.each { |connect| connect.orm = orm }
71
- remove_duplicates
67
+ def logger
68
+ DatabaseCleaner.deprecate "Calling `DatabaseCleaner.logger` is deprecated, and will be removed in database_cleaner 2.0 with no replacement."
69
+ @logger ||= Logger.new(STDOUT).tap { |l| l.level = Logger::ERROR }
70
+ end
71
+
72
+ def logger= value
73
+ DatabaseCleaner.deprecate "Calling `DatabaseCleaner.logger=` is deprecated, and will be removed in database_cleaner 2.0 with no replacement."
74
+ @logger = value
72
75
  end
73
76
 
74
77
  def start
@@ -79,8 +82,6 @@ module DatabaseCleaner
79
82
  connections.each { |connection| connection.clean }
80
83
  end
81
84
 
82
- alias clean! clean
83
-
84
85
  def cleaning(&inner_block)
85
86
  connections.inject(inner_block) do |curr_block, connection|
86
87
  proc { connection.cleaning(&curr_block) }
@@ -91,41 +92,44 @@ module DatabaseCleaner
91
92
  connections.each { |connection| connection.clean_with(*args) }
92
93
  end
93
94
 
94
- alias clean_with! clean_with
95
+ # TODO remove the following methods in 2.0
95
96
 
96
- def remove_duplicates
97
- temp = []
98
- connections.each do |connect|
99
- temp.push connect unless temp.include? connect
97
+ def clean!
98
+ DatabaseCleaner.deprecate "Calling `DatabaseCleaner.clean!` is deprecated, and will be removed in database_cleaner 2.0. Use `DatabaseCleaner.clean`, instead."
99
+ clean
100
+ end
101
+
102
+ def clean_with!(*args)
103
+ DatabaseCleaner.deprecate "Calling `DatabaseCleaner.clean_with!` is deprecated, and will be removed in database_cleaner 2.0. Use `DatabaseCleaner.clean_with`, instead."
104
+ clean_with(*args)
105
+ end
106
+
107
+ def init_cleaners
108
+ DatabaseCleaner.deprecate "Calling `DatabaseCleaner.init_cleaners` is deprecated, and will be removed in database_cleaner 2.0 with no replacement."
109
+ end
110
+
111
+ def connections
112
+ if DatabaseCleaner.called_externally?(__FILE__, caller)
113
+ DatabaseCleaner.deprecate "Calling `DatabaseCleaner.connections` is deprecated, and will be removed in database_cleaner 2.0. Use `DatabaseCleaner.cleaners`, instead."
114
+ end
115
+ add_cleaner(:autodetect) if @cleaners.none?
116
+ @cleaners.values
117
+ end
118
+
119
+ # TODO privatize the following methods in 2.0
120
+
121
+ def add_cleaner(orm, opts = {})
122
+ if DatabaseCleaner.called_externally?(__FILE__, caller)
123
+ DatabaseCleaner.deprecate "Calling `DatabaseCleaner.add_cleaner` is deprecated, and will be removed in database_cleaner 2.0. Use `DatabaseCleaner.[]`, instead."
100
124
  end
101
- @connections = temp
102
- end
103
-
104
- def orm_module(symbol)
105
- case symbol
106
- when :active_record
107
- DatabaseCleaner::ActiveRecord
108
- when :data_mapper
109
- DatabaseCleaner::DataMapper
110
- when :mongo
111
- DatabaseCleaner::Mongo
112
- when :mongoid
113
- DatabaseCleaner::Mongoid
114
- when :mongo_mapper
115
- DatabaseCleaner::MongoMapper
116
- when :moped
117
- DatabaseCleaner::Moped
118
- when :couch_potato
119
- DatabaseCleaner::CouchPotato
120
- when :sequel
121
- DatabaseCleaner::Sequel
122
- when :ohm
123
- DatabaseCleaner::Ohm
124
- when :redis
125
- DatabaseCleaner::Redis
126
- when :neo4j
127
- DatabaseCleaner::Neo4j
125
+ @cleaners.add_cleaner(orm, opts = {})
126
+ end
127
+
128
+ def remove_duplicates
129
+ if DatabaseCleaner.called_externally?(__FILE__, caller)
130
+ DatabaseCleaner.deprecate "Calling `DatabaseCleaner.remove_duplicates` is deprecated, and will be removed in database_cleaner 2.0 with no replacement."
128
131
  end
132
+ @cleaners.remove_duplicates
129
133
  end
130
134
  end
131
135
  end
@@ -0,0 +1,26 @@
1
+ module DatabaseCleaner
2
+ def deprecate message
3
+ method = caller.first[/\d+:in `(.*)'$/, 1].to_sym
4
+ @@deprecator ||= Deprecator.new
5
+ @@deprecator.deprecate method, message
6
+ end
7
+ module_function :deprecate
8
+
9
+ def called_externally?(file, caller)
10
+ file != caller.first[/^(.+\.rb):\d+/, 1]
11
+ end
12
+ module_function :called_externally?
13
+
14
+ class Deprecator
15
+ def initialize
16
+ @methods_already_warned = {}
17
+ end
18
+
19
+ def deprecate method, message
20
+ return if @methods_already_warned.key?(method)
21
+ $stderr.puts message
22
+ @methods_already_warned[method] = true
23
+ end
24
+ end
25
+ end
26
+
@@ -1,18 +1,18 @@
1
1
  module DatabaseCleaner
2
2
  class NullStrategy
3
- def self.start
3
+ def start
4
4
  # no-op
5
5
  end
6
6
 
7
- def self.db=(connection)
8
- # no-op
9
- end
7
+ def db=(connection)
8
+ # no-op
9
+ end
10
10
 
11
- def self.clean
11
+ def clean
12
12
  # no-op
13
13
  end
14
14
 
15
- def self.cleaning(&block)
15
+ def cleaning(&block)
16
16
  # no-op
17
17
  yield
18
18
  end
@@ -0,0 +1,41 @@
1
+ module DatabaseCleaner
2
+ class ORMAutodetector
3
+ ORMS = {
4
+ active_record: "ActiveRecord",
5
+ data_mapper: "DataMapper",
6
+ mongo_mapper: "MongoMapper",
7
+ mongoid: "Mongoid",
8
+ mongo: "Mongo",
9
+ couch_potato: "CouchPotato",
10
+ sequel: "Sequel",
11
+ moped: "Moped",
12
+ ohm: "Ohm",
13
+ redis: "Redis",
14
+ neo4j: "Neo4j",
15
+ }
16
+
17
+ def orm
18
+ @autodetected = true
19
+ autodetected_orm or raise no_orm_detected_error
20
+ ORMS.key(autodetected_orm.to_s)
21
+ end
22
+
23
+ def autodetected?
24
+ !!@autodetected
25
+ end
26
+
27
+ private
28
+
29
+ def autodetected_orm
30
+ ORMS.values.find do |orm|
31
+ Kernel.const_get(orm) rescue next
32
+ end
33
+ end
34
+
35
+ def no_orm_detected_error
36
+ orm_list = ORMS.values.join(", ").sub(ORMS.values.last, "or #{ORMS.values.last}")
37
+ NoORMDetected.new("No known ORM was detected! Is #{orm_list} loaded?")
38
+ end
39
+ end
40
+ private_constant :ORMAutodetector
41
+ end
@@ -0,0 +1,107 @@
1
+ module DatabaseCleaner
2
+ class Safeguard
3
+ class Error < Exception
4
+ class RemoteDatabaseUrl < Error
5
+ def initialize
6
+ super("ENV['DATABASE_URL'] is set to a remote URL. Please refer to https://github.com/DatabaseCleaner/database_cleaner#safeguards")
7
+ end
8
+ end
9
+
10
+ class ProductionEnv < Error
11
+ def initialize(env)
12
+ super("ENV['#{env}'] is set to production. Please refer to https://github.com/DatabaseCleaner/database_cleaner#safeguards")
13
+ end
14
+ end
15
+
16
+ class NotWhitelistedUrl < Error
17
+ def initialize
18
+ super("ENV['DATABASE_URL'] is set to a URL that is not on the whitelist. Please refer to https://github.com/DatabaseCleaner/database_cleaner#safeguards")
19
+ end
20
+ end
21
+ end
22
+
23
+ class WhitelistedUrl
24
+ def run
25
+ return if skip?
26
+ raise Error::NotWhitelistedUrl if database_url_not_whitelisted?
27
+ end
28
+
29
+ private
30
+
31
+ def database_url_not_whitelisted?
32
+ !DatabaseCleaner.url_whitelist.include?(ENV['DATABASE_URL'])
33
+ end
34
+
35
+ def skip?
36
+ !DatabaseCleaner.url_whitelist
37
+ end
38
+ end
39
+
40
+
41
+ class RemoteDatabaseUrl
42
+ LOCAL = %w(localhost 127.0.0.1)
43
+
44
+ def run
45
+ raise Error::RemoteDatabaseUrl if !skip? && given?
46
+ end
47
+
48
+ private
49
+
50
+ def given?
51
+ remote?(ENV['DATABASE_URL'])
52
+ end
53
+
54
+ def remote?(url)
55
+ return false unless url
56
+
57
+ parsed = URI.parse(url)
58
+ return false if parsed.scheme == 'sqlite3:'
59
+
60
+ host = parsed.host
61
+ return false unless host
62
+ return false if LOCAL.include?(host)
63
+ return false if host.end_with? '.local'
64
+ true
65
+ end
66
+
67
+ def skip?
68
+ ENV['DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL'] ||
69
+ DatabaseCleaner.allow_remote_database_url ||
70
+ DatabaseCleaner.url_whitelist
71
+ end
72
+ end
73
+
74
+ class Production
75
+ KEYS = %w(ENV RACK_ENV RAILS_ENV)
76
+
77
+ def run
78
+ raise Error::ProductionEnv.new(key) if !skip? && given?
79
+ end
80
+
81
+ private
82
+
83
+ def given?
84
+ !!key
85
+ end
86
+
87
+ def key
88
+ @key ||= KEYS.detect { |key| ENV[key] == 'production' }
89
+ end
90
+
91
+ def skip?
92
+ ENV['DATABASE_CLEANER_ALLOW_PRODUCTION'] ||
93
+ DatabaseCleaner.allow_production
94
+ end
95
+ end
96
+
97
+ CHECKS = [
98
+ RemoteDatabaseUrl,
99
+ Production,
100
+ WhitelistedUrl
101
+ ]
102
+
103
+ def run
104
+ CHECKS.each { |const| const.new.run }
105
+ end
106
+ end
107
+ end