jspec-steventux 3.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/History.md +763 -0
  2. data/Manifest +73 -0
  3. data/README.md +974 -0
  4. data/Rakefile +44 -0
  5. data/bin/jspec +178 -0
  6. data/jspec-steventux.gemspec +44 -0
  7. data/lib/images/bg.png +0 -0
  8. data/lib/images/hr.png +0 -0
  9. data/lib/images/loading.gif +0 -0
  10. data/lib/images/sprites.bg.png +0 -0
  11. data/lib/images/sprites.png +0 -0
  12. data/lib/images/vr.png +0 -0
  13. data/lib/jspec.css +149 -0
  14. data/lib/jspec.growl.js +115 -0
  15. data/lib/jspec.jquery.js +72 -0
  16. data/lib/jspec.js +1756 -0
  17. data/lib/jspec.shell.js +39 -0
  18. data/lib/jspec.timers.js +90 -0
  19. data/lib/jspec.xhr.js +195 -0
  20. data/spec/commands/example_command.rb +19 -0
  21. data/spec/dom.html +33 -0
  22. data/spec/fixtures/test.html +1 -0
  23. data/spec/fixtures/test.json +1 -0
  24. data/spec/fixtures/test.xml +5 -0
  25. data/spec/node.js +17 -0
  26. data/spec/rhino.js +23 -0
  27. data/spec/ruby/bin/init_spec.rb +101 -0
  28. data/spec/ruby/bin/install_spec.rb +142 -0
  29. data/spec/ruby/bin/run_spec.rb +0 -0
  30. data/spec/ruby/bin/shell_spec.rb +13 -0
  31. data/spec/ruby/bin/spec_helper.rb +8 -0
  32. data/spec/ruby/bin/update_spec.rb +72 -0
  33. data/spec/server.html +29 -0
  34. data/spec/server.rb +2 -0
  35. data/spec/support/env.js +10118 -0
  36. data/spec/support/jquery.js +4376 -0
  37. data/spec/unit/helpers.js +64 -0
  38. data/spec/unit/spec.fixtures.js +17 -0
  39. data/spec/unit/spec.grammar-less.js +34 -0
  40. data/spec/unit/spec.grammar.js +241 -0
  41. data/spec/unit/spec.jquery.js +178 -0
  42. data/spec/unit/spec.jquery.xhr.js +84 -0
  43. data/spec/unit/spec.js +187 -0
  44. data/spec/unit/spec.matchers.js +577 -0
  45. data/spec/unit/spec.modules.js +51 -0
  46. data/spec/unit/spec.shared-behaviors.js +80 -0
  47. data/spec/unit/spec.utils.js +346 -0
  48. data/spec/unit/spec.xhr.js +157 -0
  49. data/src/browsers.rb +294 -0
  50. data/src/helpers.rb +67 -0
  51. data/src/installables.rb +229 -0
  52. data/src/project.rb +341 -0
  53. data/src/routes.rb +57 -0
  54. data/src/server.rb +99 -0
  55. data/support/js.jar +0 -0
  56. data/templates/default/History.md +5 -0
  57. data/templates/default/Readme.md +29 -0
  58. data/templates/default/lib/yourlib.js +2 -0
  59. data/templates/default/spec/commands/example_command.rb +19 -0
  60. data/templates/default/spec/dom.html +22 -0
  61. data/templates/default/spec/node.js +10 -0
  62. data/templates/default/spec/rhino.js +10 -0
  63. data/templates/default/spec/server.html +18 -0
  64. data/templates/default/spec/server.rb +4 -0
  65. data/templates/default/spec/unit/spec.helper.js +0 -0
  66. data/templates/default/spec/unit/spec.js +8 -0
  67. data/templates/rails/commands/example_commands.rb +19 -0
  68. data/templates/rails/dom.html +22 -0
  69. data/templates/rails/rhino.js +10 -0
  70. data/templates/rails/server.html +18 -0
  71. data/templates/rails/server.rb +4 -0
  72. data/templates/rails/unit/spec.helper.js +0 -0
  73. data/templates/rails/unit/spec.js +8 -0
  74. metadata +185 -0
@@ -0,0 +1,73 @@
1
+ History.md
2
+ Manifest
3
+ README.md
4
+ Rakefile
5
+ bin/jspec
6
+ jspec.gemspec
7
+ lib/images/bg.png
8
+ lib/images/hr.png
9
+ lib/images/loading.gif
10
+ lib/images/sprites.bg.png
11
+ lib/images/sprites.png
12
+ lib/images/vr.png
13
+ lib/jspec.css
14
+ lib/jspec.growl.js
15
+ lib/jspec.jquery.js
16
+ lib/jspec.js
17
+ lib/jspec.shell.js
18
+ lib/jspec.timers.js
19
+ lib/jspec.xhr.js
20
+ spec/commands/example_command.rb
21
+ spec/dom.html
22
+ spec/fixtures/test.html
23
+ spec/fixtures/test.json
24
+ spec/fixtures/test.xml
25
+ spec/node.js
26
+ spec/rhino.js
27
+ spec/ruby/bin/init_spec.rb
28
+ spec/ruby/bin/install_spec.rb
29
+ spec/ruby/bin/run_spec.rb
30
+ spec/ruby/bin/shell_spec.rb
31
+ spec/ruby/bin/spec_helper.rb
32
+ spec/ruby/bin/update_spec.rb
33
+ spec/server.html
34
+ spec/server.rb
35
+ spec/support/env.js
36
+ spec/support/jquery.js
37
+ spec/unit/helpers.js
38
+ spec/unit/spec.fixtures.js
39
+ spec/unit/spec.grammar-less.js
40
+ spec/unit/spec.grammar.js
41
+ spec/unit/spec.jquery.js
42
+ spec/unit/spec.jquery.xhr.js
43
+ spec/unit/spec.js
44
+ spec/unit/spec.matchers.js
45
+ spec/unit/spec.modules.js
46
+ spec/unit/spec.shared-behaviors.js
47
+ spec/unit/spec.utils.js
48
+ spec/unit/spec.xhr.js
49
+ src/browsers.rb
50
+ src/helpers.rb
51
+ src/installables.rb
52
+ src/project.rb
53
+ src/routes.rb
54
+ src/server.rb
55
+ support/js.jar
56
+ templates/default/History.md
57
+ templates/default/Readme.md
58
+ templates/default/lib/yourlib.js
59
+ templates/default/spec/commands/example_command.rb
60
+ templates/default/spec/dom.html
61
+ templates/default/spec/node.js
62
+ templates/default/spec/rhino.js
63
+ templates/default/spec/server.html
64
+ templates/default/spec/server.rb
65
+ templates/default/spec/unit/spec.helper.js
66
+ templates/default/spec/unit/spec.js
67
+ templates/rails/commands/example_commands.rb
68
+ templates/rails/dom.html
69
+ templates/rails/rhino.js
70
+ templates/rails/server.html
71
+ templates/rails/server.rb
72
+ templates/rails/unit/spec.helper.js
73
+ templates/rails/unit/spec.js
@@ -0,0 +1,974 @@
1
+ # This is a work in progress fork of visionmedia/jspec aimed at CI testing.
2
+
3
+
4
+
5
+ # JSpec
6
+
7
+ JSpec is a minimalistic JavaScript behavior driven development framework,
8
+ providing **simple installation**, extremely **low learning curve**, absolutely **no pollution**
9
+ to core prototypes, async request support, and incredibly sexy syntax, tons of matchers
10
+ and **much more**.
11
+
12
+ ## Features
13
+
14
+ * Highly readable
15
+ * Framework / DOM independent
16
+ * Modular via JSpec Module's and hooks
17
+ * Mock Ajax Requests
18
+ * Rhino support
19
+ * Node.js support
20
+ * Async support
21
+ * Growl (unobtrustive notifications) support
22
+ * Fixture support
23
+ * Ruby JavaScript testing server
24
+ * Nested describes
25
+ * Does not pollute core object prototypes
26
+ * Cascading before/after/before_each/after_each hooks
27
+ * Extremely simple and intuitive matcher declaration
28
+ * Over 45 core matchers
29
+ * Allows parens to be optional when using matchers to increase readability
30
+ * Several helpful reporters (DOM, Terminal, ...)
31
+ * Assertion graphs displaying how many, and which assertions pass or failed
32
+ * Default / customizable evaluation contexts
33
+ * DOM sandbox support
34
+ * Great looking default DOM theme
35
+ * `jspec` command-line utility for auto-running specs, and initializing project templates
36
+ * Proxy or 'Spy' assertions
37
+ * Method Stubbing
38
+ * Shared behaviors
39
+ * Extend the jspec executable with project / user specific sub-commands.
40
+ * Profiling
41
+ * Interactive Shell
42
+ * Ruby on Rails Integration
43
+ * Install support projects with a single command (jQuery, Rhino, Prototype, Dojo, etc)
44
+ * Tiny (2000-ish LOC)
45
+
46
+ ## Companies Using JSpec
47
+
48
+ To add or request removal from this list please email tj@vision-media.ca
49
+
50
+ * [Apple](http://apple.com)
51
+ * [Google - YouTube](http://youtube.com)
52
+ * [Palm](http://palm.com)
53
+ * [Carfax](http://carfax.com)
54
+ * [Vision Media](http://vision-media.ca)
55
+
56
+ ## Installation
57
+
58
+ Simply download JSpec and include _JSpec.css_ and _JSpec.js_ in your markup.
59
+ Head over to the downloads section on Github, clone this public repo, or
60
+ add JSpec as a git submodule with in your project. Alternatively JSpec is
61
+ also available as a Ruby Gem (though this is not required), which also
62
+ provides the `jspec` executable. First install [Gemcutter](http://gemcutter.org/) then execute:
63
+ $ sudo gem install jspec
64
+
65
+ At which point you may:
66
+
67
+ $ jspec init myproject
68
+
69
+ By default, the command above will use absolute path for all JSpec library files.
70
+ This behavior can be a problem when you're working across different computers or
71
+ operating systems. You can freeze the library or symlink it.
72
+
73
+ $ jspec init myproject --freeze
74
+ $ jspec init myproject --symlink
75
+
76
+ JSpec scripts should NOT be referenced via the `<script>` tag, they should be
77
+ loaded using the exec method (**unless you are using the grammar-less alternative**).
78
+ Below is an example:
79
+
80
+ ...
81
+ <script>
82
+ function runSuites() {
83
+ JSpec
84
+ .exec('spec.core.js')
85
+ .exec('spec.jquery.js')
86
+ .run({ failuresOnly : true })
87
+ .report()
88
+ }
89
+ </script>
90
+ <body onLoad="runSuites()">
91
+ ...
92
+
93
+ You may optionally want to use sources in the _/pkg_ directory
94
+ for your project, since it includes compressed alternatives generated
95
+ each release.
96
+
97
+ ## Example
98
+
99
+ describe 'ShoppingCart'
100
+ before_each
101
+ cart = new ShoppingCart
102
+ end
103
+
104
+ describe 'addProducts'
105
+ it 'should add several products'
106
+ cart.addProduct('cookie')
107
+ cart.addProduct('icecream')
108
+ cart.should.have 2, 'products'
109
+ end
110
+ end
111
+
112
+ describe 'checkout'
113
+ it 'should throw an error when checking out with no products'
114
+ -{ cart.clear().checkout() }.should.throw_error EmptyCart
115
+ end
116
+ end
117
+ end
118
+
119
+ ## Grammar-less Example
120
+
121
+ JSpec's grammar is optional, you may also use the equivalent grammar-less
122
+ alternative below using pure JavaScript (when using the JSpec grammar you
123
+ may also use grammar-less assertions):
124
+
125
+ JSpec.describe('ShoppingCart', function(){
126
+ before_each(function{
127
+ cart = new ShoppingCart
128
+ })
129
+
130
+ describe('addProducts', function(){
131
+ it ('should add several products', function(){
132
+ cart.addProducts('cookie')
133
+ cart.addProducts('icecream')
134
+ expect(cart).to(have, 2, 'products')
135
+ })
136
+ })
137
+
138
+ describe('checkout', function(){
139
+ it ('should throw an error when checking out with no products', function(){
140
+ expect(function(){ cart.clear().checkout() }).to(throw_error, EmptyCart)
141
+ })
142
+ })
143
+ })
144
+
145
+ ## Options
146
+
147
+ The following options may be passed to _JSpec.run()_.
148
+
149
+ - fixturePath
150
+ - {string} path to fixture directory (DOM, Terminal, Server)
151
+ - failuresOnly
152
+ - {bool} displays only failing specs, making them quick to discover and fix (DOM, Terminal, Server)
153
+ - reportToId
154
+ - {string} an element id to report to when using the DOM reporter (DOM)
155
+ - verbose
156
+ - {bool} verbose server output, defaults to false (Server)
157
+
158
+ ## Matchers
159
+
160
+ ### Core
161
+
162
+ - equal, be
163
+ - ===
164
+ - be_a, be_an
165
+ - have constructor of x
166
+ - be_an_instance_of
167
+ - instanceof x
168
+ - be_at_least
169
+ - &gt;=
170
+ - be_at_most
171
+ - &lt;=
172
+ - be_null
173
+ - == null
174
+ - be_empty
175
+ - length &lt; 0 or {}
176
+ - be_true
177
+ - == true
178
+ - be_false
179
+ - == false
180
+ - be_type
181
+ - be type of x
182
+ - be_greater_than
183
+ - &gt;
184
+ - be_less_than
185
+ - &lt;
186
+ - be_undefined
187
+ - check if variable passed is undefined
188
+ - throw_error
189
+ - should throw an error, optionally supply the error string or regexp for message comparison
190
+ - have
191
+ - object should have n of property (person.should.have(2, 'pets'))
192
+ - have_at_least
193
+ - object should have at least n of property
194
+ - have_at_most
195
+ - object should have a maximum n of property
196
+ - have_within
197
+ - object should have within n..n of property (person.should.have_within(1..3, 'pets')
198
+ - have_length
199
+ - length of n
200
+ - have_prop
201
+ - object should have property x, optionally supplying an expected value
202
+ - have_property
203
+ - strict version of have_prop
204
+ - be_within
205
+ - checks if n is within the range passed
206
+ - include
207
+ - include substring, array element, or hash key
208
+ - match
209
+ - string should match regexp x
210
+ - respond_to
211
+ - property x should be a function
212
+ - eql
213
+ - matches simple literals (strings, numbers) with ==
214
+ However composites like arrays or 'hashes' are recursively matched,
215
+ meaning that [1, 2, [3]].should_eql([1, 2, [3]]) will be true.
216
+
217
+ ### jQuery
218
+
219
+ - have_tag, have_one
220
+ - have exactly one tag
221
+ - have_tags, have_many
222
+ - have more than one tag
223
+ - have_child
224
+ - have exactly one child
225
+ - have_children
226
+ - have more than one child
227
+ - have_text
228
+ - have plain text
229
+ - have_attr
230
+ - have an attribute, with optional value
231
+ - have_type
232
+ - have_id
233
+ - have_title
234
+ - have_alt
235
+ - have_href
236
+ - have_rel
237
+ - have_rev
238
+ - have_name
239
+ - have_target
240
+ - have_value
241
+ - have_class
242
+ - have_classes
243
+ - be_visible
244
+ - be_hidden
245
+ - be_enabled
246
+ - be_disabled
247
+ - be_selected
248
+ - be_checked
249
+
250
+ ## Growl Support
251
+
252
+ JSpec uses the [JavaScript Growl](http://github.com/visionmedia/js-growl) library to provide
253
+ growl support when using the **Rhino JavaScript engine**. To enable simply `load()` _jspec.growl.js_
254
+ within _spec/rhino.js_
255
+
256
+ ## Async Support With Mock Timers
257
+
258
+ The javascript mock timers library is available at [http://github.com/visionmedia/js-mock-timers](http://github.com/visionmedia/js-mock-timers)
259
+ although it is already bundled with JSpec at _lib/jspec.timers.js_
260
+
261
+ Timers return ids and may be passed to `clearInterval()`, however
262
+ they do not execute in threads, they must be manually scheduled and
263
+ controlled via the `tick()` function.
264
+
265
+ setTimeout(function(){
266
+ alert('Wahoo!')
267
+ }, 400)
268
+
269
+ tick(200) // Nothing happens
270
+ tick(400) // Wahoo!
271
+
272
+ `setInterval()` works as expected, although it persists, where as `setTimeout()`
273
+ is destroyed after a single call. As conveyed by the last `tick()` call below,
274
+ a large increment in milliseconds may cause the callbacks to be called several times
275
+ to 'catch up'.
276
+
277
+ progress = ''
278
+ var id = setInterval(function(){
279
+ progress += '.'
280
+ }, 100)
281
+
282
+ tick(50), print(progress) // ''
283
+ tick(50), print(progress) // '.'
284
+ tick(100), print(progress) // '..'
285
+ tick(100), print(progress) // '...'
286
+ tick(300), print(progress) // '......'
287
+
288
+ clearInterval(id)
289
+
290
+ tick(800) // Nothing happens
291
+
292
+ You may also reset at any time using resetTimers()
293
+
294
+ ## Proxy Assertions
295
+
296
+ Proxy or 'Spy' assertions allow you to assert that a method is called n number
297
+ of times, with x arguments, returning x value. For example:
298
+
299
+ person = { getPets : function(species){ return ['izzy'] }}
300
+ person.should.receive('getPets', 'twice').with_args(an_instance_of(String))and_return(['izzy'])
301
+ person.getPets('dog') // This will pass
302
+ person.getPets() // This will fail because we asked an instance of String
303
+
304
+ This is a useful mechanism for testing the behavior of your object, as well as
305
+ how other methods may interact with it. Below is another example:
306
+
307
+ array = ['foo', 'bar']
308
+ array.should.receive('toString').and_return('foo,bar')
309
+ 'array: ' + array // This line causes the spec to pass due to calling toString()
310
+
311
+ For more examples view _spec/spec.matchers.js_
312
+
313
+ ## Method Stubbing
314
+
315
+ JSpec currently provides very simple stubbing support shown below:
316
+
317
+ person = { toString : function(){ return '<Person>' } }
318
+ stub(person, 'toString').and_return('Ive been stubbed!')
319
+
320
+ After each spec all stubs are restored to their original methods so
321
+ there is no reason to explicitly call `destub()`. To persist stubs,
322
+ use a before_each hook:
323
+
324
+ before_each
325
+ stub(someObject, 'method').and_return({ some : thing })
326
+ end
327
+
328
+ To destub a method simply call `destub()` at any time:
329
+
330
+ destub(person, 'toString')
331
+
332
+ If you would like to whipe an object clear of stubs simply pass it
333
+ to `destub()` without an additional method argument:
334
+
335
+ destub(person)
336
+
337
+ Alternatively both these utility functions may be called as methods
338
+ on any object when using the JSpec grammar:
339
+
340
+ someObject.stub('method').and_return('whatever')
341
+ // Converted to stub(someObject, 'method').and_return('whatever')
342
+
343
+ ## Helpers
344
+
345
+ * core
346
+
347
+ - an_instance_of
348
+ - used in conjunction with the 'receive' matcher
349
+
350
+ * jspec.xhr.js
351
+ - mockRequest, mock_request
352
+ - mock a request
353
+ - unmockRequest, unmock_request
354
+ - unmock requests
355
+ - lastRequest, last_request
356
+ - access previous request data
357
+
358
+ * jspec.jquery.js
359
+
360
+ - sandbox
361
+ - used to generate new DOM sandbox, using jQuery object
362
+ - element
363
+ - same as invoking jQuery, just reads better and no need to worry about $ collisions
364
+ - elements
365
+ - alias of element
366
+
367
+ ## Shared Behaviors
368
+
369
+ JSpec's support for shared behaviors allows multiple suites or describe blocks to share
370
+ common functionality. For example an Admin, would inherit all specs of User:
371
+
372
+ describe 'User'
373
+ before
374
+ User = function(name) { this.name = name }
375
+ user = new User('joe')
376
+ end
377
+
378
+ it 'should have a name'
379
+ user.should.have_property 'name'
380
+ end
381
+
382
+ describe 'Administrator'
383
+ should_behave_like('User')
384
+
385
+ before
386
+ Admin = function(name) { this.name = name }
387
+ Admin.prototype.may = function(perm){ return true }
388
+ user = new Admin('tj')
389
+ end
390
+
391
+ it 'should have access to all permissions'
392
+ user.may('edit pages').should.be_true
393
+ end
394
+ end
395
+ end
396
+
397
+ **NOTE**: both User and Administrator's before hooks implement the 'user' variable
398
+
399
+ ## Mock Ajax Requests
400
+
401
+ JSpec supports generic Ajax mocking which is usable with any JavaScript framework via _jspec.xhr.js_. The
402
+ API is comprised of two functions, `mock_request()` and `unmock_request()`. `unmock_request()` is
403
+ automatically called after each specification to restore the default functionality of XMLHttpRequest,
404
+ so it is uncommon to call `unmock_request()` directly. Below is a jQuery example:
405
+
406
+ it 'should mock requests'
407
+ mock_request().and_return('{ foo : "bar" }', 'application/json')
408
+ $.getJSON('foo', function(response, statusText){
409
+ response.foo.should.eql 'bar'
410
+ })
411
+ end
412
+
413
+ The mock_request().and_return signature is as follows:
414
+
415
+ mock_request().and_return(<data>, [content-type], [response-status-code], [headers-hash])
416
+
417
+ At the moment `mock_request()` itself does not accept any arguments, however in the future
418
+ this will be used to target specific uris for mocking.
419
+
420
+ **NOTE**: works with Rhino as well
421
+
422
+ ## Hooks
423
+
424
+ Currently the following hooks are supported, and may be utilized any number of times as they
425
+ are simply pushed to a stack. So for instance you may have two before_each blocks within the same
426
+ scope, they will both run, but this can help keep your specs readable.
427
+
428
+ - before
429
+ - run once before the suite is executed
430
+ - after
431
+ - run once after the suite is executed
432
+ - before_each
433
+ - run before each specification
434
+ - after_each
435
+ - run after each specification
436
+
437
+ ## Custom Contexts
438
+
439
+ Custom contexts can be applied to supply helper
440
+ methods or properties to all subsequent bodies (other hooks, or specs).
441
+
442
+ Keep in mind that when replacing the default context you will loose
443
+ functionality provided by it, unless you manually merge it with your
444
+ custom context.
445
+
446
+ To reset the context simply assign null to obtain the original context.
447
+
448
+ ...
449
+ before
450
+ JSpec.context = { foo : 'bar' }
451
+ end
452
+
453
+ after
454
+ JSpec.context = null
455
+ end
456
+
457
+ it 'will work ;)'
458
+ foo.should_equal 'bar'
459
+ end
460
+ ...
461
+
462
+ ## Async Support
463
+
464
+ Currently only _jspec.jquery.js_ supports async requests. JSpec uses `jQuery.ajaxSetup` and sets all
465
+ requests to sync, which preserves execution order, and reports correctly.
466
+
467
+ it 'should load mah cookies (textfile)'
468
+ $.post('async', function(text){
469
+ text.should_eql 'cookies!'
470
+ })
471
+ end
472
+
473
+ ## Grammer Pre-processor
474
+
475
+ The pre-processing capability of JSpec is extremely powerful. Your JavaScript
476
+ code is not necessarily what it seems. For example when you seemingly invoke a
477
+ object's prototype like below:
478
+
479
+ 'foobar'.should.include 'bar'
480
+
481
+ First parens are added:
482
+
483
+ 'foobar'.should.include('bar')
484
+
485
+ Secondly the matcher invocation is converted to a non-polluting match() call:
486
+
487
+ expect('foobar').to(include, 'bar')
488
+
489
+ This also means instead of:
490
+
491
+ var object = { foo : 'bar' }
492
+ object.should.include 'foo'
493
+
494
+ We can do:
495
+
496
+ { foo : 'bar' }.should.include 'foo'
497
+
498
+ ### Closure Literal
499
+
500
+ These are equivalent:
501
+
502
+ -{ throw 'test' }.should.throw_error
503
+ function() { throw 'test' }.should.throw_error
504
+
505
+ ### Inclusive Range Literal
506
+
507
+ The following expands to the array of [1,2,3,4,5]
508
+
509
+ n.should.be_within 1..5
510
+
511
+ ### __END__
512
+
513
+ Any text placed after **__END__** is considered irrelevant and
514
+ is striped out before evaluation. This is sometimes useful for
515
+ document or code reference while writing specs.
516
+
517
+ For example when writting regression specs it is sometimes useful
518
+ to paste the issue ticket's comment(s) below this area for reference.
519
+
520
+ ## Formatters
521
+
522
+ To change a reporter simply alter the options hash like below, assigning
523
+ a new constructor, or pass it within the hash to `run()`:
524
+
525
+ JSpec.options.reporter = JSpec.reporters.Terminal
526
+
527
+ OR
528
+
529
+ JSpec
530
+ .exec('...')
531
+ .run({ reporter: JSpec.reporters.Terminal })
532
+ .report()
533
+
534
+ ## Fixtures
535
+
536
+ The `fixture()` utility function may be used in order to load arbitrary file contents
537
+ for use with your specifications. JSpec will resolve `fixture('data')` in the following
538
+ manor:
539
+
540
+ - <fixturePath>/data
541
+ - <fixturePath>/data.html
542
+
543
+ In order for the `fixture()` utility to function you must pass the **fixturePath** option
544
+ to _JSpec.run()_ which provides JSpec with the fixture directory.
545
+
546
+ ## Testing DOM Elements
547
+
548
+ When using jQuery testing DOM elements is very easy. Many may think they require specific
549
+ sandbox divs in their html, however you do not. Using the fixture support mentioned above
550
+ you may simply load some HTML, and use the `elements()` utility which is an alias of jQuery:
551
+
552
+ describe 'JSpec DOM testing'
553
+ describe 'is so easy'
554
+ before_each
555
+ list = elements(fixture('users-list'))
556
+ // or list = jQuery(fixture('users-list'))
557
+ // or list = $(fixture('users-list'))
558
+ end
559
+
560
+ it 'should have users'
561
+ list.should.have_tag 'ul'
562
+ end
563
+ end
564
+ end
565
+
566
+ You may also use simple strings, since jQuery's constructor will convert them to DOM elements:
567
+
568
+ describe 'Something'
569
+ before_each
570
+ html = elements('<p>Foo</p>')
571
+ // or html = $('<p>Foo</p>') ...
572
+ end
573
+
574
+ it 'should do something'
575
+ html.should.have_text 'Foo'
576
+ end
577
+ end
578
+
579
+ ## Custom Matchers
580
+
581
+ First lets create a simple equality matcher. In the case below JSpec is smart enough to realize
582
+ this is simply a binary operator, and simply transforms this into `actual === expected`
583
+
584
+ JSpec.addMatchers({
585
+ equal : '==='
586
+ })
587
+
588
+ To alias a method to keep your specs readable you may alias them like below:
589
+
590
+ JSpec.addMatchers({
591
+ be : 'alias equal'
592
+ })
593
+
594
+ 'foo'.should.equal 'foo'
595
+ true.should.be true
596
+
597
+ Matchers with string bodies implicitly return the expression value.
598
+ The expanded version of the equal matcher would then be:
599
+
600
+ JSpec.addMatchers({
601
+ equal : 'actual === expected'
602
+ })
603
+
604
+ Large matchers or those which require several parameters may wish
605
+ to utilize the hash method:
606
+
607
+ JSpec.addMatchers({
608
+ equal : { match : function(actual, expected){
609
+ return actual === expected
610
+ }}
611
+ })
612
+
613
+ To keep JSpec tiny, JSpec will default to generating failure messages
614
+ for you, how ever this can be explicitly defined:
615
+
616
+ JSpec.addMatchers({
617
+ equal : {
618
+ match : function(actual, expected){
619
+ return actual === expected
620
+ },
621
+ message : function(actual, expected, negate) {
622
+ return 'a message here'
623
+ }
624
+ }
625
+ })
626
+
627
+ When defining matchers that are extremely similar in functionality, however
628
+ require different names, you may use a prefixed list of words like below which
629
+ defines be_disabled, be_selected, be_checked, and have_type, have_id, etc. Each
630
+ function must return the matcher body which will be used.
631
+
632
+ JSpec.addMatchers({
633
+ 'be disabled selected checked' : function(attr) {
634
+ return 'jQuery(actual).attr("' + attr + '")'
635
+ },
636
+
637
+ 'have type id title alt href src sel rev name target' : function(attr) {
638
+ return function(actual, value) {
639
+ return value ? jQuery(actual).attr(attr) ## value:
640
+ jQuery(actual).attr(attr)
641
+ }
642
+ }
643
+ })
644
+
645
+ ## Extending Or Hooking Into JSpec
646
+
647
+ JSpec provides a hook architecture for extending or analyzing various
648
+ points in its execution, through the use of modules. For a module
649
+ example view _lib/jspec.jquery.js_.
650
+
651
+ The following methods or properties are utilized by JSpec:
652
+
653
+ - name : module name string
654
+ - init : called to initialize a module
655
+ - reporters : hash of reporters merged with JSpec.reporters
656
+ - utilities : hash of utility functions merged with JSpec.defaultContext
657
+ - matchers : hash of matchers merged with JSpec's core matchers via JSpec.addMatchers()
658
+ - DSLs : hash of DSL methods; for example DSLs.snake contains before_each, after_each, etc.
659
+ Where as DSLs.camel may contain beforeEach, afterEach, etc.
660
+
661
+ Below is a list of hooks, descriptions, and valid return values which
662
+ may simply be implemented as module methods. beforeSuite, afterSuite, beforeSpec, and afterSpec have lower
663
+ precedence than before_each, after_each etc within the specs themselves, allowing them to override or undo
664
+ anything that has been done by a Module.
665
+
666
+ - running(options) : started running JSpec with the options passed : returning 'stop' will halt running
667
+ - loading(file) : loading a file : returning 'stop' will prevent loading
668
+ - executing(file) : executing a file : returning 'stop' will prevent execution
669
+ - posting(data, url) : posting data to a url : returning 'stop' will prevent request
670
+ - preprocessing(input) : before input string is preprocessed : return input string for next hook to preprocess
671
+ - stubbing(object, method, result) : called when stubbing an object's method, and return value (result). : (no return value)
672
+ - requiring(dependency, message) : requiring a dependency : (no return value)
673
+ - beforeAssertion(assertion) : before an assertion has been made : (no return value)
674
+ - afterAssertion(assertion) : after an assertion has been made : (no return value)
675
+ - addingMatcher(name, body) : unprocessed matcher name and body : (no return value)
676
+ - addingSuite(suite) : adding Suite instance to JSpec : (no return value)
677
+ - beforeSuite(suite) : before running of suite (describe block) : (no return value)
678
+ - afterSuite(suite) : after running of suite (describe block) : (no return value)
679
+ - beforeSpec(spec) : before running of spec (it block) : (no return value)
680
+ - afterSpec(spec) : after running of spec (it block) : (no return value)
681
+ - reporting(options) : called before reporting : (no return value)
682
+ - evaluatingBody(dsl, matchers, context, contents) : evaluating body contents, with the given context, matchers and dsl. : (no return value)
683
+
684
+ For example you may wish to proxy files which are being executed, simply implement the
685
+ executing method like below. This example will stop execution of any file matching /matchers/.
686
+
687
+ MyModule = {
688
+ executing : function(file) {
689
+ if (file.match(/matchers/))
690
+ return 'stop'
691
+ }
692
+ }
693
+ JSpec.include(MyModule)
694
+
695
+ Immutable values may also be passed to hooks using hookImmutable() internally. This allows
696
+ for simple numbers, strings, etc to be utilized or altered within a hook implementation. Below
697
+ is an example module which adds functionality to the JSpec grammar by converting `SomeObject.stub('method')`
698
+ to `stub(SomeObject, 'method')`:
699
+
700
+ JSpec.include({
701
+ preprocessing : function(input) {
702
+ return input.replace(/(\w+)\.(stub|destub)\((.*?)\)$/gm, '$2($1, $3)')
703
+ }
704
+ })
705
+
706
+ ## JSpec Command-line Utility
707
+
708
+ When installed as a Ruby Gem, the `jspec` executable will become available,
709
+ allowing you to initialize project templates quickly, as well as auto-testing
710
+ specifications when a file is altered.
711
+
712
+ Initialize JSpec-driven project template in directory _myproject_:
713
+ $ jspec init myproject
714
+
715
+ Once within 'myproject' start testing by executing:
716
+ $ jspec
717
+
718
+ For additional usage execute:
719
+ $ jspec help
720
+
721
+ Or for specific usage:
722
+ $ jspec help run
723
+
724
+ ## Extending JSpec's Executable
725
+
726
+ Both project specific, and user specific sub-commands may be used to
727
+ extend those already provided by `jspec`. For example create the following
728
+ in spec/commands/example_command.rb which are loaded when `jspec` is executed.
729
+
730
+ command :example do |c|
731
+ c.syntax = 'jspec example [options]'
732
+ c.description = 'Just an example command'
733
+ c.option '-f', '--foo string', 'Does some foo with <string>'
734
+ c.option '-b', '--bar [string]', 'Does some bar with [string]'
735
+ c.example 'Do some foo', 'jspec example --foo bar'
736
+ c.example 'Do some bar', 'jspec example --bar'
737
+ c.when_called do |args, options|
738
+ p args
739
+ p options.__hash__
740
+ # options.foo
741
+ # options.bar
742
+ # options.__hash__[:foo]
743
+ # options.__hash__[:bar]
744
+ end
745
+ end
746
+
747
+ And execute with:
748
+
749
+ `$ jspec example`
750
+
751
+ They may also be placed at ~/jspec/commands for global usage.
752
+
753
+ For more information on the command creation visit http://visionmedia.github.com/commander
754
+
755
+ ## Installing Support Projects
756
+
757
+ Lets say you need jQuery for your project, and wish to test against it. You could download
758
+ jQuery manually, use an absolute uri to Google's CDN, or use the following command, which will
759
+ install jQuery to _spec/support/jquery.js_.
760
+ $ jspec install jquery
761
+
762
+ Alternatively we may specify the destination path:
763
+ $ jspec install jquery spec/jquery.js
764
+
765
+ Or provide a specific version string:
766
+ $ jspec install jquery --release 1.3.1
767
+
768
+ The install command will also install Rhino for you (**MacOS only**) so you
769
+ can run specs, and js via the command-line.
770
+ $ jspec install rhino
771
+
772
+ To view the current projects supported view:
773
+ $ jspec help install
774
+
775
+ ## Rhino
776
+
777
+ JSpec provides transparent support for Rhino, while using the Terminal reporter.
778
+ Simply create a JavaScript file with contents similar to below, and then execute
779
+ the command following it:
780
+
781
+ load('lib/jspec.js')
782
+
783
+ JSpec
784
+ .exec('spec/spec.grammar.js')
785
+ .exec('spec/spec.core.js')
786
+ .run({ reporter: JSpec.reporters.Terminal, failuresOnly: true })
787
+ .report()
788
+
789
+ Initialize project with:
790
+ $ jspec init myproject
791
+
792
+ Run with:
793
+ $ jspec run --rhino
794
+
795
+ Or bind (automated testing):
796
+ $ jspec --rhino
797
+
798
+ ## Server
799
+
800
+ The Ruby JavaScript testing server included with JSpec simply runs
801
+ the spec suites within each browser you specify, while reporting result
802
+ back to the terminal. It is essentially the same as using the DOM reporter
803
+ and auto-testing each browser, however results are centralized to the terminal,
804
+ removing the need to manually view each browser's output.
805
+
806
+ When utilizing the server if a file named _spec/jspec.rb_ (or _jspec/jspec.rb_ for rails)
807
+ is present, then it will be loaded before the server is started. This allows you to
808
+ add Sinatra routes, support additional Browsers, etc.
809
+
810
+ Run with all supported browsers:
811
+ $ jspec run --server
812
+
813
+ Run with specific browsers:
814
+ $ jspec run --browsers Safari,Firefox,Chrome,Explorer
815
+
816
+ Run with alternative browser names:
817
+ $ jspec run --browsers safari,ff,chrome,ie
818
+
819
+ Browsers supported in core:
820
+
821
+ - Browser::Default (system default)
822
+ - Browser::Safari
823
+ - Browser::WebKit
824
+ - Browser::Chrome
825
+ - Browser::Firefox
826
+ - Browser::Opera
827
+ - Browser::IE
828
+
829
+ Supplied routes:
830
+
831
+ - /slow/NUMBER
832
+ - /status/NUMBER
833
+
834
+ For example `$.get('/slow/4', function(){})` will take 4 seconds
835
+ to reply, where as `$.get('/status/404', function(){})` will respond
836
+ with an 404 status code. Add additional Sinatra routes to the jspec.rb
837
+ file to add your own functionality.
838
+
839
+ ## Interactive Shell
840
+
841
+ JSpec provides an interactive shell through Rhino, utilize with:
842
+
843
+ $ jspec shell
844
+
845
+ Or to specify additional files to load:
846
+
847
+ $ jspec shell lib/*.js
848
+
849
+ Or view additional shell help
850
+
851
+ $ jspec help shell
852
+
853
+ When running the shell JSpec provides several commands:
854
+
855
+ - quit, exit
856
+ - Terminate the shell session
857
+ - p()
858
+ - Inspect the object passed
859
+
860
+ Or add your own. In the examples below, `foo` will become a getter, so it can
861
+ be invoked simply as `$ foo ` where as `bar` is a regular function which must be called
862
+ as `$ bar("something") `.
863
+
864
+ Shell.commands.foo = ['Does some foo', function(){ return 'something' }]
865
+ Shell.commands.bar = ['Does some bar', function(o){ return 'something' }]
866
+
867
+ ## Ruby on Rails
868
+
869
+ No additional gems are required for JSpec to work with rails, although
870
+ [jspec-rails](http://github.com/bhauman/jspec-rails) has been created by 'bhauman'. JSpec
871
+ supports Rails out of the box, simply execute:
872
+
873
+ $ jspec init --rails
874
+
875
+ Then while still in the root directory of your Rails project, run the following
876
+ command which will bind to, and refresh your browsers automatically when any changes
877
+ are made to _./public/javascripts/*.js_ or _./jspec/*.js_
878
+
879
+ $ jspec
880
+
881
+ Or just like regular JSpec applications, run once:
882
+
883
+ $ jspec run
884
+
885
+ Or run via the terminal using Rhino:
886
+
887
+ $ jspec run --rhino
888
+
889
+ ## Supported Browsers
890
+
891
+ Browsers below are supported and can be found in _server/browsers.rb_, however
892
+ your _spec/server.rb_ file may support additional browsers.
893
+
894
+ - Safari
895
+ - WebKit
896
+ - Chrome
897
+ - Firefox
898
+ - Opera
899
+ - Internet Explorer
900
+
901
+ ## Known Issues
902
+
903
+ - The preprocessor is not (yet) capable of multiline conversions. For example the following is invalid
904
+
905
+ object.stub('getContentsOfURL').and_return(function(url){
906
+ return 'html'
907
+ })
908
+
909
+ In cases such as this, you may always revert to utilizing JSpec in a grammar-less form as follows:
910
+
911
+ stub(object, 'getContentsOfURL').and_return(function(url){
912
+ return 'html'
913
+ })
914
+
915
+ ## Additional JSpec Modules
916
+
917
+ - JSocka stubbing http://github.com/gisikw/jsocka/tree/master
918
+
919
+ ## More Information
920
+
921
+ - [Google Group](http://groups.google.com/group/jspec)
922
+ - IRC Channel [irc://irc.freenode.net#jspec](irc://irc.freenode.net#jspec)
923
+ - Featured in Devmag ["Advanced JavaScript"](http://www.dev-mag.com/2010/02/18/advanced-javascript/) ebook for 4$
924
+ - Featured article in JSMag [http://www.jsmag.com/main.issues.description/id=21/](http://www.jsmag.com/main.issues.description/id=21/)
925
+ - Syntax comparison with other frameworks [http://gist.github.com/92283](http://gist.github.com/92283)
926
+ - Get the TextMate bundle at [https://github.com/visionmedia/jspec.tmbundle/tree](https://github.com/visionmedia/jspec.tmbundle/tree)
927
+ - For more information consult the JSpec source code documentation or visit [http://visionmedia.github.com/jspec](http://visionmedia.github.com/jspec)
928
+ - jQuery + HTML fixture example [http://gist.github.com/147831](http://gist.github.com/147831)
929
+ - [http://twitter.com/tjholowaychuk](Twitter)
930
+ - [JSpec Vim Snippits](http://github.com/tobiassvn/snipmate-jspec/)
931
+
932
+ ## Contributors
933
+
934
+ Many ideas and bug reports were contributed by
935
+ the following developers, thankyou for making
936
+ JSpec more enjoyable, and bug free. If I have
937
+ missed you on this list please let me know
938
+ (aka the fellow who donated [jspec.info](http://jspec.info))
939
+
940
+ - Lawrence Pit
941
+ - [mpd@jesters-court.ne](mpd@jesters-court.ne)
942
+ - [Sarah Brown](brown.sarah.v@gmail.com)
943
+ - [kevin.gisi@gmail.com](kevin.gisi@gmail.com)
944
+ - [tony_t_tubbs@yahoo.com](tony_t_tubbs@yahoo.com)
945
+ - [enno84@gmx.net](enno84@gmx.net)
946
+ - fnando
947
+ - Tobias Svensson
948
+
949
+ ## License
950
+
951
+ (The MIT License)
952
+
953
+ Copyright (c) 2008 - 2010 TJ Holowaychuk <tj@vision-media.ca>
954
+
955
+ Permission is hereby granted, free of charge, to any person obtaining
956
+ a copy of this software and associated documentation files (the
957
+ 'Software'), to deal in the Software without restriction, including
958
+ without limitation the rights to use, copy, modify, merge, publish,
959
+ distribute, sublicense, and/or sell copies of the Software, and to
960
+ permit persons to whom the Software is furnished to do so, subject to
961
+ the following conditions:
962
+
963
+ The above copyright notice and this permission notice shall be
964
+ included in all copies or substantial portions of the Software.
965
+
966
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
967
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
968
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
969
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
970
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
971
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
972
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
973
+
974
+