uploader 0.1.10 → 0.1.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. data/README.rdoc +2 -1
  2. data/Rakefile +4 -3
  3. data/VERSION +1 -1
  4. data/test/rails_root/.gitignore +8 -0
  5. data/test/rails_root/.rake_tasks +103 -0
  6. data/test/rails_root/Capfile +3 -0
  7. data/test/rails_root/Rakefile +10 -0
  8. data/test/rails_root/app/controllers/application_controller.rb +4 -0
  9. data/test/rails_root/app/controllers/uploads_controller.rb +18 -0
  10. data/test/rails_root/app/models/.keep +0 -0
  11. data/test/rails_root/app/models/upload.rb +28 -0
  12. data/test/rails_root/app/models/user.rb +9 -0
  13. data/test/rails_root/app/views/layouts/application.html.erb +18 -0
  14. data/test/rails_root/config/amazon_s3.yml +14 -0
  15. data/test/rails_root/config/boot.rb +109 -0
  16. data/test/rails_root/config/database.yml +14 -0
  17. data/test/rails_root/config/environment.rb +23 -0
  18. data/test/rails_root/config/environments/development.rb +19 -0
  19. data/test/rails_root/config/environments/production.rb +1 -0
  20. data/test/rails_root/config/environments/test.rb +33 -0
  21. data/test/rails_root/config/global_config.yml +18 -0
  22. data/test/rails_root/config/initializers/inflections.rb +10 -0
  23. data/test/rails_root/config/initializers/mime_types.rb +5 -0
  24. data/test/rails_root/config/initializers/requires.rb +13 -0
  25. data/test/rails_root/config/initializers/s3_credentials.rb +9 -0
  26. data/test/rails_root/config/initializers/session_store.rb +8 -0
  27. data/test/rails_root/config/routes.rb +6 -0
  28. data/test/rails_root/db/.keep +0 -0
  29. data/test/rails_root/db/migrate/20090517040220_create_uploads.rb +38 -0
  30. data/test/rails_root/db/migrate/20090602041838_create_users.rb +12 -0
  31. data/test/rails_root/db/schema.rb +47 -0
  32. data/test/rails_root/features/step_definitions/webrat_steps.rb +99 -0
  33. data/test/rails_root/features/support/env.rb +14 -0
  34. data/test/rails_root/public/.htaccess +40 -0
  35. data/test/rails_root/public/404.html +30 -0
  36. data/test/rails_root/public/422.html +30 -0
  37. data/test/rails_root/public/500.html +30 -0
  38. data/test/rails_root/public/dispatch.rb +10 -0
  39. data/test/rails_root/public/favicon.ico +0 -0
  40. data/test/rails_root/public/images/rails.png +0 -0
  41. data/test/rails_root/public/javascripts/application.js +2 -0
  42. data/test/rails_root/public/javascripts/builder.js +136 -0
  43. data/test/rails_root/public/javascripts/controls.js +963 -0
  44. data/test/rails_root/public/javascripts/dragdrop.js +972 -0
  45. data/test/rails_root/public/javascripts/effects.js +1120 -0
  46. data/test/rails_root/public/javascripts/prototype.js +4225 -0
  47. data/test/rails_root/public/javascripts/scriptaculous.js +58 -0
  48. data/test/rails_root/public/javascripts/slider.js +277 -0
  49. data/test/rails_root/public/javascripts/sound.js +60 -0
  50. data/test/rails_root/public/robots.txt +1 -0
  51. data/test/rails_root/public/stylesheets/.keep +0 -0
  52. data/test/rails_root/script/about +3 -0
  53. data/test/rails_root/script/breakpointer +3 -0
  54. data/test/rails_root/script/console +3 -0
  55. data/test/rails_root/script/create_project.rb +52 -0
  56. data/test/rails_root/script/cucumber +7 -0
  57. data/test/rails_root/script/dbconsole +3 -0
  58. data/test/rails_root/script/destroy +3 -0
  59. data/test/rails_root/script/generate +3 -0
  60. data/test/rails_root/script/performance/benchmarker +3 -0
  61. data/test/rails_root/script/performance/profiler +3 -0
  62. data/test/rails_root/script/performance/request +3 -0
  63. data/test/rails_root/script/plugin +3 -0
  64. data/test/rails_root/script/process/inspector +3 -0
  65. data/test/rails_root/script/process/reaper +3 -0
  66. data/test/rails_root/script/process/spawner +3 -0
  67. data/test/rails_root/script/runner +3 -0
  68. data/test/rails_root/script/server +3 -0
  69. data/test/rails_root/test/factories.rb +14 -0
  70. data/test/rails_root/test/functional/.keep +0 -0
  71. data/test/rails_root/test/functional/uploads_controller_test.rb +104 -0
  72. data/test/rails_root/test/integration/.keep +0 -0
  73. data/test/rails_root/test/mocks/development/.keep +0 -0
  74. data/test/rails_root/test/mocks/test/.keep +0 -0
  75. data/test/rails_root/test/test_helper.rb +22 -0
  76. data/test/rails_root/test/unit/.keep +0 -0
  77. data/test/{unit → rails_root/test/unit}/upload_test.rb +1 -1
  78. data/uploader.gemspec +104 -6
  79. metadata +111 -6
  80. data/test/test_helper.rb +0 -3
@@ -0,0 +1,58 @@
1
+ // script.aculo.us scriptaculous.js v1.7.1_beta3, Fri May 25 17:19:41 +0200 2007
2
+
3
+ // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
4
+ //
5
+ // Permission is hereby granted, free of charge, to any person obtaining
6
+ // a copy of this software and associated documentation files (the
7
+ // "Software"), to deal in the Software without restriction, including
8
+ // without limitation the rights to use, copy, modify, merge, publish,
9
+ // distribute, sublicense, and/or sell copies of the Software, and to
10
+ // permit persons to whom the Software is furnished to do so, subject to
11
+ // the following conditions:
12
+ //
13
+ // The above copyright notice and this permission notice shall be
14
+ // included in all copies or substantial portions of the Software.
15
+ //
16
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ //
24
+ // For details, see the script.aculo.us web site: http://script.aculo.us/
25
+
26
+ var Scriptaculous = {
27
+ Version: '1.7.1_beta3',
28
+ require: function(libraryName) {
29
+ // inserting via DOM fails in Safari 2.0, so brute force approach
30
+ document.write('<script type="text/javascript" src="'+libraryName+'"></script>');
31
+ },
32
+ REQUIRED_PROTOTYPE: '1.5.1',
33
+ load: function() {
34
+ function convertVersionString(versionString){
35
+ var r = versionString.split('.');
36
+ return parseInt(r[0])*100000 + parseInt(r[1])*1000 + parseInt(r[2]);
37
+ }
38
+
39
+ if((typeof Prototype=='undefined') ||
40
+ (typeof Element == 'undefined') ||
41
+ (typeof Element.Methods=='undefined') ||
42
+ (convertVersionString(Prototype.Version) <
43
+ convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE)))
44
+ throw("script.aculo.us requires the Prototype JavaScript framework >= " +
45
+ Scriptaculous.REQUIRED_PROTOTYPE);
46
+
47
+ $A(document.getElementsByTagName("script")).findAll( function(s) {
48
+ return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
49
+ }).each( function(s) {
50
+ var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,'');
51
+ var includes = s.src.match(/\?.*load=([a-z,]*)/);
52
+ (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each(
53
+ function(include) { Scriptaculous.require(path+include+'.js') });
54
+ });
55
+ }
56
+ }
57
+
58
+ Scriptaculous.load();
@@ -0,0 +1,277 @@
1
+ // script.aculo.us slider.js v1.7.1_beta3, Fri May 25 17:19:41 +0200 2007
2
+
3
+ // Copyright (c) 2005-2007 Marty Haught, Thomas Fuchs
4
+ //
5
+ // script.aculo.us is freely distributable under the terms of an MIT-style license.
6
+ // For details, see the script.aculo.us web site: http://script.aculo.us/
7
+
8
+ if(!Control) var Control = {};
9
+ Control.Slider = Class.create();
10
+
11
+ // options:
12
+ // axis: 'vertical', or 'horizontal' (default)
13
+ //
14
+ // callbacks:
15
+ // onChange(value)
16
+ // onSlide(value)
17
+ Control.Slider.prototype = {
18
+ initialize: function(handle, track, options) {
19
+ var slider = this;
20
+
21
+ if(handle instanceof Array) {
22
+ this.handles = handle.collect( function(e) { return $(e) });
23
+ } else {
24
+ this.handles = [$(handle)];
25
+ }
26
+
27
+ this.track = $(track);
28
+ this.options = options || {};
29
+
30
+ this.axis = this.options.axis || 'horizontal';
31
+ this.increment = this.options.increment || 1;
32
+ this.step = parseInt(this.options.step || '1');
33
+ this.range = this.options.range || $R(0,1);
34
+
35
+ this.value = 0; // assure backwards compat
36
+ this.values = this.handles.map( function() { return 0 });
37
+ this.spans = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false;
38
+ this.options.startSpan = $(this.options.startSpan || null);
39
+ this.options.endSpan = $(this.options.endSpan || null);
40
+
41
+ this.restricted = this.options.restricted || false;
42
+
43
+ this.maximum = this.options.maximum || this.range.end;
44
+ this.minimum = this.options.minimum || this.range.start;
45
+
46
+ // Will be used to align the handle onto the track, if necessary
47
+ this.alignX = parseInt(this.options.alignX || '0');
48
+ this.alignY = parseInt(this.options.alignY || '0');
49
+
50
+ this.trackLength = this.maximumOffset() - this.minimumOffset();
51
+
52
+ this.handleLength = this.isVertical() ?
53
+ (this.handles[0].offsetHeight != 0 ?
54
+ this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) :
55
+ (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth :
56
+ this.handles[0].style.width.replace(/px$/,""));
57
+
58
+ this.active = false;
59
+ this.dragging = false;
60
+ this.disabled = false;
61
+
62
+ if(this.options.disabled) this.setDisabled();
63
+
64
+ // Allowed values array
65
+ this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false;
66
+ if(this.allowedValues) {
67
+ this.minimum = this.allowedValues.min();
68
+ this.maximum = this.allowedValues.max();
69
+ }
70
+
71
+ this.eventMouseDown = this.startDrag.bindAsEventListener(this);
72
+ this.eventMouseUp = this.endDrag.bindAsEventListener(this);
73
+ this.eventMouseMove = this.update.bindAsEventListener(this);
74
+
75
+ // Initialize handles in reverse (make sure first handle is active)
76
+ this.handles.each( function(h,i) {
77
+ i = slider.handles.length-1-i;
78
+ slider.setValue(parseFloat(
79
+ (slider.options.sliderValue instanceof Array ?
80
+ slider.options.sliderValue[i] : slider.options.sliderValue) ||
81
+ slider.range.start), i);
82
+ Element.makePositioned(h); // fix IE
83
+ Event.observe(h, "mousedown", slider.eventMouseDown);
84
+ });
85
+
86
+ Event.observe(this.track, "mousedown", this.eventMouseDown);
87
+ Event.observe(document, "mouseup", this.eventMouseUp);
88
+ Event.observe(document, "mousemove", this.eventMouseMove);
89
+
90
+ this.initialized = true;
91
+ },
92
+ dispose: function() {
93
+ var slider = this;
94
+ Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
95
+ Event.stopObserving(document, "mouseup", this.eventMouseUp);
96
+ Event.stopObserving(document, "mousemove", this.eventMouseMove);
97
+ this.handles.each( function(h) {
98
+ Event.stopObserving(h, "mousedown", slider.eventMouseDown);
99
+ });
100
+ },
101
+ setDisabled: function(){
102
+ this.disabled = true;
103
+ },
104
+ setEnabled: function(){
105
+ this.disabled = false;
106
+ },
107
+ getNearestValue: function(value){
108
+ if(this.allowedValues){
109
+ if(value >= this.allowedValues.max()) return(this.allowedValues.max());
110
+ if(value <= this.allowedValues.min()) return(this.allowedValues.min());
111
+
112
+ var offset = Math.abs(this.allowedValues[0] - value);
113
+ var newValue = this.allowedValues[0];
114
+ this.allowedValues.each( function(v) {
115
+ var currentOffset = Math.abs(v - value);
116
+ if(currentOffset <= offset){
117
+ newValue = v;
118
+ offset = currentOffset;
119
+ }
120
+ });
121
+ return newValue;
122
+ }
123
+ if(value > this.range.end) return this.range.end;
124
+ if(value < this.range.start) return this.range.start;
125
+ return value;
126
+ },
127
+ setValue: function(sliderValue, handleIdx){
128
+ if(!this.active) {
129
+ this.activeHandleIdx = handleIdx || 0;
130
+ this.activeHandle = this.handles[this.activeHandleIdx];
131
+ this.updateStyles();
132
+ }
133
+ handleIdx = handleIdx || this.activeHandleIdx || 0;
134
+ if(this.initialized && this.restricted) {
135
+ if((handleIdx>0) && (sliderValue<this.values[handleIdx-1]))
136
+ sliderValue = this.values[handleIdx-1];
137
+ if((handleIdx < (this.handles.length-1)) && (sliderValue>this.values[handleIdx+1]))
138
+ sliderValue = this.values[handleIdx+1];
139
+ }
140
+ sliderValue = this.getNearestValue(sliderValue);
141
+ this.values[handleIdx] = sliderValue;
142
+ this.value = this.values[0]; // assure backwards compat
143
+
144
+ this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] =
145
+ this.translateToPx(sliderValue);
146
+
147
+ this.drawSpans();
148
+ if(!this.dragging || !this.event) this.updateFinished();
149
+ },
150
+ setValueBy: function(delta, handleIdx) {
151
+ this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta,
152
+ handleIdx || this.activeHandleIdx || 0);
153
+ },
154
+ translateToPx: function(value) {
155
+ return Math.round(
156
+ ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) *
157
+ (value - this.range.start)) + "px";
158
+ },
159
+ translateToValue: function(offset) {
160
+ return ((offset/(this.trackLength-this.handleLength) *
161
+ (this.range.end-this.range.start)) + this.range.start);
162
+ },
163
+ getRange: function(range) {
164
+ var v = this.values.sortBy(Prototype.K);
165
+ range = range || 0;
166
+ return $R(v[range],v[range+1]);
167
+ },
168
+ minimumOffset: function(){
169
+ return(this.isVertical() ? this.alignY : this.alignX);
170
+ },
171
+ maximumOffset: function(){
172
+ return(this.isVertical() ?
173
+ (this.track.offsetHeight != 0 ? this.track.offsetHeight :
174
+ this.track.style.height.replace(/px$/,"")) - this.alignY :
175
+ (this.track.offsetWidth != 0 ? this.track.offsetWidth :
176
+ this.track.style.width.replace(/px$/,"")) - this.alignY);
177
+ },
178
+ isVertical: function(){
179
+ return (this.axis == 'vertical');
180
+ },
181
+ drawSpans: function() {
182
+ var slider = this;
183
+ if(this.spans)
184
+ $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) });
185
+ if(this.options.startSpan)
186
+ this.setSpan(this.options.startSpan,
187
+ $R(0, this.values.length>1 ? this.getRange(0).min() : this.value ));
188
+ if(this.options.endSpan)
189
+ this.setSpan(this.options.endSpan,
190
+ $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum));
191
+ },
192
+ setSpan: function(span, range) {
193
+ if(this.isVertical()) {
194
+ span.style.top = this.translateToPx(range.start);
195
+ span.style.height = this.translateToPx(range.end - range.start + this.range.start);
196
+ } else {
197
+ span.style.left = this.translateToPx(range.start);
198
+ span.style.width = this.translateToPx(range.end - range.start + this.range.start);
199
+ }
200
+ },
201
+ updateStyles: function() {
202
+ this.handles.each( function(h){ Element.removeClassName(h, 'selected') });
203
+ Element.addClassName(this.activeHandle, 'selected');
204
+ },
205
+ startDrag: function(event) {
206
+ if(Event.isLeftClick(event)) {
207
+ if(!this.disabled){
208
+ this.active = true;
209
+
210
+ var handle = Event.element(event);
211
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
212
+ var track = handle;
213
+ if(track==this.track) {
214
+ var offsets = Position.cumulativeOffset(this.track);
215
+ this.event = event;
216
+ this.setValue(this.translateToValue(
217
+ (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2)
218
+ ));
219
+ var offsets = Position.cumulativeOffset(this.activeHandle);
220
+ this.offsetX = (pointer[0] - offsets[0]);
221
+ this.offsetY = (pointer[1] - offsets[1]);
222
+ } else {
223
+ // find the handle (prevents issues with Safari)
224
+ while((this.handles.indexOf(handle) == -1) && handle.parentNode)
225
+ handle = handle.parentNode;
226
+
227
+ if(this.handles.indexOf(handle)!=-1) {
228
+ this.activeHandle = handle;
229
+ this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
230
+ this.updateStyles();
231
+
232
+ var offsets = Position.cumulativeOffset(this.activeHandle);
233
+ this.offsetX = (pointer[0] - offsets[0]);
234
+ this.offsetY = (pointer[1] - offsets[1]);
235
+ }
236
+ }
237
+ }
238
+ Event.stop(event);
239
+ }
240
+ },
241
+ update: function(event) {
242
+ if(this.active) {
243
+ if(!this.dragging) this.dragging = true;
244
+ this.draw(event);
245
+ if(Prototype.Browser.WebKit) window.scrollBy(0,0);
246
+ Event.stop(event);
247
+ }
248
+ },
249
+ draw: function(event) {
250
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
251
+ var offsets = Position.cumulativeOffset(this.track);
252
+ pointer[0] -= this.offsetX + offsets[0];
253
+ pointer[1] -= this.offsetY + offsets[1];
254
+ this.event = event;
255
+ this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] ));
256
+ if(this.initialized && this.options.onSlide)
257
+ this.options.onSlide(this.values.length>1 ? this.values : this.value, this);
258
+ },
259
+ endDrag: function(event) {
260
+ if(this.active && this.dragging) {
261
+ this.finishDrag(event, true);
262
+ Event.stop(event);
263
+ }
264
+ this.active = false;
265
+ this.dragging = false;
266
+ },
267
+ finishDrag: function(event, success) {
268
+ this.active = false;
269
+ this.dragging = false;
270
+ this.updateFinished();
271
+ },
272
+ updateFinished: function() {
273
+ if(this.initialized && this.options.onChange)
274
+ this.options.onChange(this.values.length>1 ? this.values : this.value, this);
275
+ this.event = null;
276
+ }
277
+ }
@@ -0,0 +1,60 @@
1
+ // script.aculo.us sound.js v1.7.1_beta3, Fri May 25 17:19:41 +0200 2007
2
+
3
+ // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
4
+ //
5
+ // Based on code created by Jules Gravinese (http://www.webveteran.com/)
6
+ //
7
+ // script.aculo.us is freely distributable under the terms of an MIT-style license.
8
+ // For details, see the script.aculo.us web site: http://script.aculo.us/
9
+
10
+ Sound = {
11
+ tracks: {},
12
+ _enabled: true,
13
+ template:
14
+ new Template('<embed style="height:0" id="sound_#{track}_#{id}" src="#{url}" loop="false" autostart="true" hidden="true"/>'),
15
+ enable: function(){
16
+ Sound._enabled = true;
17
+ },
18
+ disable: function(){
19
+ Sound._enabled = false;
20
+ },
21
+ play: function(url){
22
+ if(!Sound._enabled) return;
23
+ var options = Object.extend({
24
+ track: 'global', url: url, replace: false
25
+ }, arguments[1] || {});
26
+
27
+ if(options.replace && this.tracks[options.track]) {
28
+ $R(0, this.tracks[options.track].id).each(function(id){
29
+ var sound = $('sound_'+options.track+'_'+id);
30
+ sound.Stop && sound.Stop();
31
+ sound.remove();
32
+ })
33
+ this.tracks[options.track] = null;
34
+ }
35
+
36
+ if(!this.tracks[options.track])
37
+ this.tracks[options.track] = { id: 0 }
38
+ else
39
+ this.tracks[options.track].id++;
40
+
41
+ options.id = this.tracks[options.track].id;
42
+ if (Prototype.Browser.IE) {
43
+ var sound = document.createElement('bgsound');
44
+ sound.setAttribute('id','sound_'+options.track+'_'+options.id);
45
+ sound.setAttribute('src',options.url);
46
+ sound.setAttribute('loop','1');
47
+ sound.setAttribute('autostart','true');
48
+ $$('body')[0].appendChild(sound);
49
+ }
50
+ else
51
+ new Insertion.Bottom($$('body')[0], Sound.template.evaluate(options));
52
+ }
53
+ };
54
+
55
+ if(Prototype.Browser.Gecko && navigator.userAgent.indexOf("Win") > 0){
56
+ if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('QuickTime') != -1 }))
57
+ Sound.template = new Template('<object id="sound_#{track}_#{id}" width="0" height="0" type="audio/mpeg" data="#{url}"/>')
58
+ else
59
+ Sound.play = function(){}
60
+ }
@@ -0,0 +1 @@
1
+ # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
File without changes
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../config/boot'
3
+ require 'commands/about'
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../config/boot'
3
+ require 'commands/breakpointer'
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../config/boot'
3
+ require 'commands/console'
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'activesupport'
4
+ require 'pathname'
5
+
6
+ project_name = ARGV[0]
7
+ fail("Usage: #{File.basename(__FILE__)} new_project_name") unless project_name
8
+ fail("Project name must only contain [a-z0-9_]") unless project_name =~ /^[a-z0-9_]+$/
9
+
10
+ base_directory = Pathname.new(File.join(File.dirname(__FILE__), '..', '..')).realpath
11
+ project_directory = base_directory + project_name
12
+ fail("Project directory (#{project_directory}) already exists") if project_directory.exist?
13
+
14
+ template_url = "git@github.com:thoughtbot/rails-template.git"
15
+ changeme = "CHANGEME"
16
+
17
+ def run(cmd)
18
+ puts "Running '#{cmd}'"
19
+ out = `#{cmd}`
20
+ if $? != 0
21
+ fail "Command #{cmd} failed: #$?\n#{out}"
22
+ end
23
+ out
24
+ end
25
+
26
+ def search_and_replace(file, search, replace)
27
+ if File.file?(file)
28
+ contents = File.read(file)
29
+ if contents[search]
30
+ puts "Replacing #{search} with #{replace} in #{file}"
31
+ contents.gsub!(search, replace)
32
+ File.open(file, "w") { |f| f << contents }
33
+ end
34
+ end
35
+ end
36
+
37
+ run("mkdir #{project_directory}")
38
+ Dir.chdir(project_directory) or fail("Couldn't change to #{project_directory}")
39
+ run("git init")
40
+ run("git remote add template #{template_url}")
41
+ run("git pull template master")
42
+
43
+ Dir.glob("#{project_directory}/**/*").each do |file|
44
+ search_and_replace(file, changeme, project_name)
45
+ end
46
+
47
+ run("git commit -a -m 'Initial commit'")
48
+
49
+ puts
50
+ puts "Now login to github and add a new project named '#{project_name.humanize.titleize}'"
51
+
52
+
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ begin
3
+ load File.expand_path(File.dirname(__FILE__) + "/../vendor/plugins/cucumber/bin/cucumber")
4
+ rescue LoadError
5
+ require "rubygems"
6
+ load File.join(Gem.bindir, "cucumber")
7
+ end
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../config/boot'
3
+ require 'commands/dbconsole'
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../config/boot'
3
+ require 'commands/destroy'
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../config/boot'
3
+ require 'commands/generate'
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../../config/boot'
3
+ require 'commands/performance/benchmarker'
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../../config/boot'
3
+ require 'commands/performance/profiler'
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../../config/boot'
3
+ require 'commands/performance/request'
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../config/boot'
3
+ require 'commands/plugin'
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../../config/boot'
3
+ require 'commands/process/inspector'
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../../config/boot'
3
+ require 'commands/process/reaper'
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../../config/boot'
3
+ require 'commands/process/spawner'
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../config/boot'
3
+ require 'commands/runner'
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../config/boot'
3
+ require 'commands/server'
@@ -0,0 +1,14 @@
1
+ Factory.sequence :name do |n|
2
+ "a_name#{n}"
3
+ end
4
+
5
+ Factory.define :user do |f|
6
+ f.name { Factory.next(:name) }
7
+ end
8
+
9
+ Factory.define :upload do |f|
10
+ f.creator {|a| a.association(:user)}
11
+ f.uploadable {|a| a.association(:user)}
12
+ f.caption { Factory.next(:name) }
13
+ f.local ActionController::TestUploadedFile.new(File.join(RAILS_ROOT, 'public/images/rails.png'), 'image/gif')
14
+ end
File without changes
@@ -0,0 +1,104 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class UploadsControllerTest < ActionController::TestCase
4
+
5
+ def setup
6
+ @controller = UploadsController.new
7
+ @request = ActionController::TestRequest.new
8
+ @response = ActionController::TestResponse.new
9
+ @user = Factory(:user)
10
+ @controller.stubs(:current_user).returns(@user)
11
+ end
12
+
13
+ context 'on POST to :create' do
14
+ context "good file" do
15
+ setup do
16
+ post :create, { :upload => { :local => VALID_FILE }, :parent_type => 'User', :parent_id => @user.to_param }
17
+ end
18
+ should_redirect_to("/create_success") { '/create_success' }
19
+ should_set_the_flash_to(I18n.t('uploader.successful_upload'))
20
+ should "create a valid upload" do
21
+ assert_difference "@user.uploads.count", 1 do
22
+ post :create, { :upload => { :local => VALID_FILE }, :parent_type => 'User', :parent_id => @user.to_param }
23
+ end
24
+ assert assigns(:upload).errors.empty?, assigns(:upload).errors
25
+ end
26
+ end
27
+ context "bad file" do
28
+ setup do
29
+ post :create, { :upload => { :local => nil }, :parent_type => 'User', :parent_id => @user.to_param }
30
+ end
31
+ should_redirect_to("/create_failure") { '/create_failure' }
32
+ should_set_the_flash_to(/An error occured while uploading the file/)
33
+ should "not create file" do
34
+ assert_difference "@user.uploads.count", 1 do
35
+ post :create, { :upload => { :local => VALID_FILE }, :parent_type => 'User', :parent_id => @user.to_param }
36
+ end
37
+ assert assigns(:upload).errors.empty?, assigns(:upload).errors
38
+ end
39
+ end
40
+ end
41
+ context 'on POST to :swfupload' do
42
+ setup do
43
+ post :swfupload, { :Filedata => VALID_FILE, :parent_type => 'User', :parent_id => @user.to_param }
44
+ end
45
+ should_respond_with :success
46
+ should "add an upload" do
47
+ assert_difference "Upload.count", 1 do
48
+ post :swfupload, { :filedata => VALID_FILE, :parent_type => 'User', :parent_id => @user.to_param }
49
+ end
50
+ end
51
+ end
52
+
53
+ context 'permission denied' do
54
+ setup do
55
+ @controller.stubs(:has_permission_to_upload).returns(false)
56
+ post :create, { :upload => { :local => VALID_FILE }, :parent_type => 'User', :parent_id => @user.to_param }
57
+ end
58
+ should_redirect_to("/permission_denied") { '/permission_denied' }
59
+ end
60
+
61
+ context 'on DELETE to :destroy' do
62
+ setup do
63
+ @upload = Factory(:upload)
64
+ end
65
+ context "has permission" do
66
+ context "controller" do
67
+ setup do
68
+ delete :destroy, { :id => @upload.to_param }
69
+ end
70
+ should_redirect_to("/destroy_success") { '/destroy_success' }
71
+ should_set_the_flash_to(I18n.t('uploader.file_deleted'))
72
+ end
73
+ context "data changes" do
74
+ should "delete the upload" do
75
+ assert_difference "Upload.count", -1 do
76
+ delete :destroy, { :id => @upload.to_param }
77
+ end
78
+ end
79
+ end
80
+ end
81
+ context "permission denied" do
82
+ setup do
83
+ @upload.stubs(:can_edit?).returns(false)
84
+ Upload.stubs(:find).returns(@upload) # db version won't have can_edit? stubbed since it is a new object so we have to return @upload instead.
85
+ end
86
+ context "controller" do
87
+ setup do
88
+ delete :destroy, { :id => @upload.to_param }
89
+ end
90
+ should_redirect_to("/destroy_success") { '/destroy_success' }
91
+ should_set_the_flash_to(I18n.t('uploader.file_delete_permission_denied'))
92
+ end
93
+ context "data changes" do
94
+ should "not delete the upload" do
95
+ assert_no_difference "Upload.count" do
96
+ delete :destroy, { :id => @upload.to_param }
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ end
103
+
104
+ end
File without changes
File without changes
File without changes