guard-jasmine 0.9.14 → 1.0.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/README.md +89 -18
- data/bin/guard-jasmine-debug +1 -1
- data/lib/guard/jasmine/phantomjs/guard-jasmine.coffee +115 -0
- data/lib/guard/jasmine/phantomjs/lib/console.js +168 -0
- data/lib/guard/jasmine/phantomjs/lib/reporter.js +134 -0
- data/lib/guard/jasmine/phantomjs/src/console.coffee +149 -0
- data/lib/guard/jasmine/phantomjs/src/reporter.coffee +134 -0
- data/lib/guard/jasmine/phantomjs/test/console_spec.coffee +125 -0
- data/lib/guard/jasmine/phantomjs/test/reporter_spec.coffee +0 -0
- data/lib/guard/jasmine/runner.rb +5 -3
- data/lib/guard/jasmine/task.rb +1 -1
- data/lib/guard/jasmine/version.rb +1 -1
- metadata +53 -25
- data/lib/guard/jasmine/phantomjs/run-jasmine.coffee +0 -247
data/README.md
CHANGED
@@ -7,6 +7,36 @@ Tested on MRI Ruby 1.8.7, 1.9.2, 1.9.3, REE and the latest versions of JRuby and
|
|
7
7
|
If you have any questions please join us on our [Google group](http://groups.google.com/group/guard-dev) or on `#guard`
|
8
8
|
(irc.freenode.net).
|
9
9
|
|
10
|
+
## Contents
|
11
|
+
|
12
|
+
* [Highlights](#highlights)
|
13
|
+
* [Installation](#installation)
|
14
|
+
* [Guard and Guard::Jasmine](#guard-guard-jasmine)
|
15
|
+
* [PhantomJS](#phantomjs)
|
16
|
+
* [Rails 3.1 setup](#rails31)
|
17
|
+
* [How it works](#rails31-works)
|
18
|
+
* [Jasminerice](#rails31-jasminerice)
|
19
|
+
* [Rails 2 & Rails 3 setup](#rails23)
|
20
|
+
* [How it works](#rails23-works)
|
21
|
+
* [Jasmine Gem](#rails23-jasmine-gem)
|
22
|
+
* [Usage](#usage)
|
23
|
+
* [Guardfile](#guardfile)
|
24
|
+
* [Options](#options)
|
25
|
+
* [Server options](#server-options)
|
26
|
+
* [Use a custom server](#server-options-custom)
|
27
|
+
* [Spec runner options](#spec-runner-options)
|
28
|
+
* [Specdoc options](#specdoc-options)
|
29
|
+
* [Console logs](#console-logs)
|
30
|
+
* [System notifications options](#system-notifications-options)
|
31
|
+
* [Mapping file changes to the spec filter](#file-mapping)
|
32
|
+
* [Guard::Jasmine outside of Guard](#outside-guard)
|
33
|
+
* [Thor command line utility](#thor)
|
34
|
+
* [Rake task integration](#rake)
|
35
|
+
* [Travis CI integration](#travis-ci)
|
36
|
+
* [How to file an issue](#issues)
|
37
|
+
* [Development information](#development-information)
|
38
|
+
|
39
|
+
<a name="highlights" />
|
10
40
|
## Highlights
|
11
41
|
|
12
42
|
* Continuous testing based on file modifications by [Guard][], manifold configuration by writing rules with RegExp and
|
@@ -22,8 +52,10 @@ various web standards: DOM handling, CSS selector, JSON, Canvas, and SVG.
|
|
22
52
|
|
23
53
|
* Runs on Mac OS X, Linux and Windows.
|
24
54
|
|
25
|
-
|
55
|
+
<a name="installation" />
|
56
|
+
## Installation
|
26
57
|
|
58
|
+
<a name="guard-guard-jasmine" />
|
27
59
|
### Guard and Guard::Jasmine
|
28
60
|
|
29
61
|
The simplest way to install Guard is to use [Bundler](http://gembundler.com/).
|
@@ -43,6 +75,7 @@ Add the default Guard::Jasmine template to your `Guardfile` by running:
|
|
43
75
|
$ guard init jasmine
|
44
76
|
```
|
45
77
|
|
78
|
+
<a name="phantomjs" />
|
46
79
|
### PhantomJS
|
47
80
|
|
48
81
|
You need the PhantomJS browser installed on your system. You can download binaries for Mac OS X and Windows from
|
@@ -65,6 +98,7 @@ $ sudo apt-get install phantomjs
|
|
65
98
|
You can also build it from source for several other operating systems, please consult the
|
66
99
|
[PhantomJS build instructions][].
|
67
100
|
|
101
|
+
<a name="rails31" />
|
68
102
|
## Rails 3.1 setup
|
69
103
|
|
70
104
|
With Rails 3.1 you can write your Jasmine specs in addition to JavaScript with CoffeeScript, fully integrated into the
|
@@ -73,6 +107,7 @@ to fake the server response. Check out the excellent [Sinon.JS][] documentation
|
|
73
107
|
|
74
108
|
Guard::Jasmine will start a Rails Rack server to run your specs.
|
75
109
|
|
110
|
+
<a name="rails31-works" />
|
76
111
|
### How it works
|
77
112
|
|
78
113
|

|
@@ -88,6 +123,7 @@ Guard::Jasmine will start a Rails Rack server to run your specs.
|
|
88
123
|
9. The PhantomJS script collects the Jasmine runner results and returns a JSON report.
|
89
124
|
10. Guard::Jasmine reports the results to the console and system notifications.
|
90
125
|
|
126
|
+
<a name="rails31-jasminerice" />
|
91
127
|
### Jasminerice
|
92
128
|
|
93
129
|
Please read the detailed installation and configuration instructions at [Jasminerice][].
|
@@ -120,6 +156,7 @@ It also creates an empty `spec/javascripts/spec.css` file as it is always reques
|
|
120
156
|
|
121
157
|
Now you can access `/jasmine` url when you start rails server normally.
|
122
158
|
|
159
|
+
<a name="rails23" />
|
123
160
|
## Rails 2 & Rails 3 setup
|
124
161
|
|
125
162
|
With Rails 2 or Rails 3 you can use [the Jasmine Gem][] to configure your Jasmine specs and server the Jasmine
|
@@ -128,6 +165,7 @@ response. Check out the excellent [Sinon.JS][] documentation to learn more about
|
|
128
165
|
|
129
166
|
Guard::Jasmine will start a Jasmine Gem Rack server to run your specs.
|
130
167
|
|
168
|
+
<a name="rails23-works" />
|
131
169
|
### How it works
|
132
170
|
|
133
171
|

|
@@ -141,6 +179,7 @@ Guard::Jasmine will start a Jasmine Gem Rack server to run your specs.
|
|
141
179
|
7. The PhantomJS script collects the Jasmine runner results and returns a JSON report.
|
142
180
|
8. Guard::Jasmine reports the results to the console and system notifications.
|
143
181
|
|
182
|
+
<a name="rails23-jasmine-gem" />
|
144
183
|
### Jasmine Gem
|
145
184
|
|
146
185
|
Please read the detailed installation and configuration instructions at [the Jasmine Gem][].
|
@@ -179,10 +218,12 @@ guard 'coffeescript', :input => 'app/coffeescripts', :output => 'public/javascr
|
|
179
218
|
guard 'coffeescript', :input => 'spec/coffeescripts', :output => 'spec/javascripts'
|
180
219
|
```
|
181
220
|
|
221
|
+
<a name="usage" />
|
182
222
|
## Usage
|
183
223
|
|
184
224
|
Please read the [Guard usage documentation](https://github.com/guard/guard#readme).
|
185
225
|
|
226
|
+
<a name="guardfile" />
|
186
227
|
## Guardfile
|
187
228
|
|
188
229
|
Guard::Jasmine can be adapted to all kind of projects. Please read the
|
@@ -196,6 +237,7 @@ guard 'jasmine' do
|
|
196
237
|
end
|
197
238
|
```
|
198
239
|
|
240
|
+
<a name="options" />
|
199
241
|
## Options
|
200
242
|
|
201
243
|
There are many options that can customize Guard::Jasmine to your needs. Options are simply supplied as hash when
|
@@ -207,6 +249,7 @@ guard 'jasmine', :all_on_start => false, :specdoc => :always do
|
|
207
249
|
end
|
208
250
|
```
|
209
251
|
|
252
|
+
<a name="server-options" />
|
210
253
|
### Server options
|
211
254
|
|
212
255
|
The server options configures the server environment that is needed to run Guard::Jasmine:
|
@@ -244,6 +287,7 @@ The reason why the Server environment is set to `development` by default is that
|
|
244
287
|
the asset pipeline doesn't concatenate the JavaScripts and you'll see the line number in the real file,
|
245
288
|
instead of a ridiculous high line number in a single, very large JavaScript.
|
246
289
|
|
290
|
+
<a name="server-options-custom" />
|
247
291
|
#### Use a custom server
|
248
292
|
|
249
293
|
If you supply an unknown server name as the `:server` option, then Guard::Jasmine will execute
|
@@ -252,6 +296,7 @@ a `rake` task with the given server name as task in a child process. For example
|
|
252
296
|
you have to make sure the server starts on the port that you can get from the `JASMINE_PORT`
|
253
297
|
environment variable.
|
254
298
|
|
299
|
+
<a name="spec-runner-options" />
|
255
300
|
### Spec runner options
|
256
301
|
|
257
302
|
The spec runner options configures the behavior driven development (or BDD) cycle:
|
@@ -285,6 +330,7 @@ In general you want to leave the `:clean` flag on, which ensures that only Jasmi
|
|
285
330
|
`_spec.coffee` and `_spec.js.coffee` inside your project are passed to the runner. If you have a custom project
|
286
331
|
structure or spec naming convention, you can set `:clean` to false to skip that file filter.
|
287
332
|
|
333
|
+
<a name="specdoc-options" />
|
288
334
|
### Specdoc options
|
289
335
|
|
290
336
|
Guard::Jasmine can generate an RSpec like specdoc in the console after running the specs and you can set when it will
|
@@ -310,26 +356,35 @@ set to `:never`, there is no output at all, instead just a summary of the spec r
|
|
310
356
|
|
311
357
|
When `:focus` is enabled, only the failing specs are shown in the specdoc when at least one spec is failing.
|
312
358
|
|
313
|
-
|
314
|
-
|
315
|
-
`error` are missing. Please vote on [Issue 232](http://code.google.com/p/phantomjs/issues/detail?id=232) if you like
|
316
|
-
to see support for more console methods coming to PhantomJS.
|
359
|
+
<a name="console-logs" />
|
360
|
+
#### Console logs
|
317
361
|
|
318
|
-
|
362
|
+
The `:console` options adds captured console logs from the spec runner and adds them to the specdoc. Guard:Jasmine
|
363
|
+
contains its own minimalistic console implementation. The following console methods are supported:
|
319
364
|
|
320
|
-
|
321
|
-
console.
|
322
|
-
|
365
|
+
* `console.log`
|
366
|
+
* `console.info`
|
367
|
+
* `console.warn`
|
368
|
+
* `console.error`
|
369
|
+
* `console.debug`
|
323
370
|
|
324
|
-
|
371
|
+
The difference for each of this log methods is simply a prefix that is added to the log statement. The log also
|
372
|
+
supports the common format placeholders:
|
325
373
|
|
326
|
-
|
327
|
-
|
328
|
-
|
374
|
+
* `%s`
|
375
|
+
* `%i`, `%d`
|
376
|
+
* `%f`
|
377
|
+
* `%o`
|
378
|
+
|
379
|
+
You can further customize the log output by implement on of these methods:
|
380
|
+
|
381
|
+
* `toString()` - must return a string that describes the object
|
382
|
+
* `toJSON()` - must return an object that is used instead of the actual object.
|
329
383
|
|
330
|
-
|
331
|
-
|
384
|
+
In addition the console can log jQuery collections and outputs the HTML representation of the element by using the
|
385
|
+
jQuery `html()` method.
|
332
386
|
|
387
|
+
<a name="system-notifications-options" />
|
333
388
|
### System notifications options
|
334
389
|
|
335
390
|
These options affects what system notifications (growl, libnotify or notifu) are shown after a spec run:
|
@@ -345,6 +400,7 @@ These options affects what system notifications (growl, libnotify or notifu) are
|
|
345
400
|
# default: 3
|
346
401
|
```
|
347
402
|
|
403
|
+
<a name="file-mapping" />
|
348
404
|
## Mapping file changes to the spec filter
|
349
405
|
|
350
406
|
Jasmine doesn't know anything about your test files, it only knows the name of your specs that you specify in the
|
@@ -359,8 +415,10 @@ So if you want to have a precise spec detection, you should:
|
|
359
415
|
To get a feeling how your naming strategy works, play with the web based Jasmine runner and modify the `spec` query
|
360
416
|
parameter.
|
361
417
|
|
418
|
+
<a name="outside-guard" />
|
362
419
|
## Guard::Jasmine outside of Guard
|
363
420
|
|
421
|
+
<a name="thor" />
|
364
422
|
### Thor command line utility
|
365
423
|
|
366
424
|
Guard::Jasmine includes a little command line utility to run your specs once and output the specdoc to the console.
|
@@ -405,6 +463,7 @@ By default all specs are run, but you can supply multiple paths to your specs to
|
|
405
463
|
$ guard-jasmine spec/javascripts/a_spec.js.coffee spec/javascripts/another_spec.js.coffee
|
406
464
|
```
|
407
465
|
|
466
|
+
<a name="rake" />
|
408
467
|
### Rake task integration
|
409
468
|
|
410
469
|
Guard::Jasmine provides a Rake task wrapper around the Thor command line utility. Simply create a JasmineTask within
|
@@ -427,6 +486,7 @@ end
|
|
427
486
|
Guard::JasmineTask.new(:jasmine_no_server, '-s none')
|
428
487
|
```
|
429
488
|
|
489
|
+
<a name="travis-ci" />
|
430
490
|
### Travis CI integration
|
431
491
|
|
432
492
|
With the given `guard-jasmine` script you're able to configure [Travis CI](http://travis-ci.org/) to run Guard::Jasmine.
|
@@ -466,7 +526,8 @@ I recommend to check out these other brilliant Jasmine runners:
|
|
466
526
|
* [Jezebel][] a Node.js REPL and continuous test runner for [Jessie][], a Node runner for Jasmine, but has no full
|
467
527
|
featured browser environment.
|
468
528
|
|
469
|
-
|
529
|
+
<a name="issues" />
|
530
|
+
## How to file an issue
|
470
531
|
|
471
532
|
You can report issues and feature requests to [GitHub Issues](https://github.com/netzpirat/guard-jasmine/issues). Try to figure out
|
472
533
|
where the issue belongs to: Is it an issue with Guard itself or with Guard::Jasmine? Please don't
|
@@ -475,12 +536,14 @@ ask question in the issue tracker, instead join us in our [Google group](http://
|
|
475
536
|
|
476
537
|
When you file an issue, please try to follow to these simple rules if applicable:
|
477
538
|
|
539
|
+
* Make sure you have study the README carefully.
|
478
540
|
* Make sure you run Guard with `bundle exec` first.
|
479
541
|
* Add debug information to the issue by running Guard with the `--verbose` option.
|
480
542
|
* Add your `Guardfile` and `Gemfile` to the issue.
|
481
543
|
* Make sure that the issue is reproducible with your description.
|
482
544
|
|
483
|
-
|
545
|
+
<a name="development-information" />
|
546
|
+
## Development information
|
484
547
|
|
485
548
|
- Documentation hosted at [RubyDoc](http://rubydoc.info/github/guard/guard-jasmine/master/frames).
|
486
549
|
- Source hosted at [GitHub](https://github.com/netzpirat/guard-jasmine).
|
@@ -513,6 +576,14 @@ The only argument that the script takes is the URL to the Jasmine runner, which
|
|
513
576
|
```bash
|
514
577
|
$ guard-jasmine-debug http://127.0.0.1:3000/Jasmine?spec=YourSpec
|
515
578
|
```
|
579
|
+
|
580
|
+
## Author
|
581
|
+
|
582
|
+
Developed by Michael Kessler, sponsored by [mksoft.ch](https://mksoft.ch).
|
583
|
+
|
584
|
+
If you like Guard::Jasmine, you can watch the repository at [GitHub](https://github.com/netzpirat/guard-jasmine) and
|
585
|
+
follow [@netzpirat](https://twitter.com/#!/netzpirat) on Twitter for project updates.
|
586
|
+
|
516
587
|
## Contributors
|
517
588
|
|
518
589
|
See the the GitHub list of [contributors](https://github.com/netzpirat/haml_coffee_assets/contributors).
|
@@ -574,7 +645,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
574
645
|
[guard-jasmine-headless-webkit]: https://github.com/johnbintz/guard-jasmine-headless-webkit
|
575
646
|
[jasmine-headless-webkit]: https://github.com/johnbintz/jasmine-headless-webkit/
|
576
647
|
[Evergreen]: https://github.com/jnicklas/evergreen
|
577
|
-
[PhantomJS script]: https://github.com/netzpirat/guard-jasmine/blob/master/lib/guard/jasmine/phantomjs/
|
648
|
+
[PhantomJS script]: https://github.com/netzpirat/guard-jasmine/blob/master/lib/guard/jasmine/phantomjs/guard-jasmine.coffee
|
578
649
|
[Guard::CoffeeScript]: https://github.com/guard/guard-coffeescript
|
579
650
|
[Sinon.JS]: http://sinonjs.org
|
580
651
|
[guard-jasmine-node]: https://github.com/guard/guard-jasmine-node
|
data/bin/guard-jasmine-debug
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
script = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'guard', 'jasmine', 'phantomjs', '
|
2
|
+
script = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'guard', 'jasmine', 'phantomjs', 'guard-jasmine.coffee'))
|
3
3
|
puts `phantomjs #{ script } #{ ARGV[0] } #{ ARGV[1] }`
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# This file is the script that runs within PhantomJS, requests the Jasmine specs
|
2
|
+
# and waits until they are ready.
|
3
|
+
|
4
|
+
# Set default values
|
5
|
+
url = phantom.args[0] || 'http://127.0.0.1:3000/jasmine'
|
6
|
+
timeout = parseInt(phantom.args[1] || 5000)
|
7
|
+
|
8
|
+
# Create the web page.
|
9
|
+
#
|
10
|
+
page = require('webpage').create()
|
11
|
+
|
12
|
+
# Used to collect log messages for later assignment to the spec
|
13
|
+
#
|
14
|
+
currentSpecId = -1
|
15
|
+
logs = {}
|
16
|
+
|
17
|
+
# Add logs to the given suite
|
18
|
+
#
|
19
|
+
# @param suite [Object} the suite result
|
20
|
+
#
|
21
|
+
page.addLogs = (suite) ->
|
22
|
+
for s in suite.suites
|
23
|
+
arguments.callee(s) if s
|
24
|
+
|
25
|
+
for spec in suite.specs
|
26
|
+
id = Number(spec['id'])
|
27
|
+
spec['logs'] = logs[id] if logs[id] && logs[id].length isnt 0
|
28
|
+
delete spec['id']
|
29
|
+
|
30
|
+
delete suite['id']
|
31
|
+
delete suite['parent']
|
32
|
+
|
33
|
+
# Capture console.log output to add it to
|
34
|
+
# the result when specs have finished.
|
35
|
+
#
|
36
|
+
page.onConsoleMessage = (msg, line, source) ->
|
37
|
+
if /^RUNNER_RESULT: ([\s\S]*)$/.test(msg)
|
38
|
+
result = JSON.parse(RegExp.$1)
|
39
|
+
|
40
|
+
for suite in result.suites
|
41
|
+
page.addLogs(suite)
|
42
|
+
|
43
|
+
console.log JSON.stringify(result, undefined, 2)
|
44
|
+
page.evaluate -> window.resultReceived = true
|
45
|
+
|
46
|
+
else if /^SPEC_START: (\d+)$/.test(msg)
|
47
|
+
currentSpecId = Number(RegExp.$1)
|
48
|
+
logs[currentSpecId] = []
|
49
|
+
|
50
|
+
else
|
51
|
+
logs[currentSpecId].push(msg) if currentSpecId isnt -1
|
52
|
+
|
53
|
+
# Initialize the page before the JavaScript is run.
|
54
|
+
#
|
55
|
+
page.onInitialized = ->
|
56
|
+
page.injectJs 'lib/console.js'
|
57
|
+
page.injectJs 'lib/reporter.js'
|
58
|
+
|
59
|
+
page.evaluate ->
|
60
|
+
# Attach the console reporter when the document is ready.
|
61
|
+
window.onload = ->
|
62
|
+
window.resultReceived = false
|
63
|
+
jasmine.getEnv().addReporter(new ConsoleReporter())
|
64
|
+
|
65
|
+
# Open web page and run the Jasmine test runner
|
66
|
+
#
|
67
|
+
page.open url, (status) ->
|
68
|
+
# Avoid that a failed iframe load breaks the runner, see https://github.com/netzpirat/guard-jasmine/pull/19
|
69
|
+
page.onLoadFinished = ->
|
70
|
+
|
71
|
+
if status isnt 'success'
|
72
|
+
console.log JSON.stringify({ error: "Unable to access Jasmine specs at #{ url }" })
|
73
|
+
phantom.exit()
|
74
|
+
else
|
75
|
+
done = -> phantom.exit()
|
76
|
+
waitFor specsReady, done, timeout
|
77
|
+
|
78
|
+
# Test if the specs have finished.
|
79
|
+
#
|
80
|
+
specsReady = ->
|
81
|
+
page.evaluate -> window.resultReceived
|
82
|
+
|
83
|
+
# Wait until the test condition is true or a timeout occurs.
|
84
|
+
#
|
85
|
+
# @param [Function] test the test that returns true if condition is met
|
86
|
+
# @param [Function] ready the action when the condition is fulfilled
|
87
|
+
# @param [Number] timeout the max amount of time to wait in milliseconds
|
88
|
+
#
|
89
|
+
waitFor = (test, ready, timeout = 5000) ->
|
90
|
+
start = new Date().getTime()
|
91
|
+
condition = false
|
92
|
+
|
93
|
+
wait = ->
|
94
|
+
if (new Date().getTime() - start < timeout) and not condition
|
95
|
+
condition = test()
|
96
|
+
else
|
97
|
+
if not condition
|
98
|
+
text = page.evaluate -> document.getElementsByTagName('body')[0]?.innerText
|
99
|
+
|
100
|
+
if text
|
101
|
+
error = """
|
102
|
+
Timeout waiting for the Jasmine test results!
|
103
|
+
|
104
|
+
#{ text }
|
105
|
+
"""
|
106
|
+
console.log JSON.stringify({ error: error })
|
107
|
+
else
|
108
|
+
console.log JSON.stringify({ error: 'Timeout waiting for the Jasmine test results!' })
|
109
|
+
|
110
|
+
phantom.exit(1)
|
111
|
+
else
|
112
|
+
ready()
|
113
|
+
clearInterval interval
|
114
|
+
|
115
|
+
interval = setInterval wait, 250
|
@@ -0,0 +1,168 @@
|
|
1
|
+
(function() {
|
2
|
+
var Console,
|
3
|
+
__slice = Array.prototype.slice;
|
4
|
+
|
5
|
+
Console = (function() {
|
6
|
+
|
7
|
+
function Console(console) {
|
8
|
+
var log;
|
9
|
+
log = console.log;
|
10
|
+
console.log = function() {
|
11
|
+
var args;
|
12
|
+
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
13
|
+
return log.call(console, Console.format.apply(Console, args));
|
14
|
+
};
|
15
|
+
console.info = function() {
|
16
|
+
var args;
|
17
|
+
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
18
|
+
return log.call(console, "INFO: " + (Console.format.apply(Console, args)));
|
19
|
+
};
|
20
|
+
console.warn = function() {
|
21
|
+
var args;
|
22
|
+
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
23
|
+
return log.call(console, "WARN: " + (Console.format.apply(Console, args)));
|
24
|
+
};
|
25
|
+
console.error = function() {
|
26
|
+
var args;
|
27
|
+
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
28
|
+
return log.call(console, "ERROR: " + (Console.format.apply(Console, args)));
|
29
|
+
};
|
30
|
+
console.debug = function() {
|
31
|
+
var args;
|
32
|
+
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
33
|
+
return log.call(console, "DEBUG: " + (Console.format.apply(Console, args)));
|
34
|
+
};
|
35
|
+
}
|
36
|
+
|
37
|
+
Console.MAX_OBJECT_DEPTH = 2;
|
38
|
+
|
39
|
+
Console.format = function() {
|
40
|
+
var arg, args, result, _i, _len,
|
41
|
+
_this = this;
|
42
|
+
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
43
|
+
result = [];
|
44
|
+
if (typeof args[0] === 'string' && /%[sdifo]/gi.test(args[0])) {
|
45
|
+
arg = args.shift();
|
46
|
+
result.push(arg.replace(/%[sdifo]/gi, function(str) {
|
47
|
+
return Console.inspect(args.shift(), str);
|
48
|
+
}));
|
49
|
+
}
|
50
|
+
for (_i = 0, _len = args.length; _i < _len; _i++) {
|
51
|
+
arg = args[_i];
|
52
|
+
result.push(Console.inspect(arg));
|
53
|
+
}
|
54
|
+
return result.join(' ');
|
55
|
+
};
|
56
|
+
|
57
|
+
Console.inspect = function(object, type) {
|
58
|
+
var match, result;
|
59
|
+
switch (type) {
|
60
|
+
case '%s':
|
61
|
+
result = String(object);
|
62
|
+
if (match = /'(.*)'/.exec(result)) result = match[1];
|
63
|
+
break;
|
64
|
+
case '%d':
|
65
|
+
case '%i':
|
66
|
+
result = parseInt(object);
|
67
|
+
break;
|
68
|
+
case '%f':
|
69
|
+
result = parseFloat(object);
|
70
|
+
break;
|
71
|
+
default:
|
72
|
+
type = Object.prototype.toString.call(object).slice(8, -1);
|
73
|
+
if (type === 'Object' && object.toJSON) {
|
74
|
+
result = Console.pp(object.toJSON());
|
75
|
+
} else if (type === 'Object' && object.toString && object.toString() !== '[object Object]') {
|
76
|
+
result = Console.pp(object.toString());
|
77
|
+
if (match = /'(.*)'/.exec(result)) result = match[1];
|
78
|
+
} else if (type === 'String') {
|
79
|
+
result = String(object);
|
80
|
+
if (match = /'(.*)'/.exec(result)) result = match[1];
|
81
|
+
} else {
|
82
|
+
result = Console.pp(object);
|
83
|
+
}
|
84
|
+
}
|
85
|
+
return result;
|
86
|
+
};
|
87
|
+
|
88
|
+
Console.pp = function(object, depth) {
|
89
|
+
var key, result, type, value, _i, _len;
|
90
|
+
if (depth == null) depth = 0;
|
91
|
+
type = Object.prototype.toString.call(object).slice(8, -1);
|
92
|
+
result = '';
|
93
|
+
switch (type) {
|
94
|
+
case 'Undefined':
|
95
|
+
case 'Null':
|
96
|
+
result += type.toLowerCase();
|
97
|
+
break;
|
98
|
+
case 'Boolean':
|
99
|
+
case 'Number':
|
100
|
+
case 'Date':
|
101
|
+
result += object.toString();
|
102
|
+
break;
|
103
|
+
case 'String':
|
104
|
+
result += "'" + (object.toString()) + "'";
|
105
|
+
break;
|
106
|
+
case 'Array':
|
107
|
+
if (object.length > 0) {
|
108
|
+
result += '[';
|
109
|
+
for (_i = 0, _len = object.length; _i < _len; _i++) {
|
110
|
+
value = object[_i];
|
111
|
+
if (depth < Console.MAX_OBJECT_DEPTH || Object.prototype.toString.call(value).slice(8, -1) !== 'Object') {
|
112
|
+
result += "" + (Console.pp(value, depth + 1)) + ", ";
|
113
|
+
} else {
|
114
|
+
result += "[Object], ";
|
115
|
+
}
|
116
|
+
}
|
117
|
+
result = result.slice(0, -2);
|
118
|
+
result += ']';
|
119
|
+
} else {
|
120
|
+
result += '[]';
|
121
|
+
}
|
122
|
+
break;
|
123
|
+
case 'Object':
|
124
|
+
if (object.jquery) {
|
125
|
+
if (object.length > 0) {
|
126
|
+
result += '[';
|
127
|
+
object.each(function() {
|
128
|
+
return result += jQuery(this).html();
|
129
|
+
});
|
130
|
+
result += ']';
|
131
|
+
} else {
|
132
|
+
result += '[]';
|
133
|
+
}
|
134
|
+
} else if (Object.keys(object).length > 0) {
|
135
|
+
result += '{ ';
|
136
|
+
for (key in object) {
|
137
|
+
value = object[key];
|
138
|
+
if (depth < Console.MAX_OBJECT_DEPTH || Object.prototype.toString.call(value).slice(8, -1) !== 'Object') {
|
139
|
+
if (object.hasOwnProperty(key)) {
|
140
|
+
result += "" + key + ": " + (Console.pp(value, depth + 1)) + ", ";
|
141
|
+
}
|
142
|
+
} else {
|
143
|
+
result += "" + key + ": [Object], ";
|
144
|
+
}
|
145
|
+
}
|
146
|
+
result = result.slice(0, -2);
|
147
|
+
result += ' }';
|
148
|
+
} else {
|
149
|
+
result += '{}';
|
150
|
+
}
|
151
|
+
break;
|
152
|
+
case 'Function':
|
153
|
+
result += '[Function]';
|
154
|
+
}
|
155
|
+
return result;
|
156
|
+
};
|
157
|
+
|
158
|
+
return Console;
|
159
|
+
|
160
|
+
})();
|
161
|
+
|
162
|
+
if (typeof module !== 'undefined' && module.exports) {
|
163
|
+
if (module) module.exports = Console;
|
164
|
+
} else {
|
165
|
+
if (window) new Console(window.console);
|
166
|
+
}
|
167
|
+
|
168
|
+
}).call(this);
|