dump 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.
- data/.autotest +13 -0
- data/.gitignore +12 -0
- data/LICENSE.txt +20 -0
- data/README.markdown +250 -0
- data/dump.gemspec +22 -0
- data/lib/dump.rb +3 -0
- data/lib/dump/capistrano.rb +1 -0
- data/lib/dump/railtie.rb +8 -0
- data/lib/dump_rake.rb +85 -0
- data/lib/dump_rake/archive_tar_minitar_fix.rb +8 -0
- data/lib/dump_rake/assets.rb +22 -0
- data/lib/dump_rake/continious_timeout.rb +38 -0
- data/lib/dump_rake/dump.rb +175 -0
- data/lib/dump_rake/dump_reader.rb +289 -0
- data/lib/dump_rake/dump_writer.rb +119 -0
- data/lib/dump_rake/env.rb +139 -0
- data/lib/dump_rake/env/filter.rb +26 -0
- data/lib/dump_rake/rails_root.rb +12 -0
- data/lib/dump_rake/table_manipulation.rb +131 -0
- data/lib/generators/assets_config/assets_config_generator.rb +16 -0
- data/lib/generators/assets_config/templates/assets +8 -0
- data/lib/tasks/assets.rake +17 -0
- data/lib/tasks/dump.rake +27 -0
- data/recipes/dump.rb +343 -0
- data/script/update_readme +21 -0
- data/spec/.gitignore +1 -0
- data/spec/.tmignore +1 -0
- data/spec/cycle_spec.rb +229 -0
- data/spec/db/database.example.yml +19 -0
- data/spec/db/schema.rb +7 -0
- data/spec/dummy-3.1.3/.gitignore +15 -0
- data/spec/dummy-3.1.3/.rspec +1 -0
- data/spec/dummy-3.1.3/Gemfile +23 -0
- data/spec/dummy-3.1.3/Gemfile.lock +159 -0
- data/spec/dummy-3.1.3/README +261 -0
- data/spec/dummy-3.1.3/Rakefile +7 -0
- data/spec/dummy-3.1.3/app/assets/images/rails.png +0 -0
- data/spec/dummy-3.1.3/app/assets/javascripts/application.js +9 -0
- data/spec/dummy-3.1.3/app/assets/stylesheets/application.css +7 -0
- data/spec/dummy-3.1.3/app/controllers/application_controller.rb +3 -0
- data/spec/dummy-3.1.3/app/helpers/application_helper.rb +2 -0
- data/spec/dummy-3.1.3/app/mailers/.gitkeep +0 -0
- data/spec/dummy-3.1.3/app/models/.gitkeep +0 -0
- data/spec/dummy-3.1.3/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy-3.1.3/config.ru +4 -0
- data/spec/dummy-3.1.3/config/application.rb +54 -0
- data/spec/dummy-3.1.3/config/boot.rb +6 -0
- data/spec/dummy-3.1.3/config/database.yml +25 -0
- data/spec/dummy-3.1.3/config/environment.rb +5 -0
- data/spec/dummy-3.1.3/config/environments/development.rb +30 -0
- data/spec/dummy-3.1.3/config/environments/production.rb +60 -0
- data/spec/dummy-3.1.3/config/environments/test.rb +39 -0
- data/spec/dummy-3.1.3/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy-3.1.3/config/initializers/inflections.rb +10 -0
- data/spec/dummy-3.1.3/config/initializers/mime_types.rb +5 -0
- data/spec/dummy-3.1.3/config/initializers/secret_token.rb +7 -0
- data/spec/dummy-3.1.3/config/initializers/session_store.rb +8 -0
- data/spec/dummy-3.1.3/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy-3.1.3/config/locales/en.yml +5 -0
- data/spec/dummy-3.1.3/config/routes.rb +58 -0
- data/spec/dummy-3.1.3/db/seeds.rb +7 -0
- data/spec/dummy-3.1.3/doc/README_FOR_APP +2 -0
- data/spec/dummy-3.1.3/lib/assets/.gitkeep +0 -0
- data/spec/dummy-3.1.3/lib/tasks/.gitkeep +0 -0
- data/spec/dummy-3.1.3/log/.gitkeep +0 -0
- data/spec/dummy-3.1.3/public/404.html +26 -0
- data/spec/dummy-3.1.3/public/422.html +26 -0
- data/spec/dummy-3.1.3/public/500.html +26 -0
- data/spec/dummy-3.1.3/public/favicon.ico +0 -0
- data/spec/dummy-3.1.3/public/index.html +241 -0
- data/spec/dummy-3.1.3/public/robots.txt +5 -0
- data/spec/dummy-3.1.3/script/rails +6 -0
- data/spec/dummy-3.1.3/spec/spec_helper.rb +32 -0
- data/spec/dummy-3.1.3/vendor/assets/stylesheets/.gitkeep +0 -0
- data/spec/dummy-3.1.3/vendor/plugins/.gitkeep +0 -0
- data/spec/lib/dump_rake/dump_reader_spec.rb +638 -0
- data/spec/lib/dump_rake/dump_spec.rb +291 -0
- data/spec/lib/dump_rake/dump_writer_spec.rb +328 -0
- data/spec/lib/dump_rake/env/filter_spec.rb +56 -0
- data/spec/lib/dump_rake/env_spec.rb +139 -0
- data/spec/lib/dump_rake/rails_root_spec.rb +45 -0
- data/spec/lib/dump_rake/table_manipulation_spec.rb +256 -0
- data/spec/lib/dump_rake_spec.rb +326 -0
- data/spec/recipes/dump_spec.rb +553 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +34 -0
- data/spec/tasks/assets_spec.rb +92 -0
- data/spec/tasks/dump_spec.rb +107 -0
- metadata +272 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
|
5
|
+
<style type="text/css">
|
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
|
7
|
+
div.dialog {
|
|
8
|
+
width: 25em;
|
|
9
|
+
padding: 0 4em;
|
|
10
|
+
margin: 4em auto 0 auto;
|
|
11
|
+
border: 1px solid #ccc;
|
|
12
|
+
border-right-color: #999;
|
|
13
|
+
border-bottom-color: #999;
|
|
14
|
+
}
|
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<!-- This file lives in public/422.html -->
|
|
21
|
+
<div class="dialog">
|
|
22
|
+
<h1>The change you wanted was rejected.</h1>
|
|
23
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
|
24
|
+
</div>
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
|
5
|
+
<style type="text/css">
|
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
|
7
|
+
div.dialog {
|
|
8
|
+
width: 25em;
|
|
9
|
+
padding: 0 4em;
|
|
10
|
+
margin: 4em auto 0 auto;
|
|
11
|
+
border: 1px solid #ccc;
|
|
12
|
+
border-right-color: #999;
|
|
13
|
+
border-bottom-color: #999;
|
|
14
|
+
}
|
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<!-- This file lives in public/500.html -->
|
|
21
|
+
<div class="dialog">
|
|
22
|
+
<h1>We're sorry, but something went wrong.</h1>
|
|
23
|
+
<p>We've been notified about this issue and we'll take a look at it shortly.</p>
|
|
24
|
+
</div>
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
|
File without changes
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>Ruby on Rails: Welcome aboard</title>
|
|
5
|
+
<style type="text/css" media="screen">
|
|
6
|
+
body {
|
|
7
|
+
margin: 0;
|
|
8
|
+
margin-bottom: 25px;
|
|
9
|
+
padding: 0;
|
|
10
|
+
background-color: #f0f0f0;
|
|
11
|
+
font-family: "Lucida Grande", "Bitstream Vera Sans", "Verdana";
|
|
12
|
+
font-size: 13px;
|
|
13
|
+
color: #333;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
h1 {
|
|
17
|
+
font-size: 28px;
|
|
18
|
+
color: #000;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
a {color: #03c}
|
|
22
|
+
a:hover {
|
|
23
|
+
background-color: #03c;
|
|
24
|
+
color: white;
|
|
25
|
+
text-decoration: none;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
#page {
|
|
30
|
+
background-color: #f0f0f0;
|
|
31
|
+
width: 750px;
|
|
32
|
+
margin: 0;
|
|
33
|
+
margin-left: auto;
|
|
34
|
+
margin-right: auto;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
#content {
|
|
38
|
+
float: left;
|
|
39
|
+
background-color: white;
|
|
40
|
+
border: 3px solid #aaa;
|
|
41
|
+
border-top: none;
|
|
42
|
+
padding: 25px;
|
|
43
|
+
width: 500px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
#sidebar {
|
|
47
|
+
float: right;
|
|
48
|
+
width: 175px;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
#footer {
|
|
52
|
+
clear: both;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
#header, #about, #getting-started {
|
|
56
|
+
padding-left: 75px;
|
|
57
|
+
padding-right: 30px;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
#header {
|
|
62
|
+
background-image: url("/assets/rails.png");
|
|
63
|
+
background-repeat: no-repeat;
|
|
64
|
+
background-position: top left;
|
|
65
|
+
height: 64px;
|
|
66
|
+
}
|
|
67
|
+
#header h1, #header h2 {margin: 0}
|
|
68
|
+
#header h2 {
|
|
69
|
+
color: #888;
|
|
70
|
+
font-weight: normal;
|
|
71
|
+
font-size: 16px;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
#about h3 {
|
|
76
|
+
margin: 0;
|
|
77
|
+
margin-bottom: 10px;
|
|
78
|
+
font-size: 14px;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
#about-content {
|
|
82
|
+
background-color: #ffd;
|
|
83
|
+
border: 1px solid #fc0;
|
|
84
|
+
margin-left: -55px;
|
|
85
|
+
margin-right: -10px;
|
|
86
|
+
}
|
|
87
|
+
#about-content table {
|
|
88
|
+
margin-top: 10px;
|
|
89
|
+
margin-bottom: 10px;
|
|
90
|
+
font-size: 11px;
|
|
91
|
+
border-collapse: collapse;
|
|
92
|
+
}
|
|
93
|
+
#about-content td {
|
|
94
|
+
padding: 10px;
|
|
95
|
+
padding-top: 3px;
|
|
96
|
+
padding-bottom: 3px;
|
|
97
|
+
}
|
|
98
|
+
#about-content td.name {color: #555}
|
|
99
|
+
#about-content td.value {color: #000}
|
|
100
|
+
|
|
101
|
+
#about-content ul {
|
|
102
|
+
padding: 0;
|
|
103
|
+
list-style-type: none;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
#about-content.failure {
|
|
107
|
+
background-color: #fcc;
|
|
108
|
+
border: 1px solid #f00;
|
|
109
|
+
}
|
|
110
|
+
#about-content.failure p {
|
|
111
|
+
margin: 0;
|
|
112
|
+
padding: 10px;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
#getting-started {
|
|
117
|
+
border-top: 1px solid #ccc;
|
|
118
|
+
margin-top: 25px;
|
|
119
|
+
padding-top: 15px;
|
|
120
|
+
}
|
|
121
|
+
#getting-started h1 {
|
|
122
|
+
margin: 0;
|
|
123
|
+
font-size: 20px;
|
|
124
|
+
}
|
|
125
|
+
#getting-started h2 {
|
|
126
|
+
margin: 0;
|
|
127
|
+
font-size: 14px;
|
|
128
|
+
font-weight: normal;
|
|
129
|
+
color: #333;
|
|
130
|
+
margin-bottom: 25px;
|
|
131
|
+
}
|
|
132
|
+
#getting-started ol {
|
|
133
|
+
margin-left: 0;
|
|
134
|
+
padding-left: 0;
|
|
135
|
+
}
|
|
136
|
+
#getting-started li {
|
|
137
|
+
font-size: 18px;
|
|
138
|
+
color: #888;
|
|
139
|
+
margin-bottom: 25px;
|
|
140
|
+
}
|
|
141
|
+
#getting-started li h2 {
|
|
142
|
+
margin: 0;
|
|
143
|
+
font-weight: normal;
|
|
144
|
+
font-size: 18px;
|
|
145
|
+
color: #333;
|
|
146
|
+
}
|
|
147
|
+
#getting-started li p {
|
|
148
|
+
color: #555;
|
|
149
|
+
font-size: 13px;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
#sidebar ul {
|
|
154
|
+
margin-left: 0;
|
|
155
|
+
padding-left: 0;
|
|
156
|
+
}
|
|
157
|
+
#sidebar ul h3 {
|
|
158
|
+
margin-top: 25px;
|
|
159
|
+
font-size: 16px;
|
|
160
|
+
padding-bottom: 10px;
|
|
161
|
+
border-bottom: 1px solid #ccc;
|
|
162
|
+
}
|
|
163
|
+
#sidebar li {
|
|
164
|
+
list-style-type: none;
|
|
165
|
+
}
|
|
166
|
+
#sidebar ul.links li {
|
|
167
|
+
margin-bottom: 5px;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.filename {
|
|
171
|
+
font-style: italic;
|
|
172
|
+
}
|
|
173
|
+
</style>
|
|
174
|
+
<script type="text/javascript">
|
|
175
|
+
function about() {
|
|
176
|
+
info = document.getElementById('about-content');
|
|
177
|
+
if (window.XMLHttpRequest)
|
|
178
|
+
{ xhr = new XMLHttpRequest(); }
|
|
179
|
+
else
|
|
180
|
+
{ xhr = new ActiveXObject("Microsoft.XMLHTTP"); }
|
|
181
|
+
xhr.open("GET","rails/info/properties",false);
|
|
182
|
+
xhr.send("");
|
|
183
|
+
info.innerHTML = xhr.responseText;
|
|
184
|
+
info.style.display = 'block'
|
|
185
|
+
}
|
|
186
|
+
</script>
|
|
187
|
+
</head>
|
|
188
|
+
<body>
|
|
189
|
+
<div id="page">
|
|
190
|
+
<div id="sidebar">
|
|
191
|
+
<ul id="sidebar-items">
|
|
192
|
+
<li>
|
|
193
|
+
<h3>Browse the documentation</h3>
|
|
194
|
+
<ul class="links">
|
|
195
|
+
<li><a href="http://guides.rubyonrails.org/">Rails Guides</a></li>
|
|
196
|
+
<li><a href="http://api.rubyonrails.org/">Rails API</a></li>
|
|
197
|
+
<li><a href="http://www.ruby-doc.org/core/">Ruby core</a></li>
|
|
198
|
+
<li><a href="http://www.ruby-doc.org/stdlib/">Ruby standard library</a></li>
|
|
199
|
+
</ul>
|
|
200
|
+
</li>
|
|
201
|
+
</ul>
|
|
202
|
+
</div>
|
|
203
|
+
|
|
204
|
+
<div id="content">
|
|
205
|
+
<div id="header">
|
|
206
|
+
<h1>Welcome aboard</h1>
|
|
207
|
+
<h2>You’re riding Ruby on Rails!</h2>
|
|
208
|
+
</div>
|
|
209
|
+
|
|
210
|
+
<div id="about">
|
|
211
|
+
<h3><a href="rails/info/properties" onclick="about(); return false">About your application’s environment</a></h3>
|
|
212
|
+
<div id="about-content" style="display: none"></div>
|
|
213
|
+
</div>
|
|
214
|
+
|
|
215
|
+
<div id="getting-started">
|
|
216
|
+
<h1>Getting started</h1>
|
|
217
|
+
<h2>Here’s how to get rolling:</h2>
|
|
218
|
+
|
|
219
|
+
<ol>
|
|
220
|
+
<li>
|
|
221
|
+
<h2>Use <code>rails generate</code> to create your models and controllers</h2>
|
|
222
|
+
<p>To see all available options, run it without parameters.</p>
|
|
223
|
+
</li>
|
|
224
|
+
|
|
225
|
+
<li>
|
|
226
|
+
<h2>Set up a default route and remove <span class="filename">public/index.html</span></h2>
|
|
227
|
+
<p>Routes are set up in <span class="filename">config/routes.rb</span>.</p>
|
|
228
|
+
</li>
|
|
229
|
+
|
|
230
|
+
<li>
|
|
231
|
+
<h2>Create your database</h2>
|
|
232
|
+
<p>Run <code>rake db:create</code> to create your database. If you're not using SQLite (the default), edit <span class="filename">config/database.yml</span> with your username and password.</p>
|
|
233
|
+
</li>
|
|
234
|
+
</ol>
|
|
235
|
+
</div>
|
|
236
|
+
</div>
|
|
237
|
+
|
|
238
|
+
<div id="footer"> </div>
|
|
239
|
+
</div>
|
|
240
|
+
</body>
|
|
241
|
+
</html>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
|
3
|
+
|
|
4
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
|
5
|
+
require File.expand_path('../../config/boot', __FILE__)
|
|
6
|
+
require 'rails/commands'
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
|
2
|
+
ENV["RAILS_ENV"] ||= 'test'
|
|
3
|
+
require File.expand_path("../../config/environment", __FILE__)
|
|
4
|
+
require 'rspec/rails'
|
|
5
|
+
require 'rspec/autorun'
|
|
6
|
+
|
|
7
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
|
8
|
+
# in spec/support/ and its subdirectories.
|
|
9
|
+
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
|
|
10
|
+
|
|
11
|
+
RSpec.configure do |config|
|
|
12
|
+
# ## Mock Framework
|
|
13
|
+
#
|
|
14
|
+
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
|
|
15
|
+
#
|
|
16
|
+
# config.mock_with :mocha
|
|
17
|
+
# config.mock_with :flexmock
|
|
18
|
+
# config.mock_with :rr
|
|
19
|
+
|
|
20
|
+
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
|
|
21
|
+
config.fixture_path = "#{::Rails.root}/spec/fixtures"
|
|
22
|
+
|
|
23
|
+
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
|
24
|
+
# examples within a transaction, remove the following line or assign false
|
|
25
|
+
# instead of true.
|
|
26
|
+
config.use_transactional_fixtures = true
|
|
27
|
+
|
|
28
|
+
# If true, the base class of anonymous controllers will be inferred
|
|
29
|
+
# automatically. This will be the default behavior in future versions of
|
|
30
|
+
# rspec-rails.
|
|
31
|
+
config.infer_base_class_for_anonymous_controllers = false
|
|
32
|
+
end
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,638 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
|
2
|
+
|
|
3
|
+
require File.dirname(__FILE__) + '/../../../lib/dump_rake'
|
|
4
|
+
|
|
5
|
+
require 'active_record/migration'
|
|
6
|
+
|
|
7
|
+
def object_of_length(required_length)
|
|
8
|
+
LengthConstraint.new(required_length)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class LengthConstraint
|
|
12
|
+
def initialize(required_length)
|
|
13
|
+
@required_length = required_length
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def ==(value)
|
|
17
|
+
@required_length == value.length
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
DumpReader = DumpRake::DumpReader
|
|
22
|
+
describe DumpReader do
|
|
23
|
+
describe "restore" do
|
|
24
|
+
it "should create selves instance and open" do
|
|
25
|
+
@dump = mock('dump')
|
|
26
|
+
@dump.should_receive(:open)
|
|
27
|
+
DumpReader.should_receive(:new).with('/abc/123.tmp').and_return(@dump)
|
|
28
|
+
DumpReader.restore('/abc/123.tmp')
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "should call dump subroutines" do
|
|
32
|
+
@dump = mock('dump')
|
|
33
|
+
@dump.stub!(:open).and_yield(@dump)
|
|
34
|
+
DumpReader.stub!(:new).and_return(@dump)
|
|
35
|
+
|
|
36
|
+
@dump.should_receive(:read_config).ordered
|
|
37
|
+
@dump.should_receive(:migrate_down).ordered
|
|
38
|
+
@dump.should_receive(:read_schema).ordered
|
|
39
|
+
@dump.should_receive(:read_tables).ordered
|
|
40
|
+
@dump.should_receive(:read_assets).ordered
|
|
41
|
+
|
|
42
|
+
DumpReader.restore('/abc/123.tmp')
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
describe "summary" do
|
|
47
|
+
Summary = DumpReader::Summary
|
|
48
|
+
describe Summary do
|
|
49
|
+
it "should format text" do
|
|
50
|
+
@summary = Summary.new
|
|
51
|
+
@summary.header 'One'
|
|
52
|
+
@summary.data(%w[fff ggg jjj ppp qqq www])
|
|
53
|
+
@summary.header 'Two'
|
|
54
|
+
@summary.data([['fff', 234], ['ggg', 321], ['jjj', 666], ['ppp', 678], ['qqq', 123], ['www', 345]].map{ |entry| entry.join(': ') })
|
|
55
|
+
|
|
56
|
+
output = <<-TEXT
|
|
57
|
+
One:
|
|
58
|
+
fff
|
|
59
|
+
ggg
|
|
60
|
+
jjj
|
|
61
|
+
ppp
|
|
62
|
+
qqq
|
|
63
|
+
www
|
|
64
|
+
Two:
|
|
65
|
+
fff: 234
|
|
66
|
+
ggg: 321
|
|
67
|
+
jjj: 666
|
|
68
|
+
ppp: 678
|
|
69
|
+
qqq: 123
|
|
70
|
+
www: 345
|
|
71
|
+
TEXT
|
|
72
|
+
"#{@summary}".should == output.gsub(/#{output[/^\s+/]}/, ' ')
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "should pluralize" do
|
|
76
|
+
Summary.pluralize(0, 'file').should == '0 files'
|
|
77
|
+
Summary.pluralize(1, 'file').should == '1 file'
|
|
78
|
+
Summary.pluralize(10, 'file').should == '10 files'
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "should create selves instance and open" do
|
|
83
|
+
@dump = mock('dump')
|
|
84
|
+
@dump.should_receive(:open)
|
|
85
|
+
DumpReader.should_receive(:new).with('/abc/123.tmp').and_return(@dump)
|
|
86
|
+
DumpReader.summary('/abc/123.tmp')
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
{
|
|
90
|
+
{'path/a' => {:total => 20, :files => 10}, 'path/b' => {:total => 20, :files => 10}} => ['path/a: 10 files (20 entries total)', 'path/b: 10 files (20 entries total)'],
|
|
91
|
+
{'path/a' => 10, 'path/b' => 20} => ['path/a: 10 entries', 'path/b: 20 entries'],
|
|
92
|
+
%w[path/a path/b] => %w[path/a path/b],
|
|
93
|
+
}.each do |assets, formatted_assets|
|
|
94
|
+
it "should call dump subroutines and create summary" do
|
|
95
|
+
tables = {'a' => 10, 'b' => 20, 'c' => 666}
|
|
96
|
+
formatted_tables = ['a: 10 rows', 'b: 20 rows', 'c: 666 rows']
|
|
97
|
+
|
|
98
|
+
@dump = mock('dump')
|
|
99
|
+
@dump.stub!(:config).and_return(:tables => tables, :assets => assets)
|
|
100
|
+
@dump.stub!(:open).and_yield(@dump)
|
|
101
|
+
DumpReader.stub!(:new).and_return(@dump)
|
|
102
|
+
@dump.should_receive(:read_config)
|
|
103
|
+
|
|
104
|
+
@summary = mock('summary')
|
|
105
|
+
@summary.should_receive(:header).with('Tables')
|
|
106
|
+
@summary.should_receive(:data).with(formatted_tables)
|
|
107
|
+
@summary.should_receive(:header).with('Assets')
|
|
108
|
+
@summary.should_receive(:data).with(formatted_assets)
|
|
109
|
+
Summary.stub!(:new).and_return(@summary)
|
|
110
|
+
|
|
111
|
+
DumpReader.summary('/abc/123.tmp').should == @summary
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it "should call dump subroutines and create summary with schema" do
|
|
116
|
+
tables = {'a' => 10, 'b' => 20, 'c' => 666}
|
|
117
|
+
formatted_tables = ['a: 10 rows', 'b: 20 rows', 'c: 666 rows']
|
|
118
|
+
assets = formatted_assets = %w[path/a path/b]
|
|
119
|
+
|
|
120
|
+
schema = mock('schema')
|
|
121
|
+
schema_lines = mock('schema_lines')
|
|
122
|
+
schema.should_receive(:split).with("\n").and_return(schema_lines)
|
|
123
|
+
|
|
124
|
+
@dump = mock('dump')
|
|
125
|
+
@dump.stub!(:config).and_return(:tables => tables, :assets => assets)
|
|
126
|
+
@dump.stub!(:open).and_yield(@dump)
|
|
127
|
+
@dump.stub!(:schema).and_return(schema)
|
|
128
|
+
DumpReader.stub!(:new).and_return(@dump)
|
|
129
|
+
@dump.should_receive(:read_config)
|
|
130
|
+
|
|
131
|
+
@summary = mock('summary')
|
|
132
|
+
@summary.should_receive(:header).with('Tables')
|
|
133
|
+
@summary.should_receive(:data).with(formatted_tables)
|
|
134
|
+
@summary.should_receive(:header).with('Assets')
|
|
135
|
+
@summary.should_receive(:data).with(formatted_assets)
|
|
136
|
+
@summary.should_receive(:header).with('Schema')
|
|
137
|
+
@summary.should_receive(:data).with(schema_lines)
|
|
138
|
+
Summary.stub!(:new).and_return(@summary)
|
|
139
|
+
|
|
140
|
+
DumpReader.summary('/abc/123.tmp', :schema => true).should == @summary
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
describe "open" do
|
|
145
|
+
it "should set stream to gzipped tar reader" do
|
|
146
|
+
@gzip = mock('gzip')
|
|
147
|
+
@stream = mock('stream')
|
|
148
|
+
Zlib::GzipReader.should_receive(:open).with(Pathname("123.tgz")).and_yield(@gzip)
|
|
149
|
+
Archive::Tar::Minitar::Input.should_receive(:open).with(@gzip).and_yield(@stream)
|
|
150
|
+
|
|
151
|
+
@dump = DumpReader.new('123.tgz')
|
|
152
|
+
@dump.open do |dump|
|
|
153
|
+
dump.should == @dump
|
|
154
|
+
dump.stream.should == @stream
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
describe "low level" do
|
|
160
|
+
before do
|
|
161
|
+
@e1 = mock('e1', :full_name => 'config', :read => 'config_data')
|
|
162
|
+
@e2 = mock('e2', :full_name => 'first.dump', :read => 'first.dump_data')
|
|
163
|
+
@e3 = mock('e3', :full_name => 'second.dump', :read => 'second.dump_data')
|
|
164
|
+
@stream = [@e1, @e2, @e3]
|
|
165
|
+
@dump = DumpReader.new('123.tgz')
|
|
166
|
+
@dump.stub!(:stream).and_return(@stream)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
describe "find_entry" do
|
|
170
|
+
it "should find first entry in stream equal string" do
|
|
171
|
+
@dump.find_entry('config') do |entry|
|
|
172
|
+
entry.should == @e1
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it "should find first entry in stream matching regexp" do
|
|
177
|
+
@dump.find_entry(/\.dump$/) do |entry|
|
|
178
|
+
entry.should == @e2
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it "should return result of block" do
|
|
183
|
+
@dump.find_entry(/\.dump$/) do |entry|
|
|
184
|
+
'hello'
|
|
185
|
+
end.should == 'hello'
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
describe "read_entry" do
|
|
190
|
+
it "should call find_entry" do
|
|
191
|
+
@dump.should_receive(:find_entry).with('config').and_yield(@e1)
|
|
192
|
+
@dump.read_entry('config')
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
it "should read entries data" do
|
|
196
|
+
@dump.read_entry('config').should == 'config_data'
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
describe "read_entry_to_file" do
|
|
201
|
+
it "should call find_entry" do
|
|
202
|
+
@dump.should_receive(:find_entry).with('config')
|
|
203
|
+
@dump.read_entry_to_file('config')
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
it "should open temp file, write data there, rewind and yield that file" do
|
|
207
|
+
@entry = mock('entry')
|
|
208
|
+
@dump.stub!(:find_entry).and_yield(@entry)
|
|
209
|
+
@temp = mock('temp')
|
|
210
|
+
Tempfile.should_receive(:open).and_yield(@temp)
|
|
211
|
+
|
|
212
|
+
@entry.should_receive(:eof?).and_return(false, false, true)
|
|
213
|
+
@entry.should_receive(:read).with(4096).and_return('a' * 4096, 'b' * 1000)
|
|
214
|
+
@temp.should_receive(:write).with('a' * 4096).ordered
|
|
215
|
+
@temp.should_receive(:write).with('b' * 1000).ordered
|
|
216
|
+
@temp.should_receive(:rewind).ordered
|
|
217
|
+
|
|
218
|
+
@dump.read_entry_to_file('config') do |f|
|
|
219
|
+
f.should == @temp
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
describe "subroutines" do
|
|
226
|
+
before do
|
|
227
|
+
@stream = mock('stream')
|
|
228
|
+
@dump = DumpReader.new('123.tgz')
|
|
229
|
+
@dump.stub!(:stream).and_return(@stream)
|
|
230
|
+
Progress.stub!(:io).and_return(StringIO.new)
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
describe "read_config" do
|
|
234
|
+
it "should read config" do
|
|
235
|
+
@data = {:tables => {:first => 1}, :assets => %w[images videos]}
|
|
236
|
+
@dump.should_receive(:read_entry).with('config').and_return(Marshal.dump(@data))
|
|
237
|
+
|
|
238
|
+
@dump.read_config
|
|
239
|
+
@dump.config.should == @data
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
describe "migrate_down" do
|
|
244
|
+
it "should not invoke rake tasks or find_entry if migrate_down is 0, no or false" do
|
|
245
|
+
Rake::Task.should_not_receive(:[])
|
|
246
|
+
@dump.should_not_receive(:find_entry)
|
|
247
|
+
|
|
248
|
+
DumpRake::Env.with_env(:migrate_down => '0') do
|
|
249
|
+
@dump.migrate_down
|
|
250
|
+
end
|
|
251
|
+
DumpRake::Env.with_env(:migrate_down => 'no') do
|
|
252
|
+
@dump.migrate_down
|
|
253
|
+
end
|
|
254
|
+
DumpRake::Env.with_env(:migrate_down => 'false') do
|
|
255
|
+
@dump.migrate_down
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
it "should invoke db:drop and db:create if migrate_down is reset" do
|
|
260
|
+
@load_task = mock('drop_task')
|
|
261
|
+
@dump_task = mock('create_task')
|
|
262
|
+
Rake::Task.should_receive(:[]).with('db:drop').and_return(@load_task)
|
|
263
|
+
Rake::Task.should_receive(:[]).with('db:create').and_return(@dump_task)
|
|
264
|
+
@load_task.should_receive(:invoke)
|
|
265
|
+
@dump_task.should_receive(:invoke)
|
|
266
|
+
|
|
267
|
+
DumpRake::Env.with_env(:migrate_down => 'reset') do
|
|
268
|
+
@dump.migrate_down
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
[nil, '1'].each do |migrate_down_value|
|
|
273
|
+
describe "when migrate_down is #{migrate_down_value.inspect}" do
|
|
274
|
+
it "should not find_entry if table schema_migrations is not present" do
|
|
275
|
+
@dump.stub!(:avaliable_tables).and_return(%w[first])
|
|
276
|
+
@dump.should_not_receive(:find_entry)
|
|
277
|
+
|
|
278
|
+
DumpRake::Env.with_env(:migrate_down => migrate_down_value) do
|
|
279
|
+
@dump.migrate_down
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
it "should find schema_migrations.dump if table schema_migrations is present" do
|
|
284
|
+
@dump.stub!(:avaliable_tables).and_return(%w[schema_migrations first])
|
|
285
|
+
@dump.should_receive(:find_entry).with('schema_migrations.dump')
|
|
286
|
+
|
|
287
|
+
DumpRake::Env.with_env(:migrate_down => migrate_down_value) do
|
|
288
|
+
@dump.migrate_down
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
it "should call migrate down for each version not present in schema_migrations table" do
|
|
293
|
+
@entry = StringIO.new
|
|
294
|
+
Marshal.dump(['version'], @entry)
|
|
295
|
+
%w[1 2 3 4].each do |i|
|
|
296
|
+
Marshal.dump(i, @entry)
|
|
297
|
+
end
|
|
298
|
+
@entry.rewind
|
|
299
|
+
|
|
300
|
+
@dump.stub!(:avaliable_tables).and_return(%w[schema_migrations first])
|
|
301
|
+
@dump.should_receive(:find_entry).with('schema_migrations.dump').and_yield(@entry)
|
|
302
|
+
@dump.should_receive('table_rows').with('schema_migrations').and_return(%w[1 2 4 5 6 7].map{ |version| {'version' => version} })
|
|
303
|
+
|
|
304
|
+
@versions = []
|
|
305
|
+
@migrate_down_task = mock('migrate_down_task')
|
|
306
|
+
@migrate_down_task.should_receive('invoke').exactly(2).times.with do
|
|
307
|
+
version = DumpRake::Env['VERSION']
|
|
308
|
+
@versions << version
|
|
309
|
+
if version == '6'
|
|
310
|
+
raise ActiveRecord::IrreversibleMigration
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
@migrate_down_task.should_receive('reenable').exactly(3).times
|
|
314
|
+
|
|
315
|
+
$stderr.should_receive('puts').with("Irreversible migration: 6")
|
|
316
|
+
|
|
317
|
+
Rake::Task.should_receive(:[]).with('db:migrate:down').exactly(3).times.and_return(@migrate_down_task)
|
|
318
|
+
|
|
319
|
+
DumpRake::Env.with_env(:migrate_down => migrate_down_value) do
|
|
320
|
+
@dump.migrate_down
|
|
321
|
+
end
|
|
322
|
+
@versions.should == %w[5 6 7].reverse
|
|
323
|
+
end
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
describe "read_schema" do
|
|
329
|
+
before do
|
|
330
|
+
@task = mock('task')
|
|
331
|
+
Rake::Task.stub!(:[]).and_return(@task)
|
|
332
|
+
@task.stub!(:invoke)
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
it "should read schema.rb to temp file" do
|
|
336
|
+
@dump.should_receive(:read_entry_to_file).with('schema.rb')
|
|
337
|
+
@dump.read_schema
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
it "should set ENV SCHEMA to temp files path" do
|
|
341
|
+
@file = mock('tempfile', :path => '/temp/123-arst')
|
|
342
|
+
@dump.stub!(:read_entry_to_file).and_yield(@file)
|
|
343
|
+
|
|
344
|
+
DumpRake::Env.should_receive(:with_env).with('SCHEMA' => '/temp/123-arst')
|
|
345
|
+
@dump.read_schema
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
it "should call task db:schema:load and db:schema:dump" do
|
|
349
|
+
@file = mock('tempfile', :path => '/temp/123-arst')
|
|
350
|
+
@dump.stub!(:read_entry_to_file).and_yield(@file)
|
|
351
|
+
|
|
352
|
+
@load_task = mock('load_task')
|
|
353
|
+
@dump_task = mock('dump_task')
|
|
354
|
+
Rake::Task.should_receive(:[]).with('db:schema:load').and_return(@load_task)
|
|
355
|
+
Rake::Task.should_receive(:[]).with('db:schema:dump').and_return(@dump_task)
|
|
356
|
+
@load_task.should_receive(:invoke)
|
|
357
|
+
@dump_task.should_receive(:invoke)
|
|
358
|
+
|
|
359
|
+
@dump.read_schema
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
describe "schema" do
|
|
364
|
+
it "should read schema" do
|
|
365
|
+
@data = %q{create table, rows, etc...}
|
|
366
|
+
@dump.should_receive(:read_entry).with('schema.rb').and_return(@data)
|
|
367
|
+
@dump.schema.should == @data
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
describe "read_tables" do
|
|
372
|
+
it "should verify connection" do
|
|
373
|
+
@dump.stub!(:config).and_return({:tables => []})
|
|
374
|
+
@dump.should_receive(:verify_connection)
|
|
375
|
+
@dump.read_tables
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
it "should call read_table for each table in config" do
|
|
379
|
+
@dump.stub!(:verify_connection)
|
|
380
|
+
@dump.stub!(:config).and_return({:tables => {'first' => 1, 'second' => 3}})
|
|
381
|
+
|
|
382
|
+
@dump.should_receive(:read_table).with('first', 1)
|
|
383
|
+
@dump.should_receive(:read_table).with('second', 3)
|
|
384
|
+
|
|
385
|
+
@dump.read_tables
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
describe "read_table" do
|
|
390
|
+
it "should not read table if no entry found for table" do
|
|
391
|
+
@dump.should_receive(:find_entry).with('first.dump').and_return(nil)
|
|
392
|
+
@dump.should_not_receive(:quote_table_name)
|
|
393
|
+
@dump.read_table('first', 10)
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
it "should clear table and read table if entry found for table" do
|
|
397
|
+
@entry = mock('entry', :to_str => Marshal.dump('data'), :eof? => true)
|
|
398
|
+
@dump.should_receive(:columns_insert_sql).with('data')
|
|
399
|
+
@dump.should_receive(:find_entry).with('first.dump').and_yield(@entry)
|
|
400
|
+
@dump.should_receive(:quote_table_name).with('first').and_return('`first`')
|
|
401
|
+
@dump.should_receive(:clear_table).with('`first`')
|
|
402
|
+
@dump.read_table('first', 10)
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
it "should clear schema table before writing" do
|
|
406
|
+
@entry = mock('entry', :to_str => Marshal.dump('data'), :eof? => true)
|
|
407
|
+
@dump.should_receive(:columns_insert_sql).with('data')
|
|
408
|
+
@dump.should_receive(:find_entry).with('schema_migrations.dump').and_yield(@entry)
|
|
409
|
+
@dump.should_receive(:quote_table_name).with('schema_migrations').and_return('`schema_migrations`')
|
|
410
|
+
@dump.should_receive(:clear_table).with('`schema_migrations`')
|
|
411
|
+
@dump.read_table('schema_migrations', 10)
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
describe "reading/writing data" do
|
|
415
|
+
def create_entry(rows_count)
|
|
416
|
+
@entry = StringIO.new
|
|
417
|
+
|
|
418
|
+
@columns = %w[id name]
|
|
419
|
+
@rows = []
|
|
420
|
+
Marshal.dump(@columns, @entry)
|
|
421
|
+
(1..rows_count).each do |i|
|
|
422
|
+
row = [i, "entry#{i}"]
|
|
423
|
+
@rows << row
|
|
424
|
+
Marshal.dump(row, @entry)
|
|
425
|
+
end
|
|
426
|
+
@entry.rewind
|
|
427
|
+
|
|
428
|
+
@dump.stub!(:find_entry).and_yield(@entry)
|
|
429
|
+
end
|
|
430
|
+
it "should read to eof" do
|
|
431
|
+
create_entry(2500)
|
|
432
|
+
@dump.stub!(:clear_table)
|
|
433
|
+
@dump.stub!(:insert_into_table)
|
|
434
|
+
@dump.read_table('first', 2500)
|
|
435
|
+
@entry.eof?.should be_true
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
it "should try to insert rows in slices of 1000 rows" do
|
|
439
|
+
create_entry(2500)
|
|
440
|
+
@dump.stub!(:clear_table)
|
|
441
|
+
@dump.should_receive(:insert_into_table).with(anything, anything, object_of_length(1000)).twice
|
|
442
|
+
@dump.should_receive(:insert_into_table).with(anything, anything, object_of_length(500)).once
|
|
443
|
+
|
|
444
|
+
@dump.read_table('first', 2500)
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
it "should try to insert row by row if slice method fails" do
|
|
448
|
+
create_entry(2500)
|
|
449
|
+
@dump.stub!(:clear_table)
|
|
450
|
+
@dump.should_receive(:insert_into_table).with(anything, anything, kind_of(Array)).exactly(3).times.and_raise('sql error')
|
|
451
|
+
@dump.should_receive(:insert_into_table).with(anything, anything, kind_of(String)).exactly(2500).times
|
|
452
|
+
@dump.read_table('first', 2500)
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
it "should quote table, columns and values and send them to insert_into_table" do
|
|
456
|
+
create_entry(100)
|
|
457
|
+
@dump.stub!(:clear_table)
|
|
458
|
+
@dump.should_receive(:quote_table_name).with('first').and_return('`first`')
|
|
459
|
+
@dump.should_receive(:columns_insert_sql).with(@columns).and_return('(`id`, `name`)')
|
|
460
|
+
@rows.each do |row|
|
|
461
|
+
@dump.should_receive(:values_insert_sql).with(row).and_return{ |vs| vs.inspect }
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
@dump.should_receive(:insert_into_table).with('`first`', '(`id`, `name`)', @rows.map(&:inspect))
|
|
465
|
+
@dump.read_table('first', 100)
|
|
466
|
+
end
|
|
467
|
+
end
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
describe "read_assets" do
|
|
471
|
+
before do
|
|
472
|
+
@task = mock('task')
|
|
473
|
+
Rake::Task.stub!(:[]).with('assets:delete').and_return(@task)
|
|
474
|
+
@task.stub!(:invoke)
|
|
475
|
+
@dump.stub!(:assets_root_link).and_yield('/tmp', 'assets')
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
it "should not read assets if config[:assets] is nil" do
|
|
479
|
+
@dump.stub!(:config).and_return({})
|
|
480
|
+
@dump.should_not_receive(:find_entry)
|
|
481
|
+
@dump.read_assets
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
it "should not read assets if config[:assets] is blank" do
|
|
485
|
+
@dump.stub!(:config).and_return({:assets => []})
|
|
486
|
+
@dump.should_not_receive(:find_entry)
|
|
487
|
+
@dump.read_assets
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
describe "deleting existing assets" do
|
|
491
|
+
before do
|
|
492
|
+
@stream.stub!(:each)
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
it "should call assets:delete" do
|
|
496
|
+
@assets = %w[images videos]
|
|
497
|
+
@dump.stub!(:config).and_return({:assets => @assets})
|
|
498
|
+
@dump.stub!(:find_entry)
|
|
499
|
+
|
|
500
|
+
@task.should_receive(:invoke)
|
|
501
|
+
|
|
502
|
+
@dump.read_assets
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
it "should call assets:delete with ASSETS set to config[:assets] joined with :" do
|
|
506
|
+
@assets = %w[images videos]
|
|
507
|
+
@dump.stub!(:config).and_return({:assets => @assets})
|
|
508
|
+
@dump.stub!(:find_entry)
|
|
509
|
+
|
|
510
|
+
def @task.invoke
|
|
511
|
+
DumpRake::Env[:assets].should == 'images:videos'
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
@dump.read_assets
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
describe "when called with restore_assets" do
|
|
518
|
+
it "should delete files and dirs only in requested paths" do
|
|
519
|
+
@assets = %w[images videos]
|
|
520
|
+
@dump.stub!(:config).and_return({:assets => @assets})
|
|
521
|
+
|
|
522
|
+
DumpRake::Assets.should_receive('glob_asset_children').with('images', '**/*').and_return(%w[images images/a.jpg images/b.jpg])
|
|
523
|
+
DumpRake::Assets.should_receive('glob_asset_children').with('videos', '**/*').and_return(%w[videos videos/a.mov])
|
|
524
|
+
|
|
525
|
+
@dump.should_receive('read_asset?').with('images/b.jpg', DumpRake::RailsRoot).ordered.and_return(false)
|
|
526
|
+
@dump.should_receive('read_asset?').with('images/a.jpg', DumpRake::RailsRoot).ordered.and_return(true)
|
|
527
|
+
@dump.should_receive('read_asset?').with('images', DumpRake::RailsRoot).ordered.and_return(true)
|
|
528
|
+
@dump.should_receive('read_asset?').with('videos/a.mov', DumpRake::RailsRoot).ordered.and_return(false)
|
|
529
|
+
@dump.should_receive('read_asset?').with('videos', DumpRake::RailsRoot).ordered.and_return(false)
|
|
530
|
+
|
|
531
|
+
File.should_receive('file?').with('images/a.jpg').and_return(true)
|
|
532
|
+
File.should_receive('unlink').with('images/a.jpg')
|
|
533
|
+
File.should_not_receive('file?').with('images/b.jpg')
|
|
534
|
+
File.should_receive('file?').with('images').and_return(false)
|
|
535
|
+
File.should_receive('directory?').with('images').and_return(true)
|
|
536
|
+
Dir.should_receive('unlink').with('images').and_raise(Errno::ENOTEMPTY)
|
|
537
|
+
|
|
538
|
+
DumpRake::Env.with_env(:restore_assets => 'images/a.*:stylesheets') do
|
|
539
|
+
@dump.read_assets
|
|
540
|
+
end
|
|
541
|
+
end
|
|
542
|
+
end
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
describe "old style" do
|
|
546
|
+
it "should find assets.tar" do
|
|
547
|
+
@assets = %w[images videos]
|
|
548
|
+
@dump.stub!(:config).and_return({:assets => @assets})
|
|
549
|
+
Dir.stub!(:glob).and_return([])
|
|
550
|
+
FileUtils.stub!(:remove_entry)
|
|
551
|
+
@stream.stub!(:each)
|
|
552
|
+
|
|
553
|
+
@dump.should_receive(:find_entry).with('assets.tar')
|
|
554
|
+
@dump.read_assets
|
|
555
|
+
end
|
|
556
|
+
|
|
557
|
+
[
|
|
558
|
+
%w[images videos],
|
|
559
|
+
{'images' => 0, 'videos' => 0},
|
|
560
|
+
{'images' => {:files => 0, :total => 0}, 'videos' => {:files => 0, :total => 0}},
|
|
561
|
+
].each do |assets|
|
|
562
|
+
it "should rewrite rewind method to empty method - to not raise exception, open tar and extract each entry" do
|
|
563
|
+
@dump.stub!(:config).and_return({:assets => assets})
|
|
564
|
+
Dir.stub!(:glob).and_return([])
|
|
565
|
+
FileUtils.stub!(:remove_entry)
|
|
566
|
+
|
|
567
|
+
@assets_tar = mock('assets_tar')
|
|
568
|
+
@assets_tar.stub!(:rewind).and_raise('hehe - we want to rewind to center of gzip')
|
|
569
|
+
@dump.stub!(:find_entry).and_yield(@assets_tar)
|
|
570
|
+
|
|
571
|
+
@inp = mock('inp')
|
|
572
|
+
each_excpectation = @inp.should_receive(:each)
|
|
573
|
+
@entries = %w[a b c d].map do |s|
|
|
574
|
+
file = mock("file_#{s}")
|
|
575
|
+
each_excpectation.and_yield(file)
|
|
576
|
+
@inp.should_receive(:extract_entry).with(DumpRake::RailsRoot, file)
|
|
577
|
+
file
|
|
578
|
+
end
|
|
579
|
+
Archive::Tar::Minitar.should_receive(:open).with(@assets_tar).and_yield(@inp)
|
|
580
|
+
|
|
581
|
+
@dump.read_assets
|
|
582
|
+
end
|
|
583
|
+
end
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
describe "new style" do
|
|
587
|
+
before do
|
|
588
|
+
@dump.should_receive(:find_entry).with('assets.tar')
|
|
589
|
+
end
|
|
590
|
+
|
|
591
|
+
[
|
|
592
|
+
%w[images videos],
|
|
593
|
+
{'images' => 0, 'videos' => 0},
|
|
594
|
+
{'images' => {:files => 0, :total => 0}, 'videos' => {:files => 0, :total => 0}},
|
|
595
|
+
].each do |assets|
|
|
596
|
+
it "should extract each entry" do
|
|
597
|
+
@dump.stub!(:config).and_return({:assets => assets})
|
|
598
|
+
Dir.stub!(:glob).and_return([])
|
|
599
|
+
FileUtils.stub!(:remove_entry)
|
|
600
|
+
|
|
601
|
+
@dump.should_receive(:assets_root_link).and_yield('/tmp/abc', 'assets')
|
|
602
|
+
each_excpectation = @stream.should_receive(:each)
|
|
603
|
+
@entries = %w[a b c d].map do |s|
|
|
604
|
+
file = mock("file_#{s}", :full_name => "assets/#{s}")
|
|
605
|
+
each_excpectation.and_yield(file)
|
|
606
|
+
@stream.should_receive(:extract_entry).with('/tmp/abc', file)
|
|
607
|
+
file
|
|
608
|
+
end
|
|
609
|
+
other_file = mock('other_file', :full_name => 'other_file')
|
|
610
|
+
each_excpectation.and_yield(other_file)
|
|
611
|
+
@stream.should_not_receive(:extract_entry).with('/tmp/abc', other_file)
|
|
612
|
+
|
|
613
|
+
@dump.read_assets
|
|
614
|
+
end
|
|
615
|
+
end
|
|
616
|
+
end
|
|
617
|
+
end
|
|
618
|
+
|
|
619
|
+
describe "read_asset?" do
|
|
620
|
+
it "should create filter and call custom_pass? on it" do
|
|
621
|
+
@filter = mock('filter')
|
|
622
|
+
@filter.stub!('custom_pass?')
|
|
623
|
+
|
|
624
|
+
DumpRake::Env.should_receive('filter').with(:restore_assets, DumpRake::Assets::SPLITTER).and_return(@filter)
|
|
625
|
+
|
|
626
|
+
@dump.read_asset?('a', 'b')
|
|
627
|
+
end
|
|
628
|
+
|
|
629
|
+
it "should test path usint fnmatch" do
|
|
630
|
+
DumpRake::Env.with_env(:restore_assets => '[a-b]') do
|
|
631
|
+
@dump.read_asset?('x/a', 'x').should be_true
|
|
632
|
+
@dump.read_asset?('x/b/file', 'x').should be_true
|
|
633
|
+
@dump.read_asset?('x/c', 'x').should be_false
|
|
634
|
+
end
|
|
635
|
+
end
|
|
636
|
+
end
|
|
637
|
+
end
|
|
638
|
+
end
|