uploader 0.1.10 → 0.1.12

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.
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