guard-jasmine 0.9.14 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
![Guard Jasmine](https://github.com/netzpirat/guard-jasmine/raw/master/resources/guard-jasmine-rails31.jpg)
|
@@ -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
|
![Guard Jasmine](https://github.com/netzpirat/guard-jasmine/raw/master/resources/guard-jasmine-rails23.jpg)
|
@@ -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);
|