jim 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/HISTORY +28 -0
  2. data/README.rdoc +1 -1
  3. data/Rakefile +2 -1
  4. data/jim.gemspec +67 -9
  5. data/lib/jim/bundler.rb +14 -11
  6. data/lib/jim/cli.rb +51 -9
  7. data/lib/jim/index.rb +3 -7
  8. data/lib/jim/installer.rb +140 -22
  9. data/lib/jim/templates/commands +21 -6
  10. data/lib/jim/version_parser.rb +2 -3
  11. data/lib/jim.rb +19 -2
  12. data/test/fixtures/jimfile +3 -3
  13. data/test/fixtures/sammy-0.5.0/HISTORY.md +135 -0
  14. data/test/fixtures/sammy-0.5.0/LICENSE +22 -0
  15. data/test/fixtures/sammy-0.5.0/README.md +81 -0
  16. data/test/fixtures/sammy-0.5.0/Rakefile +174 -0
  17. data/test/fixtures/sammy-0.5.0/examples/backend/README.md +23 -0
  18. data/test/fixtures/sammy-0.5.0/examples/backend/Rakefile +15 -0
  19. data/test/fixtures/sammy-0.5.0/examples/backend/app.rb +17 -0
  20. data/test/fixtures/sammy-0.5.0/examples/backend/app.ru +3 -0
  21. data/test/fixtures/sammy-0.5.0/examples/backend/public/javascripts/app.js +106 -0
  22. data/test/fixtures/sammy-0.5.0/examples/backend/public/javascripts/jquery.cloudkit.js +840 -0
  23. data/test/fixtures/sammy-0.5.0/examples/backend/public/javascripts/jquery.js +19 -0
  24. data/test/fixtures/sammy-0.5.0/examples/backend/public/javascripts/sammy.js +1013 -0
  25. data/test/fixtures/sammy-0.5.0/examples/backend/public/templates/index.html.erb +11 -0
  26. data/test/fixtures/sammy-0.5.0/examples/backend/public/templates/task.html.erb +4 -0
  27. data/test/fixtures/sammy-0.5.0/examples/backend/public/templates/task_details.html.erb +4 -0
  28. data/test/fixtures/sammy-0.5.0/examples/backend/views/app.sass +63 -0
  29. data/test/fixtures/sammy-0.5.0/examples/backend/views/index.haml +18 -0
  30. data/test/fixtures/sammy-0.5.0/examples/form_handling/files/form.html +12 -0
  31. data/test/fixtures/sammy-0.5.0/examples/form_handling/index.html +65 -0
  32. data/test/fixtures/sammy-0.5.0/examples/hello_world/index.html +50 -0
  33. data/test/fixtures/sammy-0.5.0/examples/location_override/README.md +15 -0
  34. data/test/fixtures/sammy-0.5.0/examples/location_override/data.html +110 -0
  35. data/test/fixtures/sammy-0.5.0/examples/location_override/index.html +79 -0
  36. data/test/fixtures/sammy-0.5.0/examples/location_override/test.html +121 -0
  37. data/test/fixtures/sammy-0.5.0/lib/min/sammy-0.5.0.min.js +5 -0
  38. data/test/fixtures/sammy-0.5.0/lib/min/sammy-lastest.min.js +5 -0
  39. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.cache.js +117 -0
  40. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.haml.js +539 -0
  41. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.json.js +362 -0
  42. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.mustache.js +415 -0
  43. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.nested_params.js +118 -0
  44. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.storage.js +515 -0
  45. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.template.js +117 -0
  46. data/test/fixtures/sammy-0.5.0/lib/sammy.js +1367 -0
  47. data/test/fixtures/sammy-0.5.0/test/fixtures/partial +1 -0
  48. data/test/fixtures/sammy-0.5.0/test/fixtures/partial.html +1 -0
  49. data/test/fixtures/sammy-0.5.0/test/fixtures/partial.noengine +1 -0
  50. data/test/fixtures/sammy-0.5.0/test/fixtures/partial.template +1 -0
  51. data/test/fixtures/sammy-0.5.0/test/index.html +84 -0
  52. data/test/fixtures/sammy-0.5.0/test/test_sammy_application.js +953 -0
  53. data/test/fixtures/sammy-0.5.0/test/test_sammy_event_context.js +252 -0
  54. data/test/fixtures/sammy-0.5.0/test/test_sammy_location_proxy.js +91 -0
  55. data/test/fixtures/sammy-0.5.0/test/test_sammy_plugins.js +296 -0
  56. data/test/fixtures/sammy-0.5.0/test/test_sammy_storage.js +175 -0
  57. data/test/fixtures/sammy-0.5.0/test/test_server +27 -0
  58. data/test/fixtures/sammy-0.5.0/vendor/jquery-1.4.1.js +6078 -0
  59. data/test/fixtures/sammy-0.5.0/vendor/jquery-1.4.1.min.js +152 -0
  60. data/test/fixtures/sammy-0.5.0/vendor/jsdoc/doc.haml +58 -0
  61. data/test/fixtures/sammy-0.5.0/vendor/jsdoc/jsdoc.rb +143 -0
  62. data/test/fixtures/sammy-0.5.0/vendor/jslitmus.js +670 -0
  63. data/test/fixtures/sammy-0.5.0/vendor/qunit/qunit.css +119 -0
  64. data/test/fixtures/sammy-0.5.0/vendor/qunit/qunit.js +1043 -0
  65. data/test/fixtures/sammy-0.5.0/vendor/qunit-spec.js +127 -0
  66. data/test/helper.rb +23 -3
  67. data/test/test_jim_bundler.rb +9 -8
  68. data/test/test_jim_cli.rb +21 -12
  69. data/test/test_jim_installer.rb +152 -35
  70. data/test/test_jim_version_parser.rb +4 -0
  71. metadata +117 -27
  72. data/.document +0 -5
@@ -0,0 +1,953 @@
1
+ (function($) {
2
+ // $(function() {
3
+ with(QUnit) {
4
+ context('Sammy','apps')
5
+ .should('return a new application if no arguments passed', function() {
6
+ var app = Sammy();
7
+ defined(app, 'route');
8
+ })
9
+ .should('save the application to Sammy.apps', function() {
10
+ var app = Sammy();
11
+ ok(Sammy.apps['body']);
12
+ equal(Sammy.apps['body'], app);
13
+ })
14
+ .should('create a new app and set the element selector', function() {
15
+ var app = Sammy('#main');
16
+ equal(app.element_selector, '#main');
17
+ ok(Sammy.apps['#main']);
18
+ equal(Sammy.apps['#main'], app);
19
+ })
20
+ .should('return the app at selector', function() {
21
+ Sammy('#main');
22
+ var app = Sammy('#main')
23
+ equal(app.element_selector, '#main');
24
+ ok(Sammy.apps['#main']);
25
+ equal(Sammy.apps['#main'], app);
26
+ })
27
+ .should('extend the app at selector', function() {
28
+ var app = Sammy('#main', function() {
29
+ this.extended = true;
30
+ });
31
+ equal(app.element_selector, '#main');
32
+ ok(Sammy.apps['#main']);
33
+ equal(Sammy.apps['#main'], app);
34
+ ok(app.extended);
35
+ });
36
+
37
+ context('Sammy.Application', 'init', {
38
+ before: function() {
39
+ var context = this;
40
+ this.app = new Sammy.Application(function(app) {
41
+ this.random_setting = 1;
42
+ context.yielded_app = app;
43
+ });
44
+ }
45
+ })
46
+ .should('create a sammy object', function() {
47
+ defined(this.app, 'route');
48
+ })
49
+ .should('set arbitrary settings in the app', function() {
50
+ equal(this.app.random_setting, 1);
51
+ })
52
+ .should('set namespace as random UUID', function() {
53
+ matches(/^(\d+)-(\d{1,3})$/, this.app.namespace);
54
+ })
55
+ .should('initialize empty routes object', function() {
56
+ isType(this.app.routes, 'Object');
57
+ })
58
+ .should('yield the app as a argument', function() {
59
+ equal(this.yielded_app, this.app)
60
+ })
61
+ .should('set the location proxy to the default hash location proxy', function() {
62
+ ok(this.app.location_proxy);
63
+ defined(this.app.location_proxy, 'getLocation');
64
+ });
65
+
66
+ context('Sammy.Application', 'route', {
67
+ before: function() {
68
+ var context = this;
69
+ this.app = new Sammy.Application(function() {
70
+ context.returned = this.route('get', /testing/, function() {
71
+ $('#main').trigger('click');
72
+ });
73
+
74
+ this.mycallback = function() { this.redirect('#/'); };
75
+
76
+ this.route('get', '/blah', function() {
77
+ $('#testarea').show();
78
+ });
79
+
80
+ this.route('get', '/boosh/:boosh1/:boosh2', function() {
81
+ $('#testarea').show();
82
+ });
83
+
84
+ this.get(/blurgh/, function() {
85
+ alert('blurgh');
86
+ });
87
+
88
+ this.get('#/', function() {
89
+ alert('home');
90
+ });
91
+
92
+ this.post('#/post', 'mycallback');
93
+
94
+ this.route('#/verbless', function() {});
95
+
96
+ this.route('any', '/any', function() {});
97
+
98
+ });
99
+ }
100
+ })
101
+ .should('return the sammy application instance', function() {
102
+ equal(this.returned, this.app);
103
+ })
104
+ .should('turn a string path into a regular expression', function() {
105
+ var app = this.app;
106
+ ok(app.routes['get']);
107
+ var route = app.routes['get'][1];
108
+ isType(route.path, 'RegExp');
109
+ })
110
+ .should('turn a string path with a named param into a regex and save to param_names', function() {
111
+ var app = this.app;
112
+ ok(app.routes['get']);
113
+ var route = app.routes['get'][2];
114
+ isType(route.path, 'RegExp');
115
+ // deepEqual(route.path.toString(), /^\/boosh\/([^\/]+)\/([^\/]+)$/.toString());
116
+ deepEqual(route.param_names, ['boosh1', 'boosh2']);
117
+ })
118
+ .should('append route to application.routes object', function() {
119
+ var app = this.app;
120
+ ok(app.routes['get']);
121
+ var route = app.routes['get'][1]
122
+ isType(route.path, 'RegExp');
123
+ equal(route.verb, 'get');
124
+ defined(route, 'callback');
125
+ })
126
+ .should('allow shortcuts for defining routes', function() {
127
+ var app = this.app;
128
+ ok(app.routes['get']);
129
+ var route = app.routes['get'][3];
130
+ isType(route.path, 'RegExp');
131
+ equal(route.verb, 'get');
132
+ defined(route, 'callback');
133
+ })
134
+ .should('append late and short route to application.routes object', function() {
135
+ var app = this.app;
136
+ ok(app.routes['get']);
137
+ equal(app.routes['get'].length, 7)
138
+ var route = app.routes['get'][4];
139
+ isType(route.path, 'RegExp');
140
+ equal(route.verb, 'get');
141
+ defined(route, 'callback');
142
+ equal(route.path.toString(), new RegExp("^#/$").toString());
143
+ })
144
+ .should('lookup callback as a string', function() {
145
+ var app = this.app;
146
+ ok(app.routes['post'], "post routes defined");
147
+ var route = app.routes['post'][0];
148
+ ok(route, "route exists");
149
+ equal(route.callback, app.mycallback);
150
+ })
151
+ .should('add an "any" route to every route verb', function() {
152
+ var app = this.app;
153
+ $.each(app.ROUTE_VERBS, function(i, verb) {
154
+ ok(app.routes[verb], verb + "is set on routes");
155
+ var route = app.routes[verb].pop();
156
+ ok(route, "route exists on " + verb);
157
+ equal(route.path.toString(), new RegExp("^/any$").toString());
158
+ });
159
+ });
160
+
161
+ context('Sammy.Application', 'mapRoutes', {
162
+ before: function() {
163
+ var context = this;
164
+ context.empty_callback = function() {};
165
+ context.routes = [
166
+ ['get', '#/get', context.empty_callback],
167
+ ['post', '#/post', context.empty_callback],
168
+ ['any', '#/any', context.empty_callback],
169
+ ['get', '#/string', 'empty']
170
+ ]
171
+ context.app = new Sammy.Application(function() {
172
+ this.empty = context.empty_callback;
173
+
174
+ context.returned = this.mapRoutes(context.routes);
175
+ });
176
+ }
177
+ })
178
+ .should('return the app', function() {
179
+ equal(this.returned, this.app);
180
+ })
181
+ .should('add routes to the app', function() {
182
+ var app = this.app;
183
+ ok(app.routes, "should have routes");
184
+ ok(app.routes['get'], "should have get routes");
185
+ equal(app.routes['get'][0].path.toString(), new RegExp("^#/get$").toString());
186
+ })
187
+ .should('lookup callbacks as strings', function() {
188
+ var app = this.app, route = app.routes['get'].pop();
189
+ ok(route);
190
+ equal(route.path, new RegExp("^#/string$").toString());
191
+ equal(route.callback, this.empty_callback);
192
+ });
193
+
194
+ context('Sammy.Application', 'bind', {
195
+ before: function() {
196
+ var context = this;
197
+ context.triggered = false;
198
+ this.app = new Sammy.Application(function() {
199
+
200
+ context.returned = this.bind('boosh', function() {
201
+ context.triggered = 'boosh';
202
+ context.inner_context = this;
203
+ });
204
+
205
+ this.bind('blurgh', function() {
206
+ context.triggered = 'blurgh';
207
+ context.inner_context = this;
208
+ });
209
+
210
+ });
211
+ }
212
+ })
213
+ .should('return the sammy application instance', function() {
214
+ equal(this.returned, this.app);
215
+ })
216
+ .should('add callback to the listeners collection', function() {
217
+ equal(this.app.listeners['boosh'].length, 1);
218
+ })
219
+ .should('not be able to trigger before run', function() {
220
+ var app = this.app;
221
+ var context = this;
222
+ app.trigger('boosh');
223
+ soon(function() {
224
+ equal(context.triggered, false);
225
+ });
226
+ })
227
+ .should('actually bind/be able to trigger to element after run', function() {
228
+ var app = this.app;
229
+ var context = this;
230
+ app.run();
231
+ app.trigger('blurgh');
232
+ soon(function() {
233
+ equal(context.triggered, 'blurgh');
234
+ app.unload();
235
+ });
236
+ })
237
+ .should('catch events on the bound element', function() {
238
+ var app = this.app;
239
+ var context = this;
240
+ app.run();
241
+ app.$element().trigger('boosh');
242
+ soon(function() {
243
+ equal(context.triggered, 'boosh');
244
+ equal(context.inner_context.verb, 'bind');
245
+ app.unload();
246
+ }, this, 2, 2);
247
+ })
248
+ .should('set the context of the bound events to an EventContext', function() {
249
+ var app = this.app;
250
+ var event_context = null;
251
+ var yielded_context = null;
252
+ this.app.bind('serious-boosh', function() {
253
+ event_context = this;
254
+ });
255
+ app.run();
256
+ app.trigger('serious-boosh');
257
+ soon(function() {
258
+ deepEqual(event_context.app, app);
259
+ equal(event_context.verb, 'bind');
260
+ equal(event_context.path, 'serious-boosh');
261
+ app.unload();
262
+ }, this, 1, 3);
263
+ });
264
+
265
+ context('Sammy.Application','run', {
266
+ before: function () {
267
+ window.location.hash = ''
268
+ var context = this;
269
+ context.yielded_context = "";
270
+ $('.get_area').text('');
271
+ this.app = new Sammy.Application(function() {
272
+ this.element_selector = '#main';
273
+ this.form_params = {};
274
+
275
+ this.route('get', '#/', function() {
276
+ $('.get_area').text('');
277
+ });
278
+
279
+ this.route('get', '#/test', function() {
280
+ $('.get_area').text('test success');
281
+ });
282
+
283
+ this.route('post', '#/test', function() {
284
+ this.app.form_was_run = 'YES';
285
+ this.app.form_params = this.params;
286
+ return false;
287
+ });
288
+
289
+ this.route('post', '#/live', function() {
290
+ this.app.form_was_run = 'LIVE';
291
+ this.app.form_params = this.params;
292
+ return false;
293
+ });
294
+
295
+ this.route('get', '#/yield', function(c) {
296
+ context.yielded_context = c;
297
+ });
298
+
299
+ this.bind('blurgh', function () {
300
+ $('.get_area').text('event fired');
301
+ });
302
+ });
303
+ }
304
+ })
305
+ .should('attach application instance to element', function() {
306
+ this.app.run();
307
+ deepEqual($('#main').data('sammy-app'), this.app);
308
+ this.app.unload();
309
+ })
310
+ .should('set the location to the start url', function() {
311
+ var app = this.app;
312
+ app.run('#/');
313
+ soon(function() {
314
+ equal(window.location.hash, '#/');
315
+ app.unload();
316
+ });
317
+ })
318
+ .should('bind events to all forms', function() {
319
+ var app = this.app;
320
+ app.run('#/');
321
+ $('#main form').submit();
322
+ soon(function() {
323
+ equal(app.form_was_run, 'YES');
324
+ ok(app.form_params);
325
+ // equal(app.form_params['$form'][0], $('#main form')[0]);
326
+ app.unload();
327
+ }, this, 1, 2);
328
+ })
329
+ .should('bind events to all future forms', function () {
330
+ var app = this.app;
331
+ app.run('#/');
332
+ // add a new form to the page
333
+ $('#main').append('<form id="live_form" action="#/live" method="post">' +
334
+ '<input name="live_test" type="text" />' +
335
+ '<input type="submit" class="submit" />' +
336
+ '</form>'
337
+ );
338
+ $('#live_form .submit').submit();
339
+ soon(function() {
340
+ equal(app.form_was_run, 'LIVE');
341
+ equal(app.form_params['$form'][0], $('#live_form')[0]);
342
+ app.unload();
343
+ }, this, 1, 2);
344
+ })
345
+ .should('trigger routes on URL change', function() {
346
+ var app = this.app;
347
+ app.run();
348
+ window.location.hash = '#/test';
349
+ soon(function() {
350
+ equal($('.get_area').text(), 'test success');
351
+ app.unload();
352
+ });
353
+ })
354
+ .should('yield the event context to the route', function() {
355
+ var app = this.app;
356
+ window.location.hash = '#';
357
+ app.run('#/yield');
358
+ soon(function() {
359
+ equal(this.yielded_context.path, '#/yield');
360
+ app.unload();
361
+ }, this);
362
+ })
363
+ .should('trigger events using the apps trigger method', function() {
364
+ var app = this.app;
365
+ app.run();
366
+ app.trigger('blurgh');
367
+ soon(function() {
368
+ equal($('.get_area').text(), 'event fired');
369
+ app.unload();
370
+ });
371
+ })
372
+ .should('die silently if route is not found and 404s are off', function() {
373
+ var app = this.app;
374
+ app.silence_404 = true;
375
+ app.run();
376
+ notRaised(function() {
377
+ window.location.hash = '#/no-route-for-me'
378
+ soon(function() { app.unload(); });
379
+ });
380
+ });
381
+
382
+ context('Sammy.Application','lookupRoute', {
383
+ before: function() {
384
+ this.app = new Sammy.Application(function() {
385
+ this.route('get', /\/blah\/(.+)/, function() {
386
+ $('#main').trigger('click');
387
+ });
388
+
389
+ this.route('get', '#/boo', function() {
390
+ $('#main').trigger('click');
391
+ });
392
+
393
+ this.route('post', '/blah', function() {
394
+ $('#testarea').show();
395
+ });
396
+ });
397
+ }
398
+ })
399
+ .should('find a route by verb and route', function() {
400
+ var app = this.app;
401
+ var route = app.lookupRoute('post','/blah');
402
+ isType(route, 'Object')
403
+ equal(route.verb, 'post');
404
+ defined(route, 'callback');
405
+ })
406
+ .should('find a route by verb and partial route', function() {
407
+ var app = this.app;
408
+ var route = app.lookupRoute('get','/blah/mess');
409
+ isType(route, 'Object')
410
+ equal(route.verb, 'get');
411
+ defined(route, 'callback');
412
+ })
413
+ .should('ignore any hash query string when looking up a route', function() {
414
+ var app = this.app;
415
+ var route = app.lookupRoute('get', '#/boo?ohdontmindeme');
416
+ isType(route, 'Object');
417
+ equal(route.verb, 'get');
418
+ defined(route, 'callback');
419
+ });
420
+
421
+ context('Sammy.Application','runRoute', {
422
+ before: function() {
423
+ var context = this;
424
+ this.app = new Sammy.Application(function() {
425
+ this.route('get', /\/blah\/(.+)/, function() {
426
+ context.params = this.params;
427
+ });
428
+
429
+ this.route('get', '#/boosh/:test/:test2', function() {
430
+ context.params = this.params;
431
+ });
432
+
433
+ this.route('get', '#/message/:message', function() {
434
+ context.params = this.params;
435
+ });
436
+ });
437
+ }
438
+ })
439
+ .should('set named params from a string route', function() {
440
+ this.app.runRoute('get', '#/boosh/blurgh/kapow');
441
+ equal(this.params['test'], 'blurgh');
442
+ equal(this.params['test2'], 'kapow');
443
+ })
444
+ .should('set unnamed params from a regex route in "splat"', function() {
445
+ this.app.runRoute('get', '#/blah/could/be/anything');
446
+ equal(this.params['splat'], 'could/be/anything');
447
+ })
448
+ .should('set additional params from a query string after the hash', function() {
449
+ this.app.runRoute('get', '#/boosh/farg/wow?with=some&nifty=params');
450
+ equal(this.params['with'], 'some');
451
+ equal(this.params['nifty'], 'params');
452
+ })
453
+ .should('exclude the query string from named param values', function() {
454
+ this.app.runRoute('get', '#/boosh/farg/wow?with=some&nifty=params');
455
+ equal(this.params['test'], 'farg');
456
+ equal(this.params['test2'], 'wow');
457
+ })
458
+ .should('exclude the query string from unnamed param values', function() {
459
+ this.app.runRoute('get', '#/blah/could/be/anything?except=aquerystring');
460
+ equal(this.params['splat'], 'could/be/anything');
461
+ })
462
+ .should('decode the query string values', function() {
463
+ this.app.runRoute('get', '#/boosh/farg/wow?encoded=this%20should%20be%20decoded%24%25%5E');
464
+ equal(this.params['encoded'], "this should be decoded$%^")
465
+ })
466
+ .should('decode param values', function() {
467
+ this.app.runRoute('get', '#/message/hello%20there');
468
+ equal(this.params['message'], 'hello there');
469
+ this.app.runRoute('get', '#/message/hello there');
470
+ equal(this.params['message'], 'hello there');
471
+ })
472
+ .should('raise error when route can not be found', function() {
473
+ var app = this.app;
474
+ app.silence_404 = false;
475
+ raised(/404/, function() {
476
+ app.runRoute('get','/blurgh');
477
+ });
478
+ });
479
+
480
+ context('Sammy.Application','before', {
481
+ before: function() {
482
+ window.location.hash = '';
483
+ var context = this;
484
+ context.before = {};
485
+ context.route = {};
486
+ this.app = new Sammy.Application(function() {
487
+ this.before(function() {
488
+ this.params['belch'] = 'burp';
489
+ context.before = this;
490
+ });
491
+
492
+ this.get('#/', function() {
493
+ context.route = this;
494
+ });
495
+
496
+ this.get('#/boosh', function() {
497
+ context.route = this;
498
+ });
499
+ });
500
+ }
501
+ })
502
+ .should('run before route', function() {
503
+ var context = this;
504
+ window.location.hash = '#';
505
+ this.app.run('#/');
506
+ soon(function() {
507
+ equal(context.route.params['belch'], 'burp');
508
+ context.app.unload();
509
+ });
510
+ })
511
+ .should('set context to event context', function() {
512
+ var context = this;
513
+ context.app.run('#/');
514
+ soon(function() {
515
+ deepEqual(context.route, context.before);
516
+ context.app.unload();
517
+ });
518
+ })
519
+ .should('not run route if before returns false', function() {
520
+ var context = this;
521
+ context.app.before(function() {
522
+ return false;
523
+ });
524
+ context.app.run('#/');
525
+ soon(function() {
526
+ deepEqual(context.before.app, context.app);
527
+ deepEqual(context.route, {});
528
+ context.app.unload();
529
+ }, this, 1, 2);
530
+ })
531
+ .should('only run if before matches options', function() {
532
+ var context = this;
533
+ context.before_run = [];
534
+ context.app.before({only: '#/boosh'}, function() {
535
+ context.before_run.push('/boosh');
536
+ });
537
+ context.app.before({only: '#/'}, function() {
538
+ context.before_run.push('/')
539
+ });
540
+ window.location.hash = '';
541
+ context.app.run('#/');
542
+ expect(4);
543
+ stop();
544
+ setTimeout(function() {
545
+ ok(context.route);
546
+ equal(context.route.path, '#/');
547
+ deepEqual(context.before_run, ['/'], 'should match /')
548
+ window.location = '#/boosh';
549
+ setTimeout(function() {
550
+ deepEqual(context.before_run, ['/', '/boosh'], "should match ['/', 'boosh']");
551
+ context.app.unload();
552
+ start();
553
+ }, 100);
554
+ }, 200);
555
+ })
556
+
557
+ context('Sammy.Application','after', {
558
+ before: function() {
559
+ var context = this;
560
+ context.after = {};
561
+ context.route = {};
562
+ this.app = new Sammy.Application(function() {
563
+ this.after(function() {
564
+ this.params['belch'] = 'burp';
565
+ context.after = this;
566
+ });
567
+
568
+ this.get('#/', function() {
569
+ this.params['belch'] = 'boosh';
570
+ context.route = this;
571
+ });
572
+ });
573
+ }
574
+ })
575
+ .should('run after route', function() {
576
+ var context = this;
577
+ this.app.run('#/');
578
+ window.location.hash = '#/';
579
+ soon(function() {
580
+ equal(context.after.params['belch'], 'burp');
581
+ context.app.unload();
582
+ }, this, 5, 1);
583
+ })
584
+ .should('set context to event context', function() {
585
+ var context = this;
586
+ context.app.run('#/');
587
+ soon(function() {
588
+ deepEqual(context.route, context.after);
589
+ context.app.unload();
590
+ });
591
+ });
592
+
593
+ context('Sammy.Application', 'around', {
594
+ before: function() {
595
+ window.location.hash = '';
596
+ var context = this;
597
+ context.path = [];
598
+ context.run_route = true;
599
+ this.app = new Sammy.Application(function() {
600
+
601
+ this.around(function(callback) {
602
+ context.path.push('around1 in');
603
+ if (context.run_route) {
604
+ callback();
605
+ }
606
+ context.path.push('around1 out');
607
+ });
608
+
609
+ this.get('#/', function() {
610
+ context.path.push('route ' + this.path);
611
+ });
612
+
613
+ });
614
+ }
615
+ })
616
+ .should('run route with callback()', function() {
617
+ var context = this;
618
+ context.app.run('#/');
619
+ soon(function() {
620
+ deepEqual(context.path, ['around1 in', 'route #/', 'around1 out']);
621
+ context.app.unload();
622
+ });
623
+ })
624
+ .should('not run route if callback is never called', function() {
625
+ var context = this;
626
+ context.run_route = false;
627
+ context.app.run('#/');
628
+ soon(function() {
629
+ deepEqual(context.path, ['around1 in', 'around1 out']);
630
+ context.app.unload();
631
+ });
632
+ })
633
+ .should('run multiple around filters', function() {
634
+ var context = this;
635
+ context.app.around(function(callback) {
636
+ context.path.push('around2 in');
637
+ callback();
638
+ context.path.push('around2 out');
639
+ });
640
+ context.app.run('#/');
641
+ soon(function() {
642
+ deepEqual(context.path, ['around1 in', 'around2 in', 'route #/', 'around2 out', 'around1 out']);
643
+ context.app.unload();
644
+ });
645
+ })
646
+ .should('run before filters after around filter', function() {
647
+ var context = this;
648
+ context.app.before(function() {
649
+ context.path.push('before');
650
+ });
651
+ context.app.run('#/');
652
+ soon(function() {
653
+ deepEqual(context.path, ['around1 in', 'before', 'route #/', 'around1 out']);
654
+ context.app.unload();
655
+ });
656
+ });
657
+
658
+ context('Sammy.Application','helpers', {
659
+ before: function() {
660
+ var context = this;
661
+ context.event_context = null;
662
+ this.app = new Sammy.Application(function() {
663
+
664
+ this.helpers({
665
+ helpme: function() {
666
+ return "halp!";
667
+ }
668
+ });
669
+
670
+ this.get('#/', function() {
671
+ this.params['belch'] = 'boosh';
672
+ context.event_context = this;
673
+ });
674
+
675
+ this.bind('blurgh', function() {
676
+ context.event_context = this;
677
+ });
678
+ });
679
+ }
680
+ })
681
+ .should('extend event context for routes', function() {
682
+ var context = this;
683
+ this.app.run('#/');
684
+ soon(function() {
685
+ ok(context['event_context']);
686
+ isType(context.event_context.helpme, 'Function');
687
+ this.app.unload();
688
+ }, this, 2, 2);
689
+ })
690
+ .should('extend event context for bind', function() {
691
+ var context = this;
692
+ this.app.run('#/');
693
+ this.app.trigger('blurgh');
694
+ soon(function() {
695
+ ok(context['event_context']);
696
+ isType(context.event_context.helpme, 'Function');
697
+ this.app.unload();
698
+ }, this, 2, 2);
699
+ });
700
+
701
+ context('Sammy.Application','helper', {
702
+ before: function() {
703
+ var context = this;
704
+ context.event_context = null;
705
+ this.app = new Sammy.Application(function() {
706
+
707
+ this.helper(
708
+ "helpme", function() {
709
+ return "halp!";
710
+ }
711
+ );
712
+
713
+ this.get('#/', function() {
714
+ this.params['belch'] = 'boosh';
715
+ context.event_context = this;
716
+ });
717
+
718
+ this.bind('blurgh', function() {
719
+ context.event_context = this;
720
+ });
721
+ });
722
+ }
723
+ })
724
+ .should('extend event context for routes', function() {
725
+ var context = this;
726
+ this.app.run('#/');
727
+ soon(function() {
728
+ ok(context['event_context']);
729
+ isType(context.event_context.helpme, 'Function');
730
+ this.app.unload();
731
+ }, this, 2, 2);
732
+ })
733
+ .should('extend event context for bind', function() {
734
+ var context = this;
735
+ this.app.run('#/');
736
+ this.app.trigger('blurgh');
737
+ soon(function() {
738
+ ok(context['event_context']);
739
+ isType(context.event_context.helpme, 'Function');
740
+ this.app.unload();
741
+ }, this, 2, 2);
742
+ });
743
+
744
+ context('Sammy.Application', 'getLocation', {
745
+ before: function() {
746
+ this.app = new Sammy.Application;
747
+ }
748
+ })
749
+ .should('return the browsers hash by default', function() {
750
+ window.location.hash = '#/boosh';
751
+ soon(function() {
752
+ equal(this.app.getLocation(), "#/boosh");
753
+ }, this);
754
+ });
755
+
756
+ context('Sammy.Application', 'setLocation', {
757
+ before: function() {
758
+ this.app = new Sammy.Application;
759
+ }
760
+ })
761
+ .should('set the browsers hash by default', function() {
762
+ this.app.setLocation('#/blurgh');
763
+ soon(function() {
764
+ equal(window.location.hash, '#/blurgh');
765
+ })
766
+ });
767
+
768
+ context('Sammy.Application', 'post routes', {
769
+ before: function() {
770
+ var context = this;
771
+ context.visited = [];
772
+ context.location = "";
773
+ context.posted = false;
774
+ this.app = new Sammy.Application(function() {
775
+
776
+ this.get('#/blah', function() {
777
+ context.location = "blah";
778
+ context.visited.push('blah');
779
+ this.redirect('#/boosh');
780
+ });
781
+
782
+ this.get('#/boosh', function() {
783
+ context.location = "boosh";
784
+ context.visited.push('boosh');
785
+ });
786
+
787
+ this.post(/test/, function() {
788
+ context.location = "post";
789
+ context.posted = true;
790
+ context.visited.push('post');
791
+ this.redirect('#/boosh');
792
+ });
793
+ });
794
+ }
795
+ })
796
+ .should('redirect after a get', function() {
797
+ window.location.hash = '';
798
+ var context = this;
799
+ context.app.run();
800
+ window.location.hash = '/blah';
801
+ expect(3)
802
+ stop();
803
+ setTimeout(function() {
804
+ $('#main form').submit();
805
+ setTimeout(function() {
806
+ ok(context.posted);
807
+ deepEqual(context.visited, ['blah', 'boosh', 'post', 'boosh'], "was: " + context.visited);
808
+ equal(context.location, 'boosh');
809
+ context.app.unload();
810
+ start();
811
+ }, 1000);
812
+ }, 1000);
813
+ });
814
+
815
+ context('Sammy.Application', 'contextMatchesOptions', {
816
+ before: function() {
817
+ this.app = $.sammy();
818
+ this.route = {
819
+ verb: 'get',
820
+ path: '#/boosh',
821
+ params: {
822
+ 'blurgh': 'boosh'
823
+ }
824
+ };
825
+ }
826
+ })
827
+ .should('match against empty options', function() {
828
+ ok(this.app.contextMatchesOptions(this.route, {}));
829
+ })
830
+ .should('match against only with path', function() {
831
+ ok(this.app.contextMatchesOptions(this.route, {only: {path: '#/boosh'}}));
832
+ ok(this.app.contextMatchesOptions(this.route, {only: '#/boosh'}));
833
+ ok(!this.app.contextMatchesOptions(this.route, {only: {path: '#/'}}));
834
+ ok(!this.app.contextMatchesOptions(this.route, {only: '#/'}));
835
+ })
836
+ .should('match against only with path and verb', function() {
837
+ ok(this.app.contextMatchesOptions(this.route, {only: {path: '#/boosh', verb: 'get'}}));
838
+ ok(!this.app.contextMatchesOptions(this.route, {only: {path: '#/boosh', verb: 'put'}}));
839
+ ok(!this.app.contextMatchesOptions(this.route, {only: {path: '#/', verb: 'get'}}));
840
+ })
841
+ .should('match against only with verb', function() {
842
+ ok(this.app.contextMatchesOptions(this.route, {only: {verb: 'get'}}));
843
+ ok(!this.app.contextMatchesOptions(this.route, {only: {verb: 'put'}}));
844
+ })
845
+ .should('match against except with path and verb', function() {
846
+ ok(this.app.contextMatchesOptions(this.route, {except: {path: '#/', verb: 'get'}}));
847
+ ok(!this.app.contextMatchesOptions(this.route, {except: {path: '#/boosh', verb: 'get'}}));
848
+ ok(this.app.contextMatchesOptions(this.route, {except: {path: '#/boosh', verb: 'put'}}));
849
+ })
850
+ .should('match against except with path', function() {
851
+ ok(this.app.contextMatchesOptions(this.route, {except: {path: '#/'}}));
852
+ ok(this.app.contextMatchesOptions(this.route, {except: '#/'}));
853
+ ok(!this.app.contextMatchesOptions(this.route, {except: {path: '#/boosh'}}));
854
+ ok(!this.app.contextMatchesOptions(this.route, {except: '#/boosh'}));
855
+ })
856
+ .should('match against except with verb', function() {
857
+ ok(!this.app.contextMatchesOptions(this.route, {except: {verb: 'get'}}));
858
+ ok(this.app.contextMatchesOptions(this.route, {except: {verb: 'put'}}));
859
+ })
860
+ .should('match against just path', function() {
861
+ ok(this.app.contextMatchesOptions(this.route, '#/boosh'), 'should match exact string path');
862
+ ok(!this.app.contextMatchesOptions(this.route, '#/boo'), 'should not match partial string path');
863
+ ok(this.app.contextMatchesOptions(this.route, /^\#\/boosh/), 'should match regex');
864
+ ok(!this.app.contextMatchesOptions(this.route, /^\#\/$/), 'should not match regex');
865
+ })
866
+ .should('match empty options', function() {
867
+ ok(this.app.contextMatchesOptions(this.route, {}));
868
+ });
869
+
870
+ context('Sammy.Application', 'use', {
871
+ before: function() {
872
+ var context = this;
873
+ var TrivialLogin = function(app, a, b, c) {
874
+ context.plugin_this = this;
875
+ this.a = a;
876
+ app.b = b;
877
+ this.c = c;
878
+
879
+ this.isAuthenticated = function(username) {
880
+ return true;
881
+ }
882
+
883
+ this.helpers({
884
+ alert: function(message) {
885
+ this.$element().append(message);
886
+ },
887
+ partial: function(template, data) {
888
+ return "MY USELESS PARTIAL";
889
+ }
890
+ });
891
+
892
+ this.get('#/login', function(e) {
893
+ e.alert(e.partial("Please Login"));
894
+ });
895
+ };
896
+
897
+ this.app = new Sammy.Application(function() {
898
+ this.use(TrivialLogin, 1, 2, 3);
899
+ this.element_selector = '.get_area';
900
+
901
+ this.get('#/', function() {
902
+ this.alert('BOOSH');
903
+ });
904
+
905
+ });
906
+
907
+ }
908
+ })
909
+ .should('raise error if the plugin is not defined', function() {
910
+ var app = this.app;
911
+ raised(/plugin/, function() {
912
+ app.use(Sammy.Boosh);
913
+ });
914
+ })
915
+ .should('raise error if the plugin is not a function', function() {
916
+ var app = this.app;
917
+ var blah = 'whu';
918
+ raised(/function/, function() {
919
+ app.use(blah);
920
+ });
921
+ })
922
+ .should('evaluate the function within the context of the app', function() {
923
+ equal(this.plugin_this, this.app);
924
+ })
925
+ .should('add defined routes to the applications routes', function() {
926
+ equal(this.app.routes['get'].length, 2);
927
+ })
928
+ .should('add defined methods to the application', function() {
929
+ isType(this.app.isAuthenticated, 'Function');
930
+ })
931
+ .should('override event context methods with helpers()', function() {
932
+ $('.get_area').text('');
933
+ var app = this.app;
934
+ window.location.hash = "";
935
+ app.run('#/login');
936
+ soon(function() {
937
+ equal($('.get_area').text(), 'MY USELESS PARTIAL');
938
+ app.unload();
939
+ });
940
+ })
941
+ .should('not override the global EventContext prototype methods', function() {
942
+ matches(/swap\(/, new Sammy.EventContext().partial.toString());
943
+ })
944
+ .should('yield additional arguments as arguments to the plugin', function() {
945
+ equal(this.app.a, 1);
946
+ equal(this.app.b, 2);
947
+ equal(this.app.c, 3);
948
+ });
949
+
950
+
951
+ }
952
+ // });
953
+ })(jQuery);