reparcs 0.1.5 → 0.2.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/History.txt +8 -0
- data/README +4 -1
- data/Rakefile +1 -0
- data/javascript/builder.js +136 -0
- data/javascript/controls.js +965 -0
- data/javascript/dragdrop.js +974 -0
- data/javascript/effects.js +1122 -0
- data/javascript/prototype.js +4221 -0
- data/javascript/scriptaculous.js +58 -0
- data/javascript/slider.js +275 -0
- data/javascript/sound.js +55 -0
- data/javascript/unittest.js +568 -0
- data/lib/reparcs/projects.rb +99 -6
- data/lib/reparcs.rb +1 -1
- metadata +10 -1
@@ -0,0 +1,568 @@
|
|
1
|
+
// script.aculo.us unittest.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008
|
2
|
+
|
3
|
+
// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
4
|
+
// (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
|
5
|
+
// (c) 2005-2007 Michael Schuerig (http://www.schuerig.de/michael/)
|
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
|
+
// experimental, Firefox-only
|
11
|
+
Event.simulateMouse = function(element, eventName) {
|
12
|
+
var options = Object.extend({
|
13
|
+
pointerX: 0,
|
14
|
+
pointerY: 0,
|
15
|
+
buttons: 0,
|
16
|
+
ctrlKey: false,
|
17
|
+
altKey: false,
|
18
|
+
shiftKey: false,
|
19
|
+
metaKey: false
|
20
|
+
}, arguments[2] || {});
|
21
|
+
var oEvent = document.createEvent("MouseEvents");
|
22
|
+
oEvent.initMouseEvent(eventName, true, true, document.defaultView,
|
23
|
+
options.buttons, options.pointerX, options.pointerY, options.pointerX, options.pointerY,
|
24
|
+
options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, 0, $(element));
|
25
|
+
|
26
|
+
if(this.mark) Element.remove(this.mark);
|
27
|
+
this.mark = document.createElement('div');
|
28
|
+
this.mark.appendChild(document.createTextNode(" "));
|
29
|
+
document.body.appendChild(this.mark);
|
30
|
+
this.mark.style.position = 'absolute';
|
31
|
+
this.mark.style.top = options.pointerY + "px";
|
32
|
+
this.mark.style.left = options.pointerX + "px";
|
33
|
+
this.mark.style.width = "5px";
|
34
|
+
this.mark.style.height = "5px;";
|
35
|
+
this.mark.style.borderTop = "1px solid red;"
|
36
|
+
this.mark.style.borderLeft = "1px solid red;"
|
37
|
+
|
38
|
+
if(this.step)
|
39
|
+
alert('['+new Date().getTime().toString()+'] '+eventName+'/'+Test.Unit.inspect(options));
|
40
|
+
|
41
|
+
$(element).dispatchEvent(oEvent);
|
42
|
+
};
|
43
|
+
|
44
|
+
// Note: Due to a fix in Firefox 1.0.5/6 that probably fixed "too much", this doesn't work in 1.0.6 or DP2.
|
45
|
+
// You need to downgrade to 1.0.4 for now to get this working
|
46
|
+
// See https://bugzilla.mozilla.org/show_bug.cgi?id=289940 for the fix that fixed too much
|
47
|
+
Event.simulateKey = function(element, eventName) {
|
48
|
+
var options = Object.extend({
|
49
|
+
ctrlKey: false,
|
50
|
+
altKey: false,
|
51
|
+
shiftKey: false,
|
52
|
+
metaKey: false,
|
53
|
+
keyCode: 0,
|
54
|
+
charCode: 0
|
55
|
+
}, arguments[2] || {});
|
56
|
+
|
57
|
+
var oEvent = document.createEvent("KeyEvents");
|
58
|
+
oEvent.initKeyEvent(eventName, true, true, window,
|
59
|
+
options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
|
60
|
+
options.keyCode, options.charCode );
|
61
|
+
$(element).dispatchEvent(oEvent);
|
62
|
+
};
|
63
|
+
|
64
|
+
Event.simulateKeys = function(element, command) {
|
65
|
+
for(var i=0; i<command.length; i++) {
|
66
|
+
Event.simulateKey(element,'keypress',{charCode:command.charCodeAt(i)});
|
67
|
+
}
|
68
|
+
};
|
69
|
+
|
70
|
+
var Test = {}
|
71
|
+
Test.Unit = {};
|
72
|
+
|
73
|
+
// security exception workaround
|
74
|
+
Test.Unit.inspect = Object.inspect;
|
75
|
+
|
76
|
+
Test.Unit.Logger = Class.create();
|
77
|
+
Test.Unit.Logger.prototype = {
|
78
|
+
initialize: function(log) {
|
79
|
+
this.log = $(log);
|
80
|
+
if (this.log) {
|
81
|
+
this._createLogTable();
|
82
|
+
}
|
83
|
+
},
|
84
|
+
start: function(testName) {
|
85
|
+
if (!this.log) return;
|
86
|
+
this.testName = testName;
|
87
|
+
this.lastLogLine = document.createElement('tr');
|
88
|
+
this.statusCell = document.createElement('td');
|
89
|
+
this.nameCell = document.createElement('td');
|
90
|
+
this.nameCell.className = "nameCell";
|
91
|
+
this.nameCell.appendChild(document.createTextNode(testName));
|
92
|
+
this.messageCell = document.createElement('td');
|
93
|
+
this.lastLogLine.appendChild(this.statusCell);
|
94
|
+
this.lastLogLine.appendChild(this.nameCell);
|
95
|
+
this.lastLogLine.appendChild(this.messageCell);
|
96
|
+
this.loglines.appendChild(this.lastLogLine);
|
97
|
+
},
|
98
|
+
finish: function(status, summary) {
|
99
|
+
if (!this.log) return;
|
100
|
+
this.lastLogLine.className = status;
|
101
|
+
this.statusCell.innerHTML = status;
|
102
|
+
this.messageCell.innerHTML = this._toHTML(summary);
|
103
|
+
this.addLinksToResults();
|
104
|
+
},
|
105
|
+
message: function(message) {
|
106
|
+
if (!this.log) return;
|
107
|
+
this.messageCell.innerHTML = this._toHTML(message);
|
108
|
+
},
|
109
|
+
summary: function(summary) {
|
110
|
+
if (!this.log) return;
|
111
|
+
this.logsummary.innerHTML = this._toHTML(summary);
|
112
|
+
},
|
113
|
+
_createLogTable: function() {
|
114
|
+
this.log.innerHTML =
|
115
|
+
'<div id="logsummary"></div>' +
|
116
|
+
'<table id="logtable">' +
|
117
|
+
'<thead><tr><th>Status</th><th>Test</th><th>Message</th></tr></thead>' +
|
118
|
+
'<tbody id="loglines"></tbody>' +
|
119
|
+
'</table>';
|
120
|
+
this.logsummary = $('logsummary')
|
121
|
+
this.loglines = $('loglines');
|
122
|
+
},
|
123
|
+
_toHTML: function(txt) {
|
124
|
+
return txt.escapeHTML().replace(/\n/g,"<br/>");
|
125
|
+
},
|
126
|
+
addLinksToResults: function(){
|
127
|
+
$$("tr.failed .nameCell").each( function(td){ // todo: limit to children of this.log
|
128
|
+
td.title = "Run only this test"
|
129
|
+
Event.observe(td, 'click', function(){ window.location.search = "?tests=" + td.innerHTML;});
|
130
|
+
});
|
131
|
+
$$("tr.passed .nameCell").each( function(td){ // todo: limit to children of this.log
|
132
|
+
td.title = "Run all tests"
|
133
|
+
Event.observe(td, 'click', function(){ window.location.search = "";});
|
134
|
+
});
|
135
|
+
}
|
136
|
+
}
|
137
|
+
|
138
|
+
Test.Unit.Runner = Class.create();
|
139
|
+
Test.Unit.Runner.prototype = {
|
140
|
+
initialize: function(testcases) {
|
141
|
+
this.options = Object.extend({
|
142
|
+
testLog: 'testlog'
|
143
|
+
}, arguments[1] || {});
|
144
|
+
this.options.resultsURL = this.parseResultsURLQueryParameter();
|
145
|
+
this.options.tests = this.parseTestsQueryParameter();
|
146
|
+
if (this.options.testLog) {
|
147
|
+
this.options.testLog = $(this.options.testLog) || null;
|
148
|
+
}
|
149
|
+
if(this.options.tests) {
|
150
|
+
this.tests = [];
|
151
|
+
for(var i = 0; i < this.options.tests.length; i++) {
|
152
|
+
if(/^test/.test(this.options.tests[i])) {
|
153
|
+
this.tests.push(new Test.Unit.Testcase(this.options.tests[i], testcases[this.options.tests[i]], testcases["setup"], testcases["teardown"]));
|
154
|
+
}
|
155
|
+
}
|
156
|
+
} else {
|
157
|
+
if (this.options.test) {
|
158
|
+
this.tests = [new Test.Unit.Testcase(this.options.test, testcases[this.options.test], testcases["setup"], testcases["teardown"])];
|
159
|
+
} else {
|
160
|
+
this.tests = [];
|
161
|
+
for(var testcase in testcases) {
|
162
|
+
if(/^test/.test(testcase)) {
|
163
|
+
this.tests.push(
|
164
|
+
new Test.Unit.Testcase(
|
165
|
+
this.options.context ? ' -> ' + this.options.titles[testcase] : testcase,
|
166
|
+
testcases[testcase], testcases["setup"], testcases["teardown"]
|
167
|
+
));
|
168
|
+
}
|
169
|
+
}
|
170
|
+
}
|
171
|
+
}
|
172
|
+
this.currentTest = 0;
|
173
|
+
this.logger = new Test.Unit.Logger(this.options.testLog);
|
174
|
+
setTimeout(this.runTests.bind(this), 1000);
|
175
|
+
},
|
176
|
+
parseResultsURLQueryParameter: function() {
|
177
|
+
return window.location.search.parseQuery()["resultsURL"];
|
178
|
+
},
|
179
|
+
parseTestsQueryParameter: function(){
|
180
|
+
if (window.location.search.parseQuery()["tests"]){
|
181
|
+
return window.location.search.parseQuery()["tests"].split(',');
|
182
|
+
};
|
183
|
+
},
|
184
|
+
// Returns:
|
185
|
+
// "ERROR" if there was an error,
|
186
|
+
// "FAILURE" if there was a failure, or
|
187
|
+
// "SUCCESS" if there was neither
|
188
|
+
getResult: function() {
|
189
|
+
var hasFailure = false;
|
190
|
+
for(var i=0;i<this.tests.length;i++) {
|
191
|
+
if (this.tests[i].errors > 0) {
|
192
|
+
return "ERROR";
|
193
|
+
}
|
194
|
+
if (this.tests[i].failures > 0) {
|
195
|
+
hasFailure = true;
|
196
|
+
}
|
197
|
+
}
|
198
|
+
if (hasFailure) {
|
199
|
+
return "FAILURE";
|
200
|
+
} else {
|
201
|
+
return "SUCCESS";
|
202
|
+
}
|
203
|
+
},
|
204
|
+
postResults: function() {
|
205
|
+
if (this.options.resultsURL) {
|
206
|
+
new Ajax.Request(this.options.resultsURL,
|
207
|
+
{ method: 'get', parameters: 'result=' + this.getResult(), asynchronous: false });
|
208
|
+
}
|
209
|
+
},
|
210
|
+
runTests: function() {
|
211
|
+
var test = this.tests[this.currentTest];
|
212
|
+
if (!test) {
|
213
|
+
// finished!
|
214
|
+
this.postResults();
|
215
|
+
this.logger.summary(this.summary());
|
216
|
+
return;
|
217
|
+
}
|
218
|
+
if(!test.isWaiting) {
|
219
|
+
this.logger.start(test.name);
|
220
|
+
}
|
221
|
+
test.run();
|
222
|
+
if(test.isWaiting) {
|
223
|
+
this.logger.message("Waiting for " + test.timeToWait + "ms");
|
224
|
+
setTimeout(this.runTests.bind(this), test.timeToWait || 1000);
|
225
|
+
} else {
|
226
|
+
this.logger.finish(test.status(), test.summary());
|
227
|
+
this.currentTest++;
|
228
|
+
// tail recursive, hopefully the browser will skip the stackframe
|
229
|
+
this.runTests();
|
230
|
+
}
|
231
|
+
},
|
232
|
+
summary: function() {
|
233
|
+
var assertions = 0;
|
234
|
+
var failures = 0;
|
235
|
+
var errors = 0;
|
236
|
+
var messages = [];
|
237
|
+
for(var i=0;i<this.tests.length;i++) {
|
238
|
+
assertions += this.tests[i].assertions;
|
239
|
+
failures += this.tests[i].failures;
|
240
|
+
errors += this.tests[i].errors;
|
241
|
+
}
|
242
|
+
return (
|
243
|
+
(this.options.context ? this.options.context + ': ': '') +
|
244
|
+
this.tests.length + " tests, " +
|
245
|
+
assertions + " assertions, " +
|
246
|
+
failures + " failures, " +
|
247
|
+
errors + " errors");
|
248
|
+
}
|
249
|
+
}
|
250
|
+
|
251
|
+
Test.Unit.Assertions = Class.create();
|
252
|
+
Test.Unit.Assertions.prototype = {
|
253
|
+
initialize: function() {
|
254
|
+
this.assertions = 0;
|
255
|
+
this.failures = 0;
|
256
|
+
this.errors = 0;
|
257
|
+
this.messages = [];
|
258
|
+
},
|
259
|
+
summary: function() {
|
260
|
+
return (
|
261
|
+
this.assertions + " assertions, " +
|
262
|
+
this.failures + " failures, " +
|
263
|
+
this.errors + " errors" + "\n" +
|
264
|
+
this.messages.join("\n"));
|
265
|
+
},
|
266
|
+
pass: function() {
|
267
|
+
this.assertions++;
|
268
|
+
},
|
269
|
+
fail: function(message) {
|
270
|
+
this.failures++;
|
271
|
+
this.messages.push("Failure: " + message);
|
272
|
+
},
|
273
|
+
info: function(message) {
|
274
|
+
this.messages.push("Info: " + message);
|
275
|
+
},
|
276
|
+
error: function(error) {
|
277
|
+
this.errors++;
|
278
|
+
this.messages.push(error.name + ": "+ error.message + "(" + Test.Unit.inspect(error) +")");
|
279
|
+
},
|
280
|
+
status: function() {
|
281
|
+
if (this.failures > 0) return 'failed';
|
282
|
+
if (this.errors > 0) return 'error';
|
283
|
+
return 'passed';
|
284
|
+
},
|
285
|
+
assert: function(expression) {
|
286
|
+
var message = arguments[1] || 'assert: got "' + Test.Unit.inspect(expression) + '"';
|
287
|
+
try { expression ? this.pass() :
|
288
|
+
this.fail(message); }
|
289
|
+
catch(e) { this.error(e); }
|
290
|
+
},
|
291
|
+
assertEqual: function(expected, actual) {
|
292
|
+
var message = arguments[2] || "assertEqual";
|
293
|
+
try { (expected == actual) ? this.pass() :
|
294
|
+
this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
|
295
|
+
'", actual "' + Test.Unit.inspect(actual) + '"'); }
|
296
|
+
catch(e) { this.error(e); }
|
297
|
+
},
|
298
|
+
assertInspect: function(expected, actual) {
|
299
|
+
var message = arguments[2] || "assertInspect";
|
300
|
+
try { (expected == actual.inspect()) ? this.pass() :
|
301
|
+
this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
|
302
|
+
'", actual "' + Test.Unit.inspect(actual) + '"'); }
|
303
|
+
catch(e) { this.error(e); }
|
304
|
+
},
|
305
|
+
assertEnumEqual: function(expected, actual) {
|
306
|
+
var message = arguments[2] || "assertEnumEqual";
|
307
|
+
try { $A(expected).length == $A(actual).length &&
|
308
|
+
expected.zip(actual).all(function(pair) { return pair[0] == pair[1] }) ?
|
309
|
+
this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) +
|
310
|
+
', actual ' + Test.Unit.inspect(actual)); }
|
311
|
+
catch(e) { this.error(e); }
|
312
|
+
},
|
313
|
+
assertNotEqual: function(expected, actual) {
|
314
|
+
var message = arguments[2] || "assertNotEqual";
|
315
|
+
try { (expected != actual) ? this.pass() :
|
316
|
+
this.fail(message + ': got "' + Test.Unit.inspect(actual) + '"'); }
|
317
|
+
catch(e) { this.error(e); }
|
318
|
+
},
|
319
|
+
assertIdentical: function(expected, actual) {
|
320
|
+
var message = arguments[2] || "assertIdentical";
|
321
|
+
try { (expected === actual) ? this.pass() :
|
322
|
+
this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
|
323
|
+
'", actual "' + Test.Unit.inspect(actual) + '"'); }
|
324
|
+
catch(e) { this.error(e); }
|
325
|
+
},
|
326
|
+
assertNotIdentical: function(expected, actual) {
|
327
|
+
var message = arguments[2] || "assertNotIdentical";
|
328
|
+
try { !(expected === actual) ? this.pass() :
|
329
|
+
this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
|
330
|
+
'", actual "' + Test.Unit.inspect(actual) + '"'); }
|
331
|
+
catch(e) { this.error(e); }
|
332
|
+
},
|
333
|
+
assertNull: function(obj) {
|
334
|
+
var message = arguments[1] || 'assertNull'
|
335
|
+
try { (obj==null) ? this.pass() :
|
336
|
+
this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); }
|
337
|
+
catch(e) { this.error(e); }
|
338
|
+
},
|
339
|
+
assertMatch: function(expected, actual) {
|
340
|
+
var message = arguments[2] || 'assertMatch';
|
341
|
+
var regex = new RegExp(expected);
|
342
|
+
try { (regex.exec(actual)) ? this.pass() :
|
343
|
+
this.fail(message + ' : regex: "' + Test.Unit.inspect(expected) + ' did not match: ' + Test.Unit.inspect(actual) + '"'); }
|
344
|
+
catch(e) { this.error(e); }
|
345
|
+
},
|
346
|
+
assertHidden: function(element) {
|
347
|
+
var message = arguments[1] || 'assertHidden';
|
348
|
+
this.assertEqual("none", element.style.display, message);
|
349
|
+
},
|
350
|
+
assertNotNull: function(object) {
|
351
|
+
var message = arguments[1] || 'assertNotNull';
|
352
|
+
this.assert(object != null, message);
|
353
|
+
},
|
354
|
+
assertType: function(expected, actual) {
|
355
|
+
var message = arguments[2] || 'assertType';
|
356
|
+
try {
|
357
|
+
(actual.constructor == expected) ? this.pass() :
|
358
|
+
this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
|
359
|
+
'", actual "' + (actual.constructor) + '"'); }
|
360
|
+
catch(e) { this.error(e); }
|
361
|
+
},
|
362
|
+
assertNotOfType: function(expected, actual) {
|
363
|
+
var message = arguments[2] || 'assertNotOfType';
|
364
|
+
try {
|
365
|
+
(actual.constructor != expected) ? this.pass() :
|
366
|
+
this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
|
367
|
+
'", actual "' + (actual.constructor) + '"'); }
|
368
|
+
catch(e) { this.error(e); }
|
369
|
+
},
|
370
|
+
assertInstanceOf: function(expected, actual) {
|
371
|
+
var message = arguments[2] || 'assertInstanceOf';
|
372
|
+
try {
|
373
|
+
(actual instanceof expected) ? this.pass() :
|
374
|
+
this.fail(message + ": object was not an instance of the expected type"); }
|
375
|
+
catch(e) { this.error(e); }
|
376
|
+
},
|
377
|
+
assertNotInstanceOf: function(expected, actual) {
|
378
|
+
var message = arguments[2] || 'assertNotInstanceOf';
|
379
|
+
try {
|
380
|
+
!(actual instanceof expected) ? this.pass() :
|
381
|
+
this.fail(message + ": object was an instance of the not expected type"); }
|
382
|
+
catch(e) { this.error(e); }
|
383
|
+
},
|
384
|
+
assertRespondsTo: function(method, obj) {
|
385
|
+
var message = arguments[2] || 'assertRespondsTo';
|
386
|
+
try {
|
387
|
+
(obj[method] && typeof obj[method] == 'function') ? this.pass() :
|
388
|
+
this.fail(message + ": object doesn't respond to [" + method + "]"); }
|
389
|
+
catch(e) { this.error(e); }
|
390
|
+
},
|
391
|
+
assertReturnsTrue: function(method, obj) {
|
392
|
+
var message = arguments[2] || 'assertReturnsTrue';
|
393
|
+
try {
|
394
|
+
var m = obj[method];
|
395
|
+
if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)];
|
396
|
+
m() ? this.pass() :
|
397
|
+
this.fail(message + ": method returned false"); }
|
398
|
+
catch(e) { this.error(e); }
|
399
|
+
},
|
400
|
+
assertReturnsFalse: function(method, obj) {
|
401
|
+
var message = arguments[2] || 'assertReturnsFalse';
|
402
|
+
try {
|
403
|
+
var m = obj[method];
|
404
|
+
if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)];
|
405
|
+
!m() ? this.pass() :
|
406
|
+
this.fail(message + ": method returned true"); }
|
407
|
+
catch(e) { this.error(e); }
|
408
|
+
},
|
409
|
+
assertRaise: function(exceptionName, method) {
|
410
|
+
var message = arguments[2] || 'assertRaise';
|
411
|
+
try {
|
412
|
+
method();
|
413
|
+
this.fail(message + ": exception expected but none was raised"); }
|
414
|
+
catch(e) {
|
415
|
+
((exceptionName == null) || (e.name==exceptionName)) ? this.pass() : this.error(e);
|
416
|
+
}
|
417
|
+
},
|
418
|
+
assertElementsMatch: function() {
|
419
|
+
var expressions = $A(arguments), elements = $A(expressions.shift());
|
420
|
+
if (elements.length != expressions.length) {
|
421
|
+
this.fail('assertElementsMatch: size mismatch: ' + elements.length + ' elements, ' + expressions.length + ' expressions');
|
422
|
+
return false;
|
423
|
+
}
|
424
|
+
elements.zip(expressions).all(function(pair, index) {
|
425
|
+
var element = $(pair.first()), expression = pair.last();
|
426
|
+
if (element.match(expression)) return true;
|
427
|
+
this.fail('assertElementsMatch: (in index ' + index + ') expected ' + expression.inspect() + ' but got ' + element.inspect());
|
428
|
+
}.bind(this)) && this.pass();
|
429
|
+
},
|
430
|
+
assertElementMatches: function(element, expression) {
|
431
|
+
this.assertElementsMatch([element], expression);
|
432
|
+
},
|
433
|
+
benchmark: function(operation, iterations) {
|
434
|
+
var startAt = new Date();
|
435
|
+
(iterations || 1).times(operation);
|
436
|
+
var timeTaken = ((new Date())-startAt);
|
437
|
+
this.info((arguments[2] || 'Operation') + ' finished ' +
|
438
|
+
iterations + ' iterations in ' + (timeTaken/1000)+'s' );
|
439
|
+
return timeTaken;
|
440
|
+
},
|
441
|
+
_isVisible: function(element) {
|
442
|
+
element = $(element);
|
443
|
+
if(!element.parentNode) return true;
|
444
|
+
this.assertNotNull(element);
|
445
|
+
if(element.style && Element.getStyle(element, 'display') == 'none')
|
446
|
+
return false;
|
447
|
+
|
448
|
+
return this._isVisible(element.parentNode);
|
449
|
+
},
|
450
|
+
assertNotVisible: function(element) {
|
451
|
+
this.assert(!this._isVisible(element), Test.Unit.inspect(element) + " was not hidden and didn't have a hidden parent either. " + ("" || arguments[1]));
|
452
|
+
},
|
453
|
+
assertVisible: function(element) {
|
454
|
+
this.assert(this._isVisible(element), Test.Unit.inspect(element) + " was not visible. " + ("" || arguments[1]));
|
455
|
+
},
|
456
|
+
benchmark: function(operation, iterations) {
|
457
|
+
var startAt = new Date();
|
458
|
+
(iterations || 1).times(operation);
|
459
|
+
var timeTaken = ((new Date())-startAt);
|
460
|
+
this.info((arguments[2] || 'Operation') + ' finished ' +
|
461
|
+
iterations + ' iterations in ' + (timeTaken/1000)+'s' );
|
462
|
+
return timeTaken;
|
463
|
+
}
|
464
|
+
}
|
465
|
+
|
466
|
+
Test.Unit.Testcase = Class.create();
|
467
|
+
Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), {
|
468
|
+
initialize: function(name, test, setup, teardown) {
|
469
|
+
Test.Unit.Assertions.prototype.initialize.bind(this)();
|
470
|
+
this.name = name;
|
471
|
+
|
472
|
+
if(typeof test == 'string') {
|
473
|
+
test = test.gsub(/(\.should[^\(]+\()/,'#{0}this,');
|
474
|
+
test = test.gsub(/(\.should[^\(]+)\(this,\)/,'#{1}(this)');
|
475
|
+
this.test = function() {
|
476
|
+
eval('with(this){'+test+'}');
|
477
|
+
}
|
478
|
+
} else {
|
479
|
+
this.test = test || function() {};
|
480
|
+
}
|
481
|
+
|
482
|
+
this.setup = setup || function() {};
|
483
|
+
this.teardown = teardown || function() {};
|
484
|
+
this.isWaiting = false;
|
485
|
+
this.timeToWait = 1000;
|
486
|
+
},
|
487
|
+
wait: function(time, nextPart) {
|
488
|
+
this.isWaiting = true;
|
489
|
+
this.test = nextPart;
|
490
|
+
this.timeToWait = time;
|
491
|
+
},
|
492
|
+
run: function() {
|
493
|
+
try {
|
494
|
+
try {
|
495
|
+
if (!this.isWaiting) this.setup.bind(this)();
|
496
|
+
this.isWaiting = false;
|
497
|
+
this.test.bind(this)();
|
498
|
+
} finally {
|
499
|
+
if(!this.isWaiting) {
|
500
|
+
this.teardown.bind(this)();
|
501
|
+
}
|
502
|
+
}
|
503
|
+
}
|
504
|
+
catch(e) { this.error(e); }
|
505
|
+
}
|
506
|
+
});
|
507
|
+
|
508
|
+
// *EXPERIMENTAL* BDD-style testing to please non-technical folk
|
509
|
+
// This draws many ideas from RSpec http://rspec.rubyforge.org/
|
510
|
+
|
511
|
+
Test.setupBDDExtensionMethods = function(){
|
512
|
+
var METHODMAP = {
|
513
|
+
shouldEqual: 'assertEqual',
|
514
|
+
shouldNotEqual: 'assertNotEqual',
|
515
|
+
shouldEqualEnum: 'assertEnumEqual',
|
516
|
+
shouldBeA: 'assertType',
|
517
|
+
shouldNotBeA: 'assertNotOfType',
|
518
|
+
shouldBeAn: 'assertType',
|
519
|
+
shouldNotBeAn: 'assertNotOfType',
|
520
|
+
shouldBeNull: 'assertNull',
|
521
|
+
shouldNotBeNull: 'assertNotNull',
|
522
|
+
|
523
|
+
shouldBe: 'assertReturnsTrue',
|
524
|
+
shouldNotBe: 'assertReturnsFalse',
|
525
|
+
shouldRespondTo: 'assertRespondsTo'
|
526
|
+
};
|
527
|
+
var makeAssertion = function(assertion, args, object) {
|
528
|
+
this[assertion].apply(this,(args || []).concat([object]));
|
529
|
+
}
|
530
|
+
|
531
|
+
Test.BDDMethods = {};
|
532
|
+
$H(METHODMAP).each(function(pair) {
|
533
|
+
Test.BDDMethods[pair.key] = function() {
|
534
|
+
var args = $A(arguments);
|
535
|
+
var scope = args.shift();
|
536
|
+
makeAssertion.apply(scope, [pair.value, args, this]); };
|
537
|
+
});
|
538
|
+
|
539
|
+
[Array.prototype, String.prototype, Number.prototype, Boolean.prototype].each(
|
540
|
+
function(p){ Object.extend(p, Test.BDDMethods) }
|
541
|
+
);
|
542
|
+
}
|
543
|
+
|
544
|
+
Test.context = function(name, spec, log){
|
545
|
+
Test.setupBDDExtensionMethods();
|
546
|
+
|
547
|
+
var compiledSpec = {};
|
548
|
+
var titles = {};
|
549
|
+
for(specName in spec) {
|
550
|
+
switch(specName){
|
551
|
+
case "setup":
|
552
|
+
case "teardown":
|
553
|
+
compiledSpec[specName] = spec[specName];
|
554
|
+
break;
|
555
|
+
default:
|
556
|
+
var testName = 'test'+specName.gsub(/\s+/,'-').camelize();
|
557
|
+
var body = spec[specName].toString().split('\n').slice(1);
|
558
|
+
if(/^\{/.test(body[0])) body = body.slice(1);
|
559
|
+
body.pop();
|
560
|
+
body = body.map(function(statement){
|
561
|
+
return statement.strip()
|
562
|
+
});
|
563
|
+
compiledSpec[testName] = body.join('\n');
|
564
|
+
titles[testName] = specName;
|
565
|
+
}
|
566
|
+
}
|
567
|
+
new Test.Unit.Runner(compiledSpec, { titles: titles, testLog: log || 'testlog', context: name });
|
568
|
+
};
|
data/lib/reparcs/projects.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'fileutils'
|
1
2
|
include Base
|
2
3
|
|
3
4
|
#The Projects module contains the classes that act as good starting points for
|
@@ -34,20 +35,112 @@ module Projects
|
|
34
35
|
c_type.set_attribute("content", "text/html;charset=#{@charset}")
|
35
36
|
@head.append(c_type)
|
36
37
|
end
|
37
|
-
#
|
38
|
-
|
39
|
-
|
38
|
+
#Includes the scriptaculous scripts in you page
|
39
|
+
#Note* it simply includes several script elements with
|
40
|
+
#relative paths to the scriptaculous script files, this method
|
41
|
+
#is really only useful if you have added this page to a Website object
|
42
|
+
#and have invoked the Website.include_scriptaculous_files method which will include
|
43
|
+
#the files when published.
|
44
|
+
#Unless you intend to create a javascript directory and include them yourself!
|
45
|
+
def include_scriptaculous
|
46
|
+
Dir.foreach("#{__FILE__}../../../javascript") { |f|
|
47
|
+
unless f[0,1] == "."
|
48
|
+
s = Script.new({:src => "javascript/#{f}"})
|
49
|
+
@head.append(s)
|
50
|
+
end
|
51
|
+
}
|
52
|
+
end
|
53
|
+
#Adds a visual effect to a element
|
54
|
+
#Note* you must have included the scriptalicous library in your
|
55
|
+
#page beforehand and the element must have its id attribute set!
|
56
|
+
#Takes the element object, the event type, and the effect type as parameters.
|
57
|
+
def add_effect(element, event_type, effect_type)
|
58
|
+
script = shortcut_script(%{
|
59
|
+
window.addEventListener("load", function(event) {
|
60
|
+
$('#{element.get_attribute('id')}').#{event_type} = function(event) {
|
61
|
+
Effect.#{effect_type}($(#{element.get_attribute('id')}));
|
62
|
+
return false;
|
63
|
+
};
|
64
|
+
}
|
65
|
+
);
|
66
|
+
})
|
67
|
+
@head.append(script)
|
40
68
|
end
|
41
69
|
#----->
|
42
70
|
attr_accessor :head, :body, :xml_lang, :lang, :xmlns, :charset
|
43
71
|
end
|
44
72
|
|
45
|
-
#A
|
73
|
+
#A Website, a good starting point for larger projects, that require
|
46
74
|
#other files, etc.
|
47
|
-
class
|
75
|
+
class Website
|
48
76
|
#Create a new Project.
|
49
77
|
def initialize
|
50
|
-
|
78
|
+
@javascript_files = []
|
79
|
+
@image_files = []
|
80
|
+
@css_files = []
|
81
|
+
@pages = []
|
82
|
+
end
|
83
|
+
#Automatically includes the required javascript files, for the effects.
|
84
|
+
def include_scriptaculous_files
|
85
|
+
Dir.foreach("#{__FILE__}../../../javascript") { |f|
|
86
|
+
unless f[0,1] == "."
|
87
|
+
@javascript_files << "../javascript/#{f}"
|
88
|
+
end
|
89
|
+
}
|
90
|
+
end
|
91
|
+
#Adds a javascript file to the project
|
92
|
+
#Once the website has been published the file will
|
93
|
+
#be accesible via the relative path of javascript/[script_file]
|
94
|
+
def add_javascript_file(file)
|
95
|
+
@javascript_files << file
|
96
|
+
end
|
97
|
+
#Adds a css stylsheet file to the project
|
98
|
+
#Once the website has been published the file will
|
99
|
+
#be accesible via the relative path of css/[css_file]
|
100
|
+
def add_css_file(file)
|
101
|
+
@css_files << file
|
102
|
+
end
|
103
|
+
#Adds a image file to the project
|
104
|
+
#Once the website has been published the file will
|
105
|
+
#be accesible via the relative path of image/[image_file]
|
106
|
+
def add_image_file(file)
|
107
|
+
@image_files << file
|
108
|
+
end
|
109
|
+
#Adds a page to the website, takes thre page object, and a name for
|
110
|
+
#the page as parameters. If you specify 'index' for the name, the file
|
111
|
+
#produced by the publish method will be index.html.
|
112
|
+
def append(name, page)
|
113
|
+
@pages << [name, page]
|
114
|
+
end
|
115
|
+
#Publishes the entire website to the given directory, Note* if you
|
116
|
+
#have any files in the given directory, they may be replaced!
|
117
|
+
def publish(directory)
|
118
|
+
root = directory
|
119
|
+
unless @javascript_files.length == 0
|
120
|
+
FileUtils.mkdir "#{root}/javascript"
|
121
|
+
@javascript_files.each do |f|
|
122
|
+
FileUtils.cp(f, "#{root}/javascript")
|
123
|
+
end
|
124
|
+
end
|
125
|
+
unless @image_files.length == 0
|
126
|
+
FileUtils.mkdir "#{root}/image"
|
127
|
+
@image_files.each do |f|
|
128
|
+
FileUtils.cp(f, "#{root}/image")
|
129
|
+
end
|
130
|
+
end
|
131
|
+
unless @css_files.length == 0
|
132
|
+
FileUtils.mkdir "#{root}/css"
|
133
|
+
@css_files.each do |f|
|
134
|
+
FileUtils.cp(f, "#{root}/css")
|
135
|
+
end
|
136
|
+
end
|
137
|
+
unless @pages.length == 0
|
138
|
+
@pages.each do |p|
|
139
|
+
f = File.new("#{root}/#{p[0]}.html", "w")
|
140
|
+
f.write(p[1].to_html)
|
141
|
+
f.close
|
142
|
+
end
|
143
|
+
end
|
51
144
|
end
|
52
145
|
end
|
53
146
|
|
data/lib/reparcs.rb
CHANGED