test_data 0.0.2 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +1 -5
- data/.standard.yml +2 -0
- data/CHANGELOG.md +41 -0
- data/Gemfile.lock +16 -16
- data/LICENSE.txt +1 -6
- data/README.md +864 -501
- data/example/.gitignore +1 -4
- data/example/Gemfile.lock +74 -74
- data/example/config/application.rb +3 -0
- data/example/config/credentials.yml.enc +1 -2
- data/example/spec/rails_helper.rb +1 -1
- data/example/spec/requests/boops_spec.rb +1 -5
- data/example/spec/requests/rails_fixtures_override_spec.rb +106 -0
- data/example/test/integration/better_mode_switching_demo_test.rb +6 -10
- data/example/test/integration/fixture_load_count_test.rb +82 -0
- data/example/test/integration/load_rollback_truncate_test.rb +40 -45
- data/example/test/integration/mode_switching_demo_test.rb +4 -14
- data/example/test/integration/parallel_boops_with_fixtures_test.rb +2 -6
- data/example/test/integration/parallel_boops_without_fixtures_test.rb +2 -6
- data/example/test/integration/rails_fixtures_double_load_test.rb +10 -0
- data/example/test/integration/rails_fixtures_override_test.rb +110 -0
- data/example/test/integration/test_data_hooks_test.rb +89 -0
- data/example/test/integration/transaction_committing_boops_test.rb +5 -3
- data/example/test/test_helper.rb +2 -6
- data/lib/generators/test_data/cable_yaml_generator.rb +18 -0
- data/lib/generators/test_data/database_yaml_generator.rb +2 -3
- data/lib/generators/test_data/environment_file_generator.rb +7 -0
- data/lib/generators/test_data/initializer_generator.rb +20 -7
- data/lib/generators/test_data/secrets_yaml_generator.rb +19 -0
- data/lib/generators/test_data/webpacker_yaml_generator.rb +3 -2
- data/lib/test_data.rb +37 -1
- data/lib/test_data/active_record_ext.rb +11 -0
- data/lib/test_data/config.rb +33 -3
- data/lib/test_data/configurators.rb +2 -0
- data/lib/test_data/configurators/cable_yaml.rb +25 -0
- data/lib/test_data/configurators/environment_file.rb +3 -2
- data/lib/test_data/configurators/initializer.rb +3 -2
- data/lib/test_data/configurators/secrets_yaml.rb +25 -0
- data/lib/test_data/configurators/webpacker_yaml.rb +4 -3
- data/lib/test_data/custom_loaders/abstract_base.rb +25 -0
- data/lib/test_data/custom_loaders/rails_fixtures.rb +45 -0
- data/lib/test_data/dumps_database.rb +24 -1
- data/lib/test_data/generator_support.rb +3 -0
- data/lib/test_data/inserts_test_data.rb +25 -0
- data/lib/test_data/loads_database_dumps.rb +1 -1
- data/lib/test_data/log.rb +19 -1
- data/lib/test_data/{transactional_data_loader.rb → manager.rb} +78 -81
- data/lib/test_data/rake.rb +16 -7
- data/lib/test_data/statistics.rb +6 -1
- data/lib/test_data/truncates_test_data.rb +31 -0
- data/lib/test_data/version.rb +1 -1
- data/script/reset_example_app +1 -0
- data/script/test +31 -6
- data/test_data.gemspec +1 -1
- metadata +20 -4
@@ -0,0 +1,25 @@
|
|
1
|
+
module TestData
|
2
|
+
module CustomLoaders
|
3
|
+
class AbstractBase
|
4
|
+
def name
|
5
|
+
raise Error.new("#name must be defined by CustomLoader subclass")
|
6
|
+
end
|
7
|
+
|
8
|
+
def load_requested(**options)
|
9
|
+
end
|
10
|
+
|
11
|
+
def loaded?(**options)
|
12
|
+
# Check to see if the requested data is already loaded (if possible and
|
13
|
+
# detectable)
|
14
|
+
#
|
15
|
+
# Return true to prevent #load from being called, potentially avoiding an
|
16
|
+
# expensive operation
|
17
|
+
false
|
18
|
+
end
|
19
|
+
|
20
|
+
def load(**options)
|
21
|
+
raise Error.new("#load must be defined by CustomLoader subclass")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module TestData
|
2
|
+
module CustomLoaders
|
3
|
+
class RailsFixtures < AbstractBase
|
4
|
+
def initialize
|
5
|
+
@config = TestData.config
|
6
|
+
@statistics = TestData.statistics
|
7
|
+
@already_loaded_rails_fixtures = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def name
|
11
|
+
:rails_fixtures
|
12
|
+
end
|
13
|
+
|
14
|
+
def validate!(test_instance:)
|
15
|
+
if !test_instance.respond_to?(:setup_fixtures)
|
16
|
+
raise Error.new("'TestData.uses_rails_fixtures(self)' must be passed a test instance that has had ActiveRecord::TestFixtures mixed-in (e.g. `TestData.uses_rails_fixtures(self)` in an ActiveSupport::TestCase `setup` block), but the provided argument does not respond to 'setup_fixtures'")
|
17
|
+
elsif !test_instance.respond_to?(:__test_data_gem_setup_fixtures)
|
18
|
+
raise Error.new("'TestData.uses_rails_fixtures(self)' depends on Rails' default fixture-loading behavior being disabled by calling 'TestData.prevent_rails_fixtures_from_loading_automatically!' as early as possible (e.g. near the top of your test_helper.rb), but it looks like it was never called.")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def load_requested(test_instance:)
|
23
|
+
ActiveRecord::FixtureSet.reset_cache
|
24
|
+
test_instance.instance_variable_set(:@loaded_fixtures,
|
25
|
+
@already_loaded_rails_fixtures.slice(*test_instance.class.fixture_table_names))
|
26
|
+
test_instance.instance_variable_set(:@fixture_cache, {})
|
27
|
+
end
|
28
|
+
|
29
|
+
def loaded?(test_instance:)
|
30
|
+
test_instance.class.fixture_table_names.all? { |table_name|
|
31
|
+
@already_loaded_rails_fixtures.key?(table_name)
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def load(test_instance:)
|
36
|
+
test_instance.pre_loaded_fixtures = false
|
37
|
+
test_instance.use_transactional_tests = false
|
38
|
+
test_instance.__test_data_gem_setup_fixtures
|
39
|
+
@already_loaded_rails_fixtures = test_instance.instance_variable_get(:@loaded_fixtures)
|
40
|
+
@statistics.count_load_rails_fixtures!
|
41
|
+
@config.after_rails_fixture_load_hook.call
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -40,12 +40,14 @@ module TestData
|
|
40
40
|
def dump(type:, database_name:, relative_path:, full_path:, name: type, flags: "")
|
41
41
|
dump_pathname = Pathname.new(full_path)
|
42
42
|
FileUtils.mkdir_p(File.dirname(dump_pathname))
|
43
|
+
before_size = File.size?(dump_pathname)
|
43
44
|
if execute("pg_dump #{database_name} --no-tablespaces --no-owner --inserts --#{type}-only #{flags} -f #{dump_pathname}")
|
44
45
|
prepend_set_replication_role!(full_path) if type == :data
|
45
46
|
|
46
47
|
TestData.log.info "Dumped '#{database_name}' #{name} to '#{relative_path}'"
|
48
|
+
log_size_info_and_warnings(before_size: before_size, after_size: File.size(dump_pathname))
|
47
49
|
else
|
48
|
-
raise "Failed while attempting to dump '#{database_name}' #{name} to '#{relative_path}'"
|
50
|
+
raise Error.new("Failed while attempting to dump '#{database_name}' #{name} to '#{relative_path}'")
|
49
51
|
end
|
50
52
|
end
|
51
53
|
|
@@ -72,5 +74,26 @@ module TestData
|
|
72
74
|
COMMAND
|
73
75
|
TestData.log.debug("Prepended replication role instruction to '#{data_dump_path}'")
|
74
76
|
end
|
77
|
+
|
78
|
+
def log_size_info_and_warnings(before_size:, after_size:)
|
79
|
+
percent_change = percent_change(before_size, after_size)
|
80
|
+
TestData.log.info " Size: #{to_size(after_size)}#{" (#{percent_change}% #{before_size > after_size ? "decrease" : "increase"})" if percent_change}"
|
81
|
+
if after_size > 5242880
|
82
|
+
TestData.log.warn " WARNING: file size exceeds 5MB. Be sure to only persist what data you need to sufficiently test your application"
|
83
|
+
end
|
84
|
+
if before_size && (after_size - before_size) > 1048576
|
85
|
+
TestData.log.warn " WARNING: size of this dump increased by #{to_size(after_size - before_size)}. You may want to inspect the file to validate extraneous data was not committed"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def percent_change(before_size, after_size)
|
90
|
+
return unless before_size && before_size > 0 && after_size
|
91
|
+
((before_size - after_size).abs / before_size * 100).round(2)
|
92
|
+
end
|
93
|
+
|
94
|
+
def to_size(bytes)
|
95
|
+
e = Math.log10(bytes).to_i / 3
|
96
|
+
"%.0f" % (bytes / 1000**e) + [" bytes", "KB", "MB", "GB"][e]
|
97
|
+
end
|
75
98
|
end
|
76
99
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module TestData
|
2
|
+
class InsertsTestData
|
3
|
+
def initialize
|
4
|
+
@config = TestData.config
|
5
|
+
@statistics = TestData.statistics
|
6
|
+
end
|
7
|
+
|
8
|
+
def call
|
9
|
+
search_path = connection.execute("show search_path").first["search_path"]
|
10
|
+
connection.disable_referential_integrity do
|
11
|
+
connection.execute(File.read(@config.data_dump_full_path))
|
12
|
+
end
|
13
|
+
connection.execute <<~SQL
|
14
|
+
select pg_catalog.set_config('search_path', '#{search_path}', false)
|
15
|
+
SQL
|
16
|
+
@statistics.count_load!
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def connection
|
22
|
+
ActiveRecord::Base.connection
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -38,7 +38,7 @@ module TestData
|
|
38
38
|
if system "psql -q -d #{database_name} < #{dump_pathname}"
|
39
39
|
TestData.log.info "Loaded #{name} from '#{relative_path}' into database '#{database_name}' "
|
40
40
|
else
|
41
|
-
raise "Failed while attempting to load #{name} from '#{relative_path}' into database '#{database_name}'"
|
41
|
+
raise Error.new("Failed while attempting to load #{name} from '#{relative_path}' into database '#{database_name}'")
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
data/lib/test_data/log.rb
CHANGED
@@ -6,13 +6,20 @@ module TestData
|
|
6
6
|
class Log
|
7
7
|
LEVELS = [:debug, :info, :warn, :error, :quiet]
|
8
8
|
DEFAULT_WRITER = ->(message, level) do
|
9
|
-
output = "[test_data
|
9
|
+
output = "[test_data:#{level}] #{message}"
|
10
10
|
if [:warn, :error].include?(level)
|
11
11
|
warn output
|
12
12
|
else
|
13
13
|
puts output
|
14
14
|
end
|
15
15
|
end
|
16
|
+
PLAIN_WRITER = ->(message, level) do
|
17
|
+
if [:warn, :error].include?(level)
|
18
|
+
warn message
|
19
|
+
else
|
20
|
+
puts message
|
21
|
+
end
|
22
|
+
end
|
16
23
|
|
17
24
|
attr_reader :level, :writer
|
18
25
|
|
@@ -49,6 +56,17 @@ module TestData
|
|
49
56
|
end
|
50
57
|
end
|
51
58
|
|
59
|
+
def with_writer(writer, &blk)
|
60
|
+
og_writer = self.writer
|
61
|
+
self.writer = writer
|
62
|
+
blk.call
|
63
|
+
self.writer = og_writer
|
64
|
+
end
|
65
|
+
|
66
|
+
def with_plain_writer(&blk)
|
67
|
+
with_writer(PLAIN_WRITER, &blk)
|
68
|
+
end
|
69
|
+
|
52
70
|
private
|
53
71
|
|
54
72
|
def enabled?(level)
|
@@ -1,69 +1,25 @@
|
|
1
1
|
module TestData
|
2
|
-
|
3
|
-
@transactional_data_loader ||= TransactionalDataLoader.new
|
4
|
-
@transactional_data_loader.load(transactions: transactions)
|
5
|
-
end
|
6
|
-
|
7
|
-
def self.rollback(save_point_name = :after_data_load)
|
8
|
-
@transactional_data_loader ||= TransactionalDataLoader.new
|
9
|
-
case save_point_name
|
10
|
-
when :before_data_load
|
11
|
-
@transactional_data_loader.rollback_to_before_data_load
|
12
|
-
when :after_data_load
|
13
|
-
@transactional_data_loader.rollback_to_after_data_load
|
14
|
-
when :after_data_truncate
|
15
|
-
@transactional_data_loader.rollback_to_after_data_truncate
|
16
|
-
else
|
17
|
-
raise Error.new("No known save point named '#{save_point_name}'. Valid values are: [:before_data_load, :after_data_load, :after_data_truncate]")
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.truncate(transactions: true)
|
22
|
-
@transactional_data_loader ||= TransactionalDataLoader.new
|
23
|
-
@transactional_data_loader.truncate(transactions: transactions)
|
24
|
-
end
|
25
|
-
|
26
|
-
class TransactionalDataLoader
|
2
|
+
class Manager
|
27
3
|
def initialize
|
4
|
+
@inserts_test_data = InsertsTestData.new
|
5
|
+
@truncates_test_data = TruncatesTestData.new
|
28
6
|
@config = TestData.config
|
29
7
|
@statistics = TestData.statistics
|
30
8
|
@save_points = []
|
31
9
|
end
|
32
10
|
|
33
|
-
def load
|
34
|
-
return execute_data_load unless transactions
|
11
|
+
def load
|
35
12
|
ensure_after_load_save_point_is_active_if_data_is_loaded!
|
36
13
|
return rollback_to_after_data_load if save_point_active?(:after_data_load)
|
37
14
|
|
38
15
|
create_save_point(:before_data_load)
|
39
|
-
|
16
|
+
@inserts_test_data.call
|
17
|
+
@config.after_test_data_load_hook.call
|
40
18
|
record_ar_internal_metadata_that_test_data_is_loaded
|
41
19
|
create_save_point(:after_data_load)
|
42
20
|
end
|
43
21
|
|
44
|
-
def
|
45
|
-
if save_point_active?(:before_data_load)
|
46
|
-
rollback_save_point(:before_data_load)
|
47
|
-
# No need to recreate the save point -- TestData.load will if called
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def rollback_to_after_data_load
|
52
|
-
if save_point_active?(:after_data_load)
|
53
|
-
rollback_save_point(:after_data_load)
|
54
|
-
create_save_point(:after_data_load)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def rollback_to_after_data_truncate
|
59
|
-
if save_point_active?(:after_data_truncate)
|
60
|
-
rollback_save_point(:after_data_truncate)
|
61
|
-
create_save_point(:after_data_truncate)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def truncate(transactions: true)
|
66
|
-
return execute_data_truncate unless transactions
|
22
|
+
def truncate
|
67
23
|
ensure_after_load_save_point_is_active_if_data_is_loaded!
|
68
24
|
ensure_after_truncate_save_point_is_active_if_data_is_truncated!
|
69
25
|
return rollback_to_after_data_truncate if save_point_active?(:after_data_truncate)
|
@@ -81,17 +37,75 @@ module TestData
|
|
81
37
|
# should expect that the existence of :after_data_truncate save point
|
82
38
|
# implies that it's safe to rollback to the :after_data_load save
|
83
39
|
# point; since tests run in random order, it's likely to happen
|
84
|
-
TestData.log.debug("TestData.
|
85
|
-
load
|
40
|
+
TestData.log.debug("TestData.uses_clean_slate was called, but data was not loaded. Loading data before truncate to preserve the transaction save point ordering")
|
41
|
+
load
|
86
42
|
end
|
87
43
|
|
88
|
-
|
44
|
+
@truncates_test_data.call
|
45
|
+
@config.after_test_data_truncate_hook.call
|
89
46
|
record_ar_internal_metadata_that_test_data_is_truncated
|
90
47
|
create_save_point(:after_data_truncate)
|
91
48
|
end
|
92
49
|
|
50
|
+
def load_custom_data(loader, **options)
|
51
|
+
loader.validate!(**options)
|
52
|
+
snapshot_name = "user_#{loader.name}".to_sym
|
53
|
+
|
54
|
+
ensure_after_load_save_point_is_active_if_data_is_loaded!
|
55
|
+
ensure_after_truncate_save_point_is_active_if_data_is_truncated!
|
56
|
+
ensure_custom_save_point_is_active_if_memo_exists!(snapshot_name)
|
57
|
+
|
58
|
+
loader.load_requested(**options)
|
59
|
+
if save_point_active?(snapshot_name) && loader.loaded?(**options)
|
60
|
+
return rollback_to_custom_savepoint(snapshot_name)
|
61
|
+
end
|
62
|
+
|
63
|
+
if save_point_active?(:after_data_truncate)
|
64
|
+
rollback_to_after_data_truncate
|
65
|
+
else
|
66
|
+
truncate
|
67
|
+
end
|
68
|
+
|
69
|
+
loader.load(**options)
|
70
|
+
record_ar_internal_metadata_of_custom_save_point(snapshot_name)
|
71
|
+
create_save_point(snapshot_name)
|
72
|
+
end
|
73
|
+
|
74
|
+
def rollback_to_before_data_load
|
75
|
+
if save_point_active?(:before_data_load)
|
76
|
+
rollback_save_point(:before_data_load)
|
77
|
+
# No need to recreate the save point
|
78
|
+
# (TestData.uses_test_data will if called)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
93
82
|
private
|
94
83
|
|
84
|
+
def rollback_to_after_data_load
|
85
|
+
if save_point_active?(:after_data_load)
|
86
|
+
rollback_save_point(:after_data_load)
|
87
|
+
create_save_point(:after_data_load)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def rollback_to_after_data_truncate
|
92
|
+
if save_point_active?(:after_data_truncate)
|
93
|
+
rollback_save_point(:after_data_truncate)
|
94
|
+
create_save_point(:after_data_truncate)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def rollback_to_custom_savepoint(name)
|
99
|
+
if save_point_active?(name)
|
100
|
+
rollback_save_point(name)
|
101
|
+
create_save_point(name)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def connection
|
106
|
+
ActiveRecord::Base.connection
|
107
|
+
end
|
108
|
+
|
95
109
|
def ensure_after_load_save_point_is_active_if_data_is_loaded!
|
96
110
|
if !save_point_active?(:after_data_load) && ar_internal_metadata_shows_test_data_is_loaded?
|
97
111
|
TestData.log.debug "Test data appears to be loaded, but the :after_data_load save point was rolled back (and not by this gem). Recreating the :after_data_load save point"
|
@@ -130,31 +144,22 @@ module TestData
|
|
130
144
|
ActiveRecord::InternalMetadata.find_by(key: "test_data:truncated")&.value == "true"
|
131
145
|
end
|
132
146
|
|
133
|
-
def
|
134
|
-
|
135
|
-
|
136
|
-
|
147
|
+
def ensure_custom_save_point_is_active_if_memo_exists!(name)
|
148
|
+
if !save_point_active?(name) && ar_internal_metadata_shows_custom_operation_was_persisted?(name)
|
149
|
+
TestData.log.debug "#{name} appears to have been loaded by test_data, but the #{name} save point was rolled back (and not by this gem). Recreating the #{name} save point"
|
150
|
+
create_save_point(name)
|
137
151
|
end
|
138
|
-
execute <<~SQL
|
139
|
-
select pg_catalog.set_config('search_path', '#{search_path}', false)
|
140
|
-
SQL
|
141
|
-
@statistics.count_load!
|
142
152
|
end
|
143
153
|
|
144
|
-
def
|
145
|
-
|
146
|
-
execute("TRUNCATE TABLE #{tables_to_truncate.map { |t| connection.quote_table_name(t) }.join(", ")}")
|
147
|
-
end
|
148
|
-
@statistics.count_truncate!
|
154
|
+
def ar_internal_metadata_shows_custom_operation_was_persisted?(name)
|
155
|
+
ActiveRecord::InternalMetadata.find_by(key: "test_data:#{name}")&.value == "true"
|
149
156
|
end
|
150
157
|
|
151
|
-
def
|
152
|
-
if
|
153
|
-
|
158
|
+
def record_ar_internal_metadata_of_custom_save_point(name)
|
159
|
+
if ar_internal_metadata_shows_custom_operation_was_persisted?(name)
|
160
|
+
TestData.log.warn "Attempted to record that test_data had loaded #{name} in ar_internal_metadata, but record already existed. Perhaps a previous test run committed it?"
|
154
161
|
else
|
155
|
-
|
156
|
-
line.match(/^INSERT INTO ([^\s]+)/)&.captures&.first
|
157
|
-
}.compact.uniq
|
162
|
+
ActiveRecord::InternalMetadata.create!(key: "test_data:#{name}", value: "true")
|
158
163
|
end
|
159
164
|
end
|
160
165
|
|
@@ -178,13 +183,5 @@ module TestData
|
|
178
183
|
save_point.active?
|
179
184
|
}
|
180
185
|
end
|
181
|
-
|
182
|
-
def execute(sql)
|
183
|
-
connection.execute(sql)
|
184
|
-
end
|
185
|
-
|
186
|
-
def connection
|
187
|
-
ActiveRecord::Base.connection
|
188
|
-
end
|
189
186
|
end
|
190
187
|
end
|
data/lib/test_data/rake.rb
CHANGED
@@ -22,13 +22,15 @@ end
|
|
22
22
|
|
23
23
|
desc "Verifies test_data environment looks good"
|
24
24
|
task "test_data:verify_config" do
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
TestData.log.with_plain_writer do
|
26
|
+
config = TestData::VerifiesConfiguration.new.call
|
27
|
+
unless config.looks_good?
|
28
|
+
TestData.log.warn "\nThe test_data gem is not configured correctly. Try running: rake test_data:configure\n\n"
|
29
|
+
config.problems.each do |problem|
|
30
|
+
TestData.log.warn " - #{problem}"
|
31
|
+
end
|
32
|
+
fail
|
30
33
|
end
|
31
|
-
fail
|
32
34
|
end
|
33
35
|
end
|
34
36
|
|
@@ -48,6 +50,13 @@ task "test_data:initialize" => ["test_data:verify_config", :environment] do
|
|
48
50
|
ActiveRecord::Tasks::DatabaseTasks.load_schema_current(ActiveRecord::Base.schema_format, ENV["SCHEMA"], "test_data")
|
49
51
|
ActiveRecord::Tasks::DatabaseTasks.load_seed
|
50
52
|
end
|
53
|
+
|
54
|
+
TestData.log.info <<~MSG
|
55
|
+
Your test_data environment and database are ready for use! You can now run your server (or any command) to create some test data like so:
|
56
|
+
|
57
|
+
$ RAILS_ENV=test_data bin/rails server
|
58
|
+
|
59
|
+
MSG
|
51
60
|
end
|
52
61
|
|
53
62
|
desc "Initialize test_data Rails environment & configure database"
|
@@ -73,7 +82,7 @@ task "test_data:load" => ["test_data:verify_config", :environment] do
|
|
73
82
|
TestData::LoadsDatabaseDumps.new.call
|
74
83
|
|
75
84
|
if ActiveRecord::Base.connection.migration_context.needs_migration?
|
76
|
-
TestData.log.warn "There are pending migrations for database '#{TestData.config.database_name}'. To run them, run:\n\n RAILS_ENV=test_data bin/rake db:migrate\n\n"
|
85
|
+
TestData.log.warn "There are pending migrations for database '#{TestData.config.database_name}'. To run them, run:\n\n $ RAILS_ENV=test_data bin/rake db:migrate\n\n"
|
77
86
|
end
|
78
87
|
end
|
79
88
|
|