config_scripts 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.rspec +2 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +17 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +124 -0
- data/LICENSE.txt +22 -0
- data/README.md +55 -0
- data/Rakefile +1 -0
- data/TODO.md +8 -0
- data/config_scripts.gemspec +31 -0
- data/lib/config_scripts/generators/config_script.rb +24 -0
- data/lib/config_scripts/generators/migrations.rb +36 -0
- data/lib/config_scripts/generators.rb +2 -0
- data/lib/config_scripts/scripts/script.rb +135 -0
- data/lib/config_scripts/scripts/script_history.rb +39 -0
- data/lib/config_scripts/scripts.rb +9 -0
- data/lib/config_scripts/seeds/seed_set.rb +321 -0
- data/lib/config_scripts/seeds/seed_type.rb +361 -0
- data/lib/config_scripts/seeds.rb +8 -0
- data/lib/config_scripts/tasks/pending_migrations.rake +11 -0
- data/lib/config_scripts/tasks/seeds.rake +18 -0
- data/lib/config_scripts/tasks.rb +12 -0
- data/lib/config_scripts/version.rb +4 -0
- data/lib/config_scripts.rb +9 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/models/hair_color.rb +2 -0
- data/spec/dummy/app/models/person.rb +4 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config/application.rb +23 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +29 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +36 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +56 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/migrate/20140208014550_create_config_scripts.rb +7 -0
- data/spec/dummy/db/migrate/20140208161829_create_people.rb +9 -0
- data/spec/dummy/db/migrate/20140208182050_create_hair_colors.rb +9 -0
- data/spec/dummy/db/migrate/20140208182101_add_hair_color_to_person.rb +6 -0
- data/spec/dummy/db/migrate/20140208225801_add_scope_to_people.rb +6 -0
- data/spec/dummy/db/migrate/20140209132911_add_hex_value_to_hair_color.rb +5 -0
- data/spec/dummy/db/schema.rb +38 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +58 -0
- data/spec/dummy/public/422.html +58 -0
- data/spec/dummy/public/500.html +57 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/generators/config_script_spec.rb +23 -0
- data/spec/generators/migrations_spec.rb +23 -0
- data/spec/scripts/script_history_spec.rb +53 -0
- data/spec/scripts/script_spec.rb +282 -0
- data/spec/seeds/seed_set_spec.rb +371 -0
- data/spec/seeds/seed_type_spec.rb +439 -0
- data/spec/spec_helper.rb +38 -0
- data/templates/config_script.rb +9 -0
- data/templates/create_config_scripts_migration.rb +7 -0
- metadata +321 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
5
|
+
<style>
|
6
|
+
body {
|
7
|
+
background-color: #EFEFEF;
|
8
|
+
color: #2E2F30;
|
9
|
+
text-align: center;
|
10
|
+
font-family: arial, sans-serif;
|
11
|
+
}
|
12
|
+
|
13
|
+
div.dialog {
|
14
|
+
width: 25em;
|
15
|
+
margin: 4em auto 0 auto;
|
16
|
+
border: 1px solid #CCC;
|
17
|
+
border-right-color: #999;
|
18
|
+
border-left-color: #999;
|
19
|
+
border-bottom-color: #BBB;
|
20
|
+
border-top: #B00100 solid 4px;
|
21
|
+
border-top-left-radius: 9px;
|
22
|
+
border-top-right-radius: 9px;
|
23
|
+
background-color: white;
|
24
|
+
padding: 7px 4em 0 4em;
|
25
|
+
}
|
26
|
+
|
27
|
+
h1 {
|
28
|
+
font-size: 100%;
|
29
|
+
color: #730E15;
|
30
|
+
line-height: 1.5em;
|
31
|
+
}
|
32
|
+
|
33
|
+
body > p {
|
34
|
+
width: 33em;
|
35
|
+
margin: 0 auto 1em;
|
36
|
+
padding: 1em 0;
|
37
|
+
background-color: #F7F7F7;
|
38
|
+
border: 1px solid #CCC;
|
39
|
+
border-right-color: #999;
|
40
|
+
border-bottom-color: #999;
|
41
|
+
border-bottom-left-radius: 4px;
|
42
|
+
border-bottom-right-radius: 4px;
|
43
|
+
border-top-color: #DADADA;
|
44
|
+
color: #666;
|
45
|
+
box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
|
46
|
+
}
|
47
|
+
</style>
|
48
|
+
</head>
|
49
|
+
|
50
|
+
<body>
|
51
|
+
<!-- This file lives in public/404.html -->
|
52
|
+
<div class="dialog">
|
53
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
54
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
55
|
+
</div>
|
56
|
+
<p>If you are the application owner check the logs for more information.</p>
|
57
|
+
</body>
|
58
|
+
</html>
|
@@ -0,0 +1,58 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
5
|
+
<style>
|
6
|
+
body {
|
7
|
+
background-color: #EFEFEF;
|
8
|
+
color: #2E2F30;
|
9
|
+
text-align: center;
|
10
|
+
font-family: arial, sans-serif;
|
11
|
+
}
|
12
|
+
|
13
|
+
div.dialog {
|
14
|
+
width: 25em;
|
15
|
+
margin: 4em auto 0 auto;
|
16
|
+
border: 1px solid #CCC;
|
17
|
+
border-right-color: #999;
|
18
|
+
border-left-color: #999;
|
19
|
+
border-bottom-color: #BBB;
|
20
|
+
border-top: #B00100 solid 4px;
|
21
|
+
border-top-left-radius: 9px;
|
22
|
+
border-top-right-radius: 9px;
|
23
|
+
background-color: white;
|
24
|
+
padding: 7px 4em 0 4em;
|
25
|
+
}
|
26
|
+
|
27
|
+
h1 {
|
28
|
+
font-size: 100%;
|
29
|
+
color: #730E15;
|
30
|
+
line-height: 1.5em;
|
31
|
+
}
|
32
|
+
|
33
|
+
body > p {
|
34
|
+
width: 33em;
|
35
|
+
margin: 0 auto 1em;
|
36
|
+
padding: 1em 0;
|
37
|
+
background-color: #F7F7F7;
|
38
|
+
border: 1px solid #CCC;
|
39
|
+
border-right-color: #999;
|
40
|
+
border-bottom-color: #999;
|
41
|
+
border-bottom-left-radius: 4px;
|
42
|
+
border-bottom-right-radius: 4px;
|
43
|
+
border-top-color: #DADADA;
|
44
|
+
color: #666;
|
45
|
+
box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
|
46
|
+
}
|
47
|
+
</style>
|
48
|
+
</head>
|
49
|
+
|
50
|
+
<body>
|
51
|
+
<!-- This file lives in public/422.html -->
|
52
|
+
<div class="dialog">
|
53
|
+
<h1>The change you wanted was rejected.</h1>
|
54
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
55
|
+
</div>
|
56
|
+
<p>If you are the application owner check the logs for more information.</p>
|
57
|
+
</body>
|
58
|
+
</html>
|
@@ -0,0 +1,57 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
5
|
+
<style>
|
6
|
+
body {
|
7
|
+
background-color: #EFEFEF;
|
8
|
+
color: #2E2F30;
|
9
|
+
text-align: center;
|
10
|
+
font-family: arial, sans-serif;
|
11
|
+
}
|
12
|
+
|
13
|
+
div.dialog {
|
14
|
+
width: 25em;
|
15
|
+
margin: 4em auto 0 auto;
|
16
|
+
border: 1px solid #CCC;
|
17
|
+
border-right-color: #999;
|
18
|
+
border-left-color: #999;
|
19
|
+
border-bottom-color: #BBB;
|
20
|
+
border-top: #B00100 solid 4px;
|
21
|
+
border-top-left-radius: 9px;
|
22
|
+
border-top-right-radius: 9px;
|
23
|
+
background-color: white;
|
24
|
+
padding: 7px 4em 0 4em;
|
25
|
+
}
|
26
|
+
|
27
|
+
h1 {
|
28
|
+
font-size: 100%;
|
29
|
+
color: #730E15;
|
30
|
+
line-height: 1.5em;
|
31
|
+
}
|
32
|
+
|
33
|
+
body > p {
|
34
|
+
width: 33em;
|
35
|
+
margin: 0 auto 1em;
|
36
|
+
padding: 1em 0;
|
37
|
+
background-color: #F7F7F7;
|
38
|
+
border: 1px solid #CCC;
|
39
|
+
border-right-color: #999;
|
40
|
+
border-bottom-color: #999;
|
41
|
+
border-bottom-left-radius: 4px;
|
42
|
+
border-bottom-right-radius: 4px;
|
43
|
+
border-top-color: #DADADA;
|
44
|
+
color: #666;
|
45
|
+
box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
|
46
|
+
}
|
47
|
+
</style>
|
48
|
+
</head>
|
49
|
+
|
50
|
+
<body>
|
51
|
+
<!-- This file lives in public/500.html -->
|
52
|
+
<div class="dialog">
|
53
|
+
<h1>We're sorry, but something went wrong.</h1>
|
54
|
+
</div>
|
55
|
+
<p>If you are the application owner check the logs for more information.</p>
|
56
|
+
</body>
|
57
|
+
</html>
|
File without changes
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'generator_spec'
|
2
|
+
|
3
|
+
describe ConfigScripts::ConfigScriptGenerator, type: :generator do
|
4
|
+
destination File.expand_path("../../../tmp", __FILE__)
|
5
|
+
arguments ['TestConfigScript']
|
6
|
+
|
7
|
+
describe "config_script" do
|
8
|
+
let(:expected_path) { "db/config_scripts/#{Time.now.to_s(:number)}_test_config_script.rb" }
|
9
|
+
before do
|
10
|
+
prepare_destination
|
11
|
+
Timecop.freeze
|
12
|
+
run_generator
|
13
|
+
end
|
14
|
+
|
15
|
+
after do
|
16
|
+
Timecop.return
|
17
|
+
end
|
18
|
+
|
19
|
+
it "creates a file in the config_scripts directory, with a config script class" do
|
20
|
+
assert_file expected_path, /class TestConfigScriptConfig < ConfigScripts::Scripts::Script/
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
describe ConfigScripts::MigrationsGenerator, type: :generator do
|
2
|
+
destination File.expand_path("../../../tmp", __FILE__)
|
3
|
+
|
4
|
+
describe "create_migrations" do
|
5
|
+
before do
|
6
|
+
prepare_destination
|
7
|
+
run_generator
|
8
|
+
end
|
9
|
+
|
10
|
+
it "creates a migration for adding the config scripts table" do
|
11
|
+
assert_file "db/migrate/#{Time.now.to_s(:number)}_create_config_scripts.rb", /create_table :config_scripts/
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when running repeatedly" do
|
15
|
+
it "says that it has skipped it" do
|
16
|
+
output = capture :stderr do
|
17
|
+
run_generator
|
18
|
+
end
|
19
|
+
expect(output).to be =~ /Another migration is already named create_config_scripts/
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
describe ConfigScripts::Scripts::ScriptHistory do
|
2
|
+
let(:klass) { ConfigScripts::Scripts::ScriptHistory }
|
3
|
+
let(:timestamp1) { 5.minutes.ago.to_s(:number) }
|
4
|
+
let(:timestamp2) { 10.minutes.ago.to_s(:number) }
|
5
|
+
|
6
|
+
describe "entries_for_timestamp" do
|
7
|
+
let!(:entry1) { klass.create(name: timestamp1) }
|
8
|
+
let!(:entry2) { klass.create(name: timestamp1) }
|
9
|
+
let!(:entry3) { klass.create(name: timestamp2) }
|
10
|
+
|
11
|
+
subject { klass.entries_for_timestamp(timestamp1) }
|
12
|
+
|
13
|
+
it "gets all the entries whose timestamp has the value given" do
|
14
|
+
expect(subject).to include entry1
|
15
|
+
expect(subject).to include entry2
|
16
|
+
end
|
17
|
+
|
18
|
+
it "does not include entries with other timestamps" do
|
19
|
+
expect(subject).not_to include entry3
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "script_was_run?" do
|
24
|
+
let!(:entry1) { klass.create(name: timestamp2) }
|
25
|
+
|
26
|
+
context "with a timestamp that has an entry in the table" do
|
27
|
+
subject { klass.script_was_run?(timestamp2) }
|
28
|
+
it { should be_true }
|
29
|
+
end
|
30
|
+
|
31
|
+
context "with a timestamp that has no entry in the table" do
|
32
|
+
subject { klass.script_was_run?(timestamp1) }
|
33
|
+
it { should be_false }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "record_timestamp" do
|
38
|
+
it "adds an entry to the table" do
|
39
|
+
expect(klass.script_was_run?(timestamp1)).to be_false
|
40
|
+
klass.record_timestamp(timestamp1)
|
41
|
+
expect(klass.script_was_run?(timestamp1)).to be_true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "remove_timestamp" do
|
46
|
+
it "removes the entry from the table" do
|
47
|
+
klass.create(name: timestamp2)
|
48
|
+
expect(klass.script_was_run?(timestamp2)).to be_true
|
49
|
+
klass.remove_timestamp(timestamp2)
|
50
|
+
expect(klass.script_was_run?(timestamp2)).to be_false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,282 @@
|
|
1
|
+
describe ConfigScripts::Scripts::Script do
|
2
|
+
let(:klass) { ConfigScripts::Scripts::Script }
|
3
|
+
|
4
|
+
describe "class methods" do
|
5
|
+
describe "script_directory" do
|
6
|
+
subject { klass.script_directory}
|
7
|
+
it "is the db/config_scripts directory" do
|
8
|
+
expect(subject).to eq Rails.root.join('db', 'config_scripts')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "pending_scripts" do
|
13
|
+
let!(:filename1) { "20140208150000_script_1" }
|
14
|
+
let!(:filename2) { "20140208200000_script_2" }
|
15
|
+
|
16
|
+
subject { klass.pending_scripts }
|
17
|
+
|
18
|
+
before do
|
19
|
+
Dir.stub glob: ["/tmp/#{filename1}.rb", "/tmp/#{filename2}.rb"]
|
20
|
+
ConfigScripts::Scripts::ScriptHistory.record_timestamp('20140208150000')
|
21
|
+
end
|
22
|
+
|
23
|
+
it "uses Dir to get the files" do
|
24
|
+
subject
|
25
|
+
expect(Dir).to have_received(:glob).with(File.join(klass.script_directory, "*.rb"))
|
26
|
+
end
|
27
|
+
|
28
|
+
it "includes filenames that don't have entries in the script histories" do
|
29
|
+
expect(subject).to include filename2
|
30
|
+
end
|
31
|
+
|
32
|
+
it "does not include filenames that have entries in the script history" do
|
33
|
+
expect(subject).not_to include filename1
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "run_pending_scripts" do
|
38
|
+
class TestConfigScriptConfig < ConfigScripts::Scripts::Script; end
|
39
|
+
|
40
|
+
let!(:timestamp1) { '20140208150000' }
|
41
|
+
let!(:timestamp2) { '20140208200000' }
|
42
|
+
let!(:timestamp3) { '20140208250000' }
|
43
|
+
|
44
|
+
let(:script_filenames) { [timestamp1, timestamp2, timestamp3].collect { |stamp| "#{stamp}_test_config_script" } }
|
45
|
+
|
46
|
+
let!(:script1) { TestConfigScriptConfig.new(timestamp1) }
|
47
|
+
let!(:script2) { TestConfigScriptConfig.new(timestamp2) }
|
48
|
+
let!(:script3) { TestConfigScriptConfig.new(timestamp3) }
|
49
|
+
|
50
|
+
before do
|
51
|
+
klass.stub pending_scripts: script_filenames
|
52
|
+
klass.stub :require
|
53
|
+
klass.stub :puts
|
54
|
+
[script1, script2, script3].each do |script|
|
55
|
+
script.stub(:run)
|
56
|
+
end
|
57
|
+
|
58
|
+
TestConfigScriptConfig.stub(:new).with(timestamp1).and_return(script1)
|
59
|
+
TestConfigScriptConfig.stub(:new).with(timestamp2).and_return(script2)
|
60
|
+
TestConfigScriptConfig.stub(:new).with(timestamp3).and_return(script3)
|
61
|
+
|
62
|
+
FileUtils.mkdir_p(Rails.root.join("tmp", "cache"))
|
63
|
+
end
|
64
|
+
|
65
|
+
let(:scripts) {[
|
66
|
+
{
|
67
|
+
filename: script_filenames[0],
|
68
|
+
script: script1,
|
69
|
+
run: true
|
70
|
+
},
|
71
|
+
{
|
72
|
+
filename: script_filenames[1],
|
73
|
+
script: script2,
|
74
|
+
run: true
|
75
|
+
},
|
76
|
+
{
|
77
|
+
filename: script_filenames[2],
|
78
|
+
script: script3,
|
79
|
+
run: true
|
80
|
+
}
|
81
|
+
]}
|
82
|
+
|
83
|
+
|
84
|
+
shared_examples "ran scripts" do
|
85
|
+
it "requires only the scripts it needs to run" do
|
86
|
+
scripts.each do |script|
|
87
|
+
path = Rails.root.join("db", "config_scripts", "#{script[:filename]}.rb")
|
88
|
+
if script[:run]
|
89
|
+
expect(klass).to have_received(:require).with(path)
|
90
|
+
else
|
91
|
+
expect(klass).not_to have_received(:require).with(path)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it "creates a config script for each timestamp with the appropriate class" do
|
97
|
+
scripts.each do |script|
|
98
|
+
timestamp = script[:filename].first(14)
|
99
|
+
if script[:run]
|
100
|
+
expect(TestConfigScriptConfig).to have_received(:new).with(timestamp)
|
101
|
+
else
|
102
|
+
expect(TestConfigScriptConfig).not_to have_received(:new).with(timestamp)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
it "calls the up command on each script item" do
|
108
|
+
scripts.each do |script|
|
109
|
+
if script[:run]
|
110
|
+
expect(script[:script]).to have_received(:run).with(:up)
|
111
|
+
else
|
112
|
+
expect(script[:script]).not_to have_received(:run)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
it "outputs the name of the scripts that it is running" do
|
118
|
+
scripts.each do |script|
|
119
|
+
if script[:run]
|
120
|
+
expect(klass).to have_received(:puts).with("Running #{script[:filename]}")
|
121
|
+
else
|
122
|
+
expect(klass).not_to have_received(:puts).with("Running #{script[:filename]}")
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
context "with no problems running the scripts" do
|
129
|
+
it_behaves_like "ran scripts"
|
130
|
+
|
131
|
+
before do
|
132
|
+
klass.run_pending_scripts
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context "with a problems running the scripts" do
|
137
|
+
it_behaves_like "ran scripts"
|
138
|
+
|
139
|
+
before do
|
140
|
+
script2.stub(:run).and_raise 'Error in script'
|
141
|
+
scripts[2][:run] = false
|
142
|
+
begin
|
143
|
+
klass.run_pending_scripts
|
144
|
+
rescue
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "with a class name it cannot find" do
|
150
|
+
let(:bad_filename) { "20140208170000_missing_class" }
|
151
|
+
|
152
|
+
before do
|
153
|
+
scripts[1][:run] = false
|
154
|
+
scripts[2][:run] = false
|
155
|
+
klass.stub pending_scripts: [script_filenames[0], bad_filename, script_filenames[1], script_filenames[2]]
|
156
|
+
klass.run_pending_scripts
|
157
|
+
end
|
158
|
+
|
159
|
+
it_behaves_like "ran scripts"
|
160
|
+
|
161
|
+
it "requires the path for the bad script" do
|
162
|
+
path = Rails.root.join("db", "config_scripts", "#{bad_filename}.rb")
|
163
|
+
expect(klass).to have_received(:require).with(path)
|
164
|
+
end
|
165
|
+
|
166
|
+
it "outputs a name error for the missing class" do
|
167
|
+
expect(klass).to have_received(:puts).with("Aborting: could not find class MissingClassConfig")
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe "list_pending_scripts" do
|
173
|
+
before do
|
174
|
+
klass.stub pending_scripts: ['script1.rb', 'script2.rb']
|
175
|
+
klass.stub :puts
|
176
|
+
klass.list_pending_scripts
|
177
|
+
end
|
178
|
+
|
179
|
+
it "prints out the name of each script" do
|
180
|
+
expect(klass).to have_received(:puts).with('script1.rb')
|
181
|
+
expect(klass).to have_received(:puts).with('script2.rb')
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe "creating" do
|
187
|
+
let(:timestamp) { '20140101153500' }
|
188
|
+
subject { klass.new(timestamp) }
|
189
|
+
|
190
|
+
it "sets the timestamp" do
|
191
|
+
expect(subject.timestamp).to eq timestamp
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe "running" do
|
196
|
+
let(:timestamp) { 1.day.ago.to_s(:number)}
|
197
|
+
let(:script) { ConfigScripts::Scripts::Script.new(timestamp) }
|
198
|
+
|
199
|
+
describe "up" do
|
200
|
+
it "raises an exception" do
|
201
|
+
expect(lambda{script.up}).to raise_exception("Not supported")
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
describe "down" do
|
206
|
+
it "raises an exception" do
|
207
|
+
expect(lambda{script.down}).to raise_exception("Not supported")
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
describe "run" do
|
212
|
+
{up: true, down: false}.each do |direction, expect_timestamp|
|
213
|
+
describe "direction" do
|
214
|
+
before do
|
215
|
+
if !expect_timestamp
|
216
|
+
ConfigScripts::Scripts::ScriptHistory.record_timestamp(timestamp)
|
217
|
+
end
|
218
|
+
|
219
|
+
script.stub :puts
|
220
|
+
|
221
|
+
Rails.cache.write("cached_item", "cached_value")
|
222
|
+
end
|
223
|
+
|
224
|
+
context "with a success" do
|
225
|
+
before do
|
226
|
+
script.stub(direction) do
|
227
|
+
Person.create(name: 'John Doe')
|
228
|
+
end
|
229
|
+
script.run(direction)
|
230
|
+
end
|
231
|
+
|
232
|
+
it "performs the changes in the #{direction} method" do
|
233
|
+
expect(Person.count).to eq 1
|
234
|
+
expect(Person.first.name).to eq "John Doe"
|
235
|
+
end
|
236
|
+
|
237
|
+
it "cleares the cache" do
|
238
|
+
expect(Rails.cache.read("cached_item")).to be_nil
|
239
|
+
end
|
240
|
+
|
241
|
+
it "{expect_timestamp ? 'adds' : 'removes'} the timestamp" do
|
242
|
+
expect(ConfigScripts::Scripts::ScriptHistory.script_was_run?(timestamp)).to eq expect_timestamp
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
context "with an exception in the #{direction} method" do
|
247
|
+
before do
|
248
|
+
script.stub(direction) do
|
249
|
+
Person.create(name: 'John Doe')
|
250
|
+
raise
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
it "re-raises the exception" do
|
255
|
+
expect(lambda{script.run(direction)}).to raise_exception
|
256
|
+
end
|
257
|
+
|
258
|
+
it "does not persist the changes in the #{direction} method" do
|
259
|
+
script.run(direction) rescue nil
|
260
|
+
expect(Person.count).to eq 0
|
261
|
+
end
|
262
|
+
|
263
|
+
it "does not clear the cache" do
|
264
|
+
script.run(direction) rescue nil
|
265
|
+
expect(Rails.cache.read('cached_item')).to eq 'cached_value'
|
266
|
+
end
|
267
|
+
|
268
|
+
it "does not #{expect_timestamp ? 'add' : 'remove'} the timestamp" do
|
269
|
+
script.run(direction) rescue nil
|
270
|
+
expect(ConfigScripts::Scripts::ScriptHistory.script_was_run?(timestamp)).not_to eq expect_timestamp
|
271
|
+
end
|
272
|
+
|
273
|
+
it "puts an error out to the logs" do
|
274
|
+
script.run(direction) rescue nil
|
275
|
+
expect(script).to have_received(:puts).with("Error running script for ConfigScripts::Scripts::Script: ")
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|