Compare commits
159 Commits
0.11.1-rel
...
v1.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41f496001f | ||
|
|
6b5956724b | ||
|
|
ec24992250 | ||
|
|
83f232237d | ||
|
|
98d32bb4a4 | ||
|
|
c4f27ae377 | ||
|
|
a075c75bce | ||
|
|
a617b59e6a | ||
|
|
917b37481e | ||
|
|
67bbc98faa | ||
|
|
620f7b6e4c | ||
|
|
b722f416c7 | ||
|
|
634a7dc402 | ||
|
|
a4522e4dce | ||
|
|
e113c338d0 | ||
|
|
b81f690a25 | ||
|
|
c06e189699 | ||
|
|
67b6cfb828 | ||
|
|
57e622fb2a | ||
|
|
c0664dd6aa | ||
|
|
b640ce6fc0 | ||
|
|
e9af7834f5 | ||
|
|
0d43ae9c38 | ||
|
|
30431a3958 | ||
|
|
3775919c92 | ||
|
|
a692ff8c95 | ||
|
|
e4e9b51544 | ||
|
|
0b97951766 | ||
|
|
75dd391d57 | ||
|
|
ae24e00c0f | ||
|
|
6b2e45eab5 | ||
|
|
e59171935f | ||
|
|
2ba0aa371c | ||
|
|
c2ed71717f | ||
|
|
09e8822107 | ||
|
|
15763c2eb0 | ||
|
|
3f264cde34 | ||
|
|
f83cb7f766 | ||
|
|
9d5470ff55 | ||
|
|
86b095e5a4 | ||
|
|
4c6dafa3f5 | ||
|
|
3f4adf7715 | ||
|
|
af7f1818b0 | ||
|
|
12f56787b0 | ||
|
|
e88d88e427 | ||
|
|
ba10d178b2 | ||
|
|
da297d0f56 | ||
|
|
7ead5388c2 | ||
|
|
a445a62e7c | ||
|
|
1d65d56a92 | ||
|
|
d875d1d997 | ||
|
|
1fae8f0a31 | ||
|
|
c1f8151bcb | ||
|
|
bd8a3baed1 | ||
|
|
118324b451 | ||
|
|
c30f7d1aa7 | ||
|
|
de7be4b316 | ||
|
|
b02aa9840a | ||
|
|
61de2268fe | ||
|
|
dd32048383 | ||
|
|
32e736aa47 | ||
|
|
38e9af8f68 | ||
|
|
e826fbb170 | ||
|
|
0c77662c5b | ||
|
|
75fb19bc49 | ||
|
|
6ec825f62d | ||
|
|
fc994108db | ||
|
|
70aed2d900 | ||
|
|
ccfa17499f | ||
|
|
ab087ef5f8 | ||
|
|
0ef6582f73 | ||
|
|
a1ba43c864 | ||
|
|
88ee377662 | ||
|
|
f5afe18a6b | ||
|
|
2731716ccb | ||
|
|
4e5083d570 | ||
|
|
b9cbd3c5a0 | ||
|
|
e42026ee84 | ||
|
|
a1f58f8be4 | ||
|
|
ac00d765d2 | ||
|
|
b1dceeacd4 | ||
|
|
5018f0d1c2 | ||
|
|
9704550b33 | ||
|
|
882c287191 | ||
|
|
7d2b900b48 | ||
|
|
f701fdc132 | ||
|
|
eb49fab652 | ||
|
|
e8c8a0bdfd | ||
|
|
e6a080039f | ||
|
|
c485c33a3c | ||
|
|
8fbf3ba859 | ||
|
|
dccafe33b0 | ||
|
|
c1d2718bea | ||
|
|
945a9ba638 | ||
|
|
528b5abeda | ||
|
|
d7cced2e7c | ||
|
|
3be0610572 | ||
|
|
5e90115eaf | ||
|
|
148317eb90 | ||
|
|
45b4e1316c | ||
|
|
aee4c5926c | ||
|
|
f41af6c2d0 | ||
|
|
9f90c4eca5 | ||
|
|
545752ae20 | ||
|
|
c04f1b1fa8 | ||
|
|
fa9741dbda | ||
|
|
560cb2edcb | ||
|
|
9a12b32a3a | ||
|
|
bd15ed6a45 | ||
|
|
fa74051071 | ||
|
|
127fe049d9 | ||
|
|
550e378dc0 | ||
|
|
377703745f | ||
|
|
8ecfd26325 | ||
|
|
2d10cc1404 | ||
|
|
63df354e78 | ||
|
|
c8d9fc562f | ||
|
|
1530ad25f9 | ||
|
|
b2557e4ebe | ||
|
|
85c265e7c5 | ||
|
|
cc36a1808b | ||
|
|
685344342a | ||
|
|
a4eab045a0 | ||
|
|
cd0346b449 | ||
|
|
f134c6e386 | ||
|
|
75238bd3b1 | ||
|
|
b8b4457b6b | ||
|
|
b33b2d2cf1 | ||
|
|
3ec736f64c | ||
|
|
e7a57606a2 | ||
|
|
55149310c3 | ||
|
|
254ebb8a03 | ||
|
|
762f88e3c8 | ||
|
|
b3715075e3 | ||
|
|
9af81b627b | ||
|
|
5d44da0238 | ||
|
|
93952890c3 | ||
|
|
5182e00c66 | ||
|
|
676af93bea | ||
|
|
4d7b839473 | ||
|
|
89afebd86b | ||
|
|
31020bb51d | ||
|
|
17e9a038a2 | ||
|
|
1e01000c17 | ||
|
|
6562b5a3b4 | ||
|
|
15955df258 | ||
|
|
81bf4784cd | ||
|
|
14486f5912 | ||
|
|
9842c8ff81 | ||
|
|
feb4618c31 | ||
|
|
c6acfb3982 | ||
|
|
ba5bd3f866 | ||
|
|
0331209413 | ||
|
|
57491a0088 | ||
|
|
e6b6d9ca95 | ||
|
|
bf44d4b0db | ||
|
|
3da73bd519 | ||
|
|
61c0fe781c | ||
|
|
766f3546bf |
9
.gitignore
vendored
@@ -1,3 +1,12 @@
|
||||
.idea/
|
||||
.svn/
|
||||
.DS_Store
|
||||
site/
|
||||
.bundle/
|
||||
.pairs
|
||||
.rvmrc
|
||||
*.gem
|
||||
.bundle
|
||||
tags
|
||||
Gemfile.lock
|
||||
pkg/*
|
||||
|
||||
44
Contribute.markdown
Normal file
@@ -0,0 +1,44 @@
|
||||
# Developing for Jasmine Core
|
||||
|
||||
## How to Contribute
|
||||
|
||||
We welcome your contributions - Thanks for helping make Jasmine a better project for everyone. Please review the backlog and discussion lists (the main group - [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js) and the developer's list - [http://groups.google.com/group/jasmine-js-dev](http://groups.google.com/group/jasmine-js-dev)) before starting work - what you're looking for may already have been done. If it hasn't, the community can help make your contribution better.
|
||||
|
||||
## How to write new Jasmine code
|
||||
|
||||
Or, How to make a successful pull request
|
||||
|
||||
* _Do not change the public interface_. Lots of projects depend on Jasmine and if you aren't careful you'll break them
|
||||
* _Be environment agnostic_ - server-side developers are just as important as browser developers
|
||||
* _Be browser agnostic_ - if you must rely on browser-specific functionality, please write it in a way that degrades gracefully
|
||||
* _Write specs_ - Jasmine's a testing framework; don't add functionality without test-driving it
|
||||
* _Ensure the *entire* test suite is green_ in all the big browsers, Node, and JSHint - your contribution shouldn't break Jasmine for other users
|
||||
|
||||
Follow these tips and your pull request, patch, or suggestion is much more likely to be integrated.
|
||||
|
||||
## Environment
|
||||
|
||||
Ruby, RubyGems and Rake are used in order to script the various file interactions. You will need to run on a system that supports Ruby in order to run Jasmine's specs.
|
||||
|
||||
Node.js is used to run most of the specs (the HTML-independent code) and should be present. Additionally, the JS Hint project scrubs the source code as part of the spec process.
|
||||
|
||||
## Development
|
||||
|
||||
All source code belongs in `src/`. The `core/` directory contains the bulk of Jasmine's functionality. This code should remain browser- and environment-agnostic. If your feature or fix cannot be, as mentioned above, please degrade gracefully. Any code that should only be in a non-browser environment should live in `src/console/`. Any code that depends on a browser (specifically, it expects `window` to be the global or `document` is present) should live in `src/html/`.
|
||||
|
||||
Please respect the code patterns as possible. For example, using `jasmine.getGlobal()` to get the global object so as to remain environment agnostic.
|
||||
|
||||
## Running Specs
|
||||
|
||||
As in all good projects, the `spec/` directory mirrors `src/` and follows the same rules. The browser runner will include and attempt to run all specs. The node runner will exclude any html-dependent specs (those in `spec/html/`).
|
||||
|
||||
You will notice that all specs are run against the built `jasmine.js` instead of the component source files. This is intentional as a way to ensure that the concatenation code is working correctly.
|
||||
|
||||
Please ensure all specs are green before committing.
|
||||
|
||||
There are rake tasks to help with getting green:
|
||||
* `rake spec` outputs the expected number of specs that should be run and attempts to run in browser and Node
|
||||
* `rake spec:browser` opens `spec/runner.html` in the default browser on MacOS. Please run this in at least Firefox and Chrome before committing
|
||||
* `rake spec:node` runs all the Jasmine specs in Node.js - it will complain if Node is not installed
|
||||
* `rake hint` runs all the files through JSHint and will complain about potential viable issues with your code. Fix them.
|
||||
|
||||
4
Gemfile
Normal file
@@ -0,0 +1,4 @@
|
||||
source :rubygems
|
||||
gem "term-ansicolor", :require => "term/ansicolor"
|
||||
gem "rake"
|
||||
gemspec
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2008 Pivotal Labs
|
||||
Copyright (c) 2008-2011 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
479
README.markdown
@@ -1,482 +1,31 @@
|
||||
[Jasmine](http://pivotal.github.com/jasmine)
|
||||
<a name="README">[Jasmine](http://pivotal.github.com/jasmine/)</a>
|
||||
=======
|
||||
**A JavaScript Testing Framework**
|
||||
|
||||
Quick Start
|
||||
----------
|
||||
Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on browsers, DOM, or any JavaScript framework. Thus it's suited for websites, [Node.js](http://nodejs.org) projects, or anywhere that JavaScript can run.
|
||||
|
||||
1. Get the latest release from the [downloads page](http://github.com/pivotal/jasmine/downloads).
|
||||
2. Open `SpecRunner.html` in your favorite browser.
|
||||
Documentation & guides live here: [http://pivotal.github.com/jasmine/](http://pivotal.github.com/jasmine/)
|
||||
|
||||
For running within a Ruby environment, including automated execution with Selenium, please use
|
||||
the [jasmine gem](http://github.com/pivotal/jasmine-gem).
|
||||
## What's Here?
|
||||
|
||||
### Which Release Should I Use?
|
||||
*
|
||||
|
||||
Please use the latest version unless you have a good reason not to. Some of this documentation may not be applicable to older versions. Please see [[Release Notes]](http://wiki.github.com/pivotal/jasmine/release-notes) for change information.
|
||||
|
||||
Why Another JavaScript TDD/BDD Framework?
|
||||
-----------
|
||||
|
||||
There are some great JavaScript testing frameworks out there already, so why did we write another?
|
||||
|
||||
None of the existing frameworks quite worked the way we wanted. Many only work from within a browser. Most don't support testing asynchronous code like event callbacks. Some have syntax that's hard for JS developers or IDEs to understand.
|
||||
|
||||
So we decided to start from scratch.
|
||||
|
||||
Enter Jasmine
|
||||
------------
|
||||
|
||||
Jasmine is our dream JavaScript testing framework. It's heavily influenced by, and borrows the best parts of, ScrewUnit, JSSpec, [JSpec](http://github.com/visionmedia/jspec/tree/master), and of course RSpec.
|
||||
|
||||
Jasmine was designed with a few principles in mind. We believe that a good JavaScript testing framework:
|
||||
|
||||
* should not be tied to any browser, framework, platform, or host language.
|
||||
* should have idiomatic and unsurprising syntax.
|
||||
* should work anywhere JavaScript can run, including browsers, servers, phones, etc.
|
||||
* shouldn't intrude in your application's territory (e.g. by cluttering the global namespace).
|
||||
* should play well with IDEs (e.g. test code should pass static analysis).
|
||||
|
||||
Some of our goals while writing Jasmine:
|
||||
|
||||
* it should encourage good testing practices.
|
||||
* it should integrate easily with continuous build systems.
|
||||
* it should be simple to get started with.
|
||||
|
||||
The result is Jasmine, and we love test-driving our code with it. Enjoy.
|
||||
|
||||
How To
|
||||
------
|
||||
|
||||
There is a simple example of how to use Jasmine in the /example directory. But here's more information.
|
||||
|
||||
### Specs
|
||||
|
||||
Each spec is, naturally, a JavaScript function. You tell Jasmine about this spec with a call to `it()` with a string and the function. The string is a description that will be helpful to you when reading a report.
|
||||
|
||||
it('should be a test', function () {
|
||||
var foo = 0;
|
||||
foo++;
|
||||
});
|
||||
|
||||
### Expectations
|
||||
|
||||
Within your spec you will want to express expectations about the behavior of your application code. These are made with the `expect()` function and expectation matchers, like this:
|
||||
|
||||
it('should be a test', function () {
|
||||
var foo = 0; // set up the world
|
||||
foo++; // call your application code
|
||||
|
||||
expect(foo).toEqual(1); // passes because foo == 1
|
||||
});
|
||||
|
||||
Results of the expectations are logged for later for reporting.
|
||||
|
||||
#### Expectation Matchers
|
||||
|
||||
Jasmine has several built-in matchers. Here are a few:
|
||||
|
||||
>`expect(x).toEqual(y);` compares objects or primitives `x` and `y` and passes if they are equivalent
|
||||
>
|
||||
>`expect(x).toMatch(pattern);` compares `x` to string or regular expression `pattern` and passes if they match
|
||||
>
|
||||
>`expect(x).toBeDefined();` passes if `x` is not `undefined`
|
||||
>
|
||||
>`expect(x).toBeNull();` passes if `x` is `null`
|
||||
>
|
||||
>`expect(x).toBeTruthy();` passes if `x` evaluates to true
|
||||
>
|
||||
>`expect(x).toBeFalsy();` passes if `x` evaluates to false
|
||||
>
|
||||
>`expect(x).toContain(y);` passes if array or string `x` contains `y`
|
||||
|
||||
Every matcher's criteria can be inverted by prepending `.not`:
|
||||
|
||||
>`expect(x).not.toEqual(y);` compares objects or primitives `x` and `y` and passes if they are *not* equivalent
|
||||
|
||||
#### Writing New Matchers
|
||||
|
||||
We've provided a small set of matchers that cover many common situations. However, we recommend that you write custom matchers when you want to assert a more specific sort of expectation. Custom matchers help to document the intent of your specs, and can help to remove code duplication in your specs.
|
||||
|
||||
It's extremely easy to create new matchers for your app. A matcher function receives the actual value as `this.actual`, and zero or more arguments may be passed in the function call. The function should return `true` if the actual value passes the matcher's requirements, and `false` if it does not.
|
||||
|
||||
Here's the definition of `toBeLessThan()`:
|
||||
|
||||
toBeLessThan: function(expected) {
|
||||
return this.actual < expected;
|
||||
};
|
||||
|
||||
To add the matcher to your suite, call `this.addMatchers()` from within a `before` or `it` block. Call it with an object mapping matcher name to function:
|
||||
|
||||
beforeEach(function() {
|
||||
this.addMatchers({
|
||||
toBeVisible: function() { return this.actual.isVisible(); }
|
||||
});
|
||||
});
|
||||
|
||||
### Suites
|
||||
|
||||
Specs are grouped in Suites. Suites are defined using the global `describe()` function:
|
||||
|
||||
describe('One suite', function () {
|
||||
it('has a test', function () {
|
||||
...
|
||||
});
|
||||
|
||||
it('has another test', function () {
|
||||
...
|
||||
});
|
||||
});
|
||||
|
||||
The Suite name is so that reporting is more descriptive.
|
||||
|
||||
Suites are executed in the order in which `describe()` calls are made, usually in the order in which their script files are included. Additionally, specs within a suite share a functional scope. So you may declare variables inside a describe block and they are accessible from within your specs. For example:
|
||||
|
||||
describe('A suite with some variables', function () {
|
||||
var bar = 0
|
||||
|
||||
it('has a test', function () {
|
||||
bar++;
|
||||
expect(bar).toEqual(1);
|
||||
});
|
||||
|
||||
it('has another test', function () {
|
||||
bar++;
|
||||
expect(bar).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
||||
#### beforeEach
|
||||
|
||||
A suite can have a beforeEach declaration. It takes a function that is run before each spec. For example:
|
||||
|
||||
describe('some suite', function () {
|
||||
|
||||
var suiteWideFoo;
|
||||
|
||||
beforeEach(function () {
|
||||
suiteWideFoo = 1;
|
||||
});
|
||||
|
||||
it('should equal bar', function () {
|
||||
expect(suiteWideFoo).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
A runner can also have beforeEach declarations. Runner beforeEach functions are executed before every spec in all suites, and execute BEFORE suite beforeEach functions. For example:
|
||||
|
||||
var runnerWideFoo = [];
|
||||
|
||||
beforeEach(function () {
|
||||
runnerWideFoo.push('runner');
|
||||
});
|
||||
|
||||
describe('some suite', function () {
|
||||
|
||||
beforeEach(function () {
|
||||
runnerWideFoo.push('suite');
|
||||
});
|
||||
|
||||
it('should equal bar', function () {
|
||||
expect(runnerWideFoo).toEqual(['runner', 'suite']);
|
||||
});
|
||||
});
|
||||
|
||||
#### afterEach
|
||||
|
||||
Similarly, there is an afterEach declaration. It takes a function that is run after each spec. For example:
|
||||
|
||||
describe('some suite', function () {
|
||||
|
||||
var suiteWideFoo;
|
||||
afterEach(function () {
|
||||
suiteWideFoo = 0;
|
||||
});
|
||||
|
||||
it('should equal 1', function () {
|
||||
expect(suiteWideFoo).toEqual(1);
|
||||
});
|
||||
|
||||
it('should equal 0 after', function () {
|
||||
expect(suiteWideFoo).toEqual(0);
|
||||
};
|
||||
});
|
||||
|
||||
A runner can also have an afterEach declarations. Runner afterEach functions are executed after every spec in all suites, and execute AFTER suite afterEach functions. For example:
|
||||
|
||||
var runnerWideFoo = [];
|
||||
|
||||
afterEach(function () {
|
||||
runnerWideFoo.push('runner');
|
||||
});
|
||||
|
||||
describe('some suite', function () {
|
||||
|
||||
afterEach(function () {
|
||||
runnerWideFoo.push('suite');
|
||||
});
|
||||
|
||||
it('should be empty', function () {
|
||||
expect(runnerWideFoo).toEqual([]);
|
||||
});
|
||||
|
||||
it('should be populated after', function () {
|
||||
expect(runnerWideFoo).toEqual(['suite', 'runner']);
|
||||
};
|
||||
});
|
||||
|
||||
### Single-spec After functions
|
||||
|
||||
A spec may ask Jasmine to execute some code after the spec has finished running; the code will run whether the spec finishes successfully or not. Multiple after functions may be given.
|
||||
|
||||
describe('some suite', function () {
|
||||
it(function () {
|
||||
var originalTitle = window.title;
|
||||
this.after(function() { window.title = originalTitle; });
|
||||
MyWindow.setTitle("new value");
|
||||
expect(window.title).toEqual("new value");
|
||||
});
|
||||
|
||||
|
||||
### Nested Describes
|
||||
Jasmine supports nested describes. An example:
|
||||
|
||||
describe('some suite', function () {
|
||||
|
||||
var suiteWideFoo;
|
||||
|
||||
beforeEach(function () {
|
||||
suiteWideFoo = 0;
|
||||
});
|
||||
|
||||
describe('some nested suite', function() {
|
||||
var nestedSuiteBar;
|
||||
beforeEach(function() {
|
||||
nestedSuiteBar=1;
|
||||
});
|
||||
|
||||
it('nested expectation', function () {
|
||||
expect(suiteWideFoo).toEqual(0);
|
||||
expect(nestedSuiteBar).toEqual(1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('top-level describe', function () {
|
||||
expect(suiteWideFoo).toEqual(0);
|
||||
expect(nestedSuiteBar).toEqual(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
### Spies
|
||||
|
||||
Jasmine integrates 'spies' that permit many spying, mocking, and faking behaviors.
|
||||
|
||||
Here are a few examples:
|
||||
|
||||
var Klass = function () {
|
||||
};
|
||||
|
||||
var Klass.prototype.method = function (arg) {
|
||||
return arg;
|
||||
};
|
||||
|
||||
var Klass.prototype.methodWithCallback = function (callback) {
|
||||
return callback('foo');
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
it('should spy on Klass#method') {
|
||||
spyOn(Klass, 'method');
|
||||
Klass.method('foo argument');
|
||||
|
||||
expect(Klass.method).toHaveBeenCalledWith('foo argument');
|
||||
});
|
||||
|
||||
it('should spy on Klass#methodWithCallback') {
|
||||
var callback = Jasmine.createSpy();
|
||||
Klass.methodWithCallback(callback);
|
||||
|
||||
expect(callback).toHaveBeenCalledWith('foo');
|
||||
});
|
||||
|
||||
|
||||
Spies can be very useful for testing AJAX or other asynchronous behaviors that take callbacks by faking the method firing an async call.
|
||||
|
||||
var Klass = function () {
|
||||
};
|
||||
|
||||
var Klass.prototype.asyncMethod = function (callback) {
|
||||
someAsyncCall(callback);
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
it('should test async call') {
|
||||
spyOn(Klass, 'asyncMethod');
|
||||
var callback = Jasmine.createSpy();
|
||||
|
||||
Klass.asyncMethod(callback);
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
|
||||
var someResponseData = 'foo';
|
||||
Klass.asyncMethod.mostRecentCall.args[0](someResponseData);
|
||||
expect(callback).toHaveBeenCalledWith(someResponseData);
|
||||
|
||||
});
|
||||
|
||||
There are spy-specfic matchers that are very handy.
|
||||
|
||||
`expect(x).toHaveBeenCalled()` passes if `x` is a spy and was called
|
||||
|
||||
`expect(x).toHaveBeenCalledWith(arguments)` passes if `x` is a spy and was called with the specified arguments
|
||||
|
||||
`expect(x).not.toHaveBeenCalled()` passes if `x` is a spy and was not called
|
||||
|
||||
`expect(x).not.toHaveBeenCalledWith(arguments)` passes if `x` is a spy and was not called with the specified arguments
|
||||
|
||||
The old matchers `wasCalled`, `wasNotCalled`, `wasCalledWith`, and `wasNotCalledWith` have been deprecated and will be removed in a future release. Please change your specs to use `toHaveBeenCalled`, `not.toHaveBeenCalled`, `toHaveBeenCalledWith`, and `not.toHaveBeenCalledWith` respectively.
|
||||
|
||||
Spies can be trained to respond in a variety of ways when invoked:
|
||||
|
||||
`spyOn(x, 'method').andCallThrough()`: spies on AND calls the original function spied on
|
||||
|
||||
`spyOn(x, 'method').andReturn(arguments)`: returns passed arguments when spy is called
|
||||
|
||||
`spyOn(x, 'method').andThrow(exception)`: throws passed exception when spy is called
|
||||
|
||||
`spyOn(x, 'method').andCallFake(function)`: calls passed function when spy is called
|
||||
|
||||
Spies have some useful properties:
|
||||
|
||||
`callCount`: returns number of times spy was called
|
||||
|
||||
`mostRecentCall.args`: returns argument array from last call to spy.
|
||||
|
||||
`argsForCall[i]` returns arguments array for call `i` to spy.
|
||||
|
||||
Spies are automatically removed after each spec. They may be set in the beforeEach function.
|
||||
|
||||
### Disabling Tests & Suites
|
||||
|
||||
Specs may be disabled by calling `xit()` instead of `it()`. Suites may be disabled by calling `xdescribe()` instead of `describe()`. A simple find/replace in your editor of choice will allow you to run a subset of your specs.
|
||||
|
||||
### Asynchronous Specs
|
||||
|
||||
You may be thinking, "That's all very nice, but what's this about asynchronous tests?"
|
||||
|
||||
Well, say you need to make a call that is asynchronous - an AJAX API, event callback, or some other JavaScript library. That is, the call returns immediately, yet you want to make expectations 'at some point in the future' after some magic happens in the background.
|
||||
|
||||
Jasmine allows you to do this with `runs()` and `waits()` blocks.
|
||||
|
||||
`runs()` blocks by themselves simply run as if they were called directly. The following snippets of code should provide similar results:
|
||||
|
||||
it('should be a test', function () {
|
||||
var foo = 0
|
||||
foo++;
|
||||
|
||||
expect(foo).toEqual(1);
|
||||
});
|
||||
|
||||
and
|
||||
|
||||
it('should be a test', function () {
|
||||
runs( function () {
|
||||
var foo = 0
|
||||
foo++;
|
||||
|
||||
expect(foo).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
multiple `runs()` blocks in a spec will run serially. For example,
|
||||
|
||||
it('should be a test', function () {
|
||||
runs( function () {
|
||||
var foo = 0
|
||||
foo++;
|
||||
|
||||
expect(foo).toEqual(1);
|
||||
});
|
||||
runs( function () {
|
||||
var bar = 0
|
||||
bar++;
|
||||
|
||||
expect(bar).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
`runs()` blocks share functional scope -- `this` properties will be common to all blocks, but declared `var`'s will not!
|
||||
|
||||
it('should be a test', function () {
|
||||
runs( function () {
|
||||
this.foo = 0
|
||||
this.foo++;
|
||||
var bar = 0;
|
||||
bar++;
|
||||
|
||||
expect(this.foo).toEqual(1);
|
||||
expect(bar).toEqual(1);
|
||||
});
|
||||
runs( function () {
|
||||
this.foo++;
|
||||
var bar = 0
|
||||
bar++;
|
||||
|
||||
expect(foo).toEqual(2);
|
||||
expect(bar).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
`runs()` blocks exist so you can test asynchronous processes. The function `waits()` works with `runs()` to provide a naive
|
||||
timeout before the next block is run. You supply a time to wait before the next `runs()` function is executed. For example:
|
||||
|
||||
it('should be a test', function () {
|
||||
runs(function () {
|
||||
this.foo = 0;
|
||||
var that = this;
|
||||
setTimeout(function () {
|
||||
that.foo++;
|
||||
}, 250);
|
||||
});
|
||||
|
||||
runs(function () {
|
||||
this.expects(this.foo).toEqual(0);
|
||||
});
|
||||
|
||||
waits(500);
|
||||
|
||||
runs(function () {
|
||||
this.expects(this.foo).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
What's happening here?
|
||||
|
||||
* The first call to `runs()` sets call for 1/4 of a second in the future that increments `this.foo`.
|
||||
* The second `runs()` is executed immediately and then verifies that `this.foo` was indeed initialized to zero in the previous `runs()`.
|
||||
* Then we wait for half a second.
|
||||
* Then the last call to `runs()` expects that `this.foo` was incremented by the `setTimeout`.
|
||||
|
||||
## Support
|
||||
We now have a Google Group for support & discussion.
|
||||
|
||||
* Discussion: [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js)
|
||||
* Group email: [jasmine-js@googlegroups.com](jasmine-js@googlegroups.com)
|
||||
* Current build status of Jasmine is visible at [ci.pivotallabs.com](http://ci.pivotallabs.com)
|
||||
* Pivotal Tracker project: [http://www.pivotaltracker.com/projects/10606](http://www.pivotaltracker.com/projects/10606)
|
||||
* Twitter: [@JasmineBDD](http://twitter.com/JasmineBDD)
|
||||
* Search past discussions: [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js)
|
||||
* Send an email to the list: [jasmine-js@googlegroups.com](jasmine-js@googlegroups.com)
|
||||
* Check the current build status: [ci.pivotallabs.com](http://ci.pivotallabs.com)
|
||||
* View the project backlog at Pivotal Tracker: [http://www.pivotaltracker.com/projects/10606](http://www.pivotaltracker.com/projects/10606)
|
||||
* Follow us on Twitter: [@JasmineBDD](http://twitter.com/JasmineBDD)
|
||||
|
||||
|
||||
## Maintainers
|
||||
|
||||
* [Davis W. Frank](mailto:dwfrank@pivotallabs.com), Pivotal Labs
|
||||
* [Rajan Agaskar](mailto:rajan@pivotallabs.com), Pivotal Labs
|
||||
* [Christian Williams](mailto:xian@pivotallabs.com), Pivotal Labs
|
||||
* [Christian Williams](mailto:antixian666@gmail.com), Square
|
||||
|
||||
## Developers
|
||||
We welcome your contributions! Jasmine is currently maintained by Davis Frank ([infews](http://github.com/infews)), Rajan Agaskar ([ragaskar](http://github.com/ragaskar)), and Christian Williams ([Xian](http://github.com/Xian)). You can help us by removing all other recipients from your pull request.
|
||||
|
||||
## Acknowledgments
|
||||
* A big shout out to the various JavaScript test framework authors, especially TJ for [JSpec](http://github.com/visionmedia/jspec/tree/master) - we played with it a bit before deciding that we really needed to roll our own.
|
||||
* Thanks to Pivot [Jessica Miller](http://www.jessicamillerworks.com/) for our fancy pass/fail/pending icons
|
||||
* Huge contributions have been made by [Adam Abrons](mailto:adam@pivotallabs.com), [Lee Byrd](mailto:lee@pivotallabs.com), [Erik Hanson](mailto:erik@pivotallabs.com), [Carl Jackson](mailto:carl@pivotallabs.com), and many other Pivots.
|
||||
Copyright (c) 2008-2011 Pivotal Labs. This software is licensed under the MIT License.
|
||||
|
||||
185
Rakefile
@@ -1,176 +1,33 @@
|
||||
def jasmine_sources
|
||||
sources = ["src/base.js", "src/util.js", "src/Env.js", "src/Reporter.js", "src/Block.js"]
|
||||
sources += Dir.glob('src/*.js').reject { |f| f == 'src/base.js' || sources.include?(f) }.sort
|
||||
sources
|
||||
require "bundler"
|
||||
Bundler::GemHelper.install_tasks
|
||||
require "term/ansicolor"
|
||||
require "json"
|
||||
require "tilt"
|
||||
|
||||
Dir["#{File.dirname(__FILE__)}/tasks/**/*.rb"].each do |file|
|
||||
require file
|
||||
end
|
||||
|
||||
def jasmine_html_sources
|
||||
["src/html/TrivialReporter.js"]
|
||||
task :default => :spec
|
||||
|
||||
task :require_pages_submodule do
|
||||
raise "Submodule for Github Pages isn't present. Run git submodule update --init" unless pages_submodule_present
|
||||
end
|
||||
|
||||
def jasmine_version
|
||||
"#{version_hash['major']}.#{version_hash['minor']}.#{version_hash['build']}"
|
||||
task :require_node do
|
||||
raise "\nNode.js is required to develop code for Jasmine. Please visit http://nodejs.org to install.\n\n" unless node_installed?
|
||||
end
|
||||
|
||||
def version_hash
|
||||
require 'json'
|
||||
@version ||= JSON.parse(File.new("src/version.json").read);
|
||||
def pages_submodule_present
|
||||
File.exist?('pages/download.html')
|
||||
end
|
||||
|
||||
task :default => 'jasmine:dist'
|
||||
|
||||
def substitute_jasmine_version(filename)
|
||||
contents = File.read(filename)
|
||||
contents = contents.gsub(/##JASMINE_VERSION##/, (jasmine_version))
|
||||
File.open(filename, 'w') { |f| f.write(contents) }
|
||||
def node_installed?
|
||||
`which node` =~ /node/
|
||||
end
|
||||
|
||||
namespace :jasmine do
|
||||
|
||||
desc 'Prepares for distribution'
|
||||
task :dist => ['jasmine:build', 'jasmine:doc', 'jasmine:build_example_project', 'jasmine:fill_index_downloads']
|
||||
|
||||
desc 'Check jasmine sources for coding problems'
|
||||
task :lint do
|
||||
passed = true
|
||||
jasmine_sources.each do |src|
|
||||
lines = File.read(src).split(/\n/)
|
||||
lines.each_index do |i|
|
||||
line = lines[i]
|
||||
undefineds = line.scan(/.?undefined/)
|
||||
if undefineds.include?(" undefined") || undefineds.include?("\tundefined")
|
||||
puts "Dangerous undefined at #{src}:#{i}:\n > #{line}"
|
||||
passed = false
|
||||
end
|
||||
|
||||
if line.scan(/window/).length > 0
|
||||
puts "Dangerous window at #{src}:#{i}:\n > #{line}"
|
||||
passed = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless passed
|
||||
puts "Lint failed!"
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Builds lib/jasmine from source'
|
||||
task :build => :lint do
|
||||
puts 'Building Jasmine from source'
|
||||
|
||||
sources = jasmine_sources
|
||||
version = version_hash
|
||||
|
||||
old_jasmine_files = Dir.glob('lib/jasmine*.js')
|
||||
old_jasmine_files.each { |file| File.delete(file) }
|
||||
|
||||
File.open("lib/jasmine.js", 'w') do |jasmine|
|
||||
sources.each do |source_filename|
|
||||
jasmine.puts(File.read(source_filename))
|
||||
end
|
||||
|
||||
jasmine.puts %{
|
||||
jasmine.version_= {
|
||||
"major": #{version['major']},
|
||||
"minor": #{version['minor']},
|
||||
"build": #{version['build']},
|
||||
"revision": #{Time.now.to_i}
|
||||
};
|
||||
}
|
||||
end
|
||||
|
||||
File.open("lib/jasmine-html.js", 'w') do |jasmine_html|
|
||||
jasmine_html_sources.each do |source_filename|
|
||||
jasmine_html.puts(File.read(source_filename))
|
||||
end
|
||||
end
|
||||
|
||||
FileUtils.cp("src/html/jasmine.css", "lib/jasmine.css")
|
||||
end
|
||||
|
||||
task :need_pages_submodule do
|
||||
unless File.exists?('pages/index.html')
|
||||
raise "Jasmine pages submodule isn't present. Run git submodule update --init"
|
||||
end
|
||||
end
|
||||
|
||||
desc "Build jasmine documentation"
|
||||
task :doc => :need_pages_submodule do
|
||||
puts 'Creating Jasmine Documentation'
|
||||
require 'rubygems'
|
||||
#sudo gem install ragaskar-jsdoc_helper
|
||||
require 'jsdoc_helper'
|
||||
|
||||
FileUtils.rm_r "pages/jsdoc", :force => true
|
||||
|
||||
JsdocHelper::Rake::Task.new(:lambda_jsdoc) do |t|
|
||||
t[:files] = jasmine_sources << jasmine_html_sources
|
||||
t[:options] = "-a"
|
||||
t[:out] = "pages/jsdoc"
|
||||
end
|
||||
Rake::Task[:lambda_jsdoc].invoke
|
||||
end
|
||||
|
||||
desc "Build example project"
|
||||
task :build_example_project => :need_pages_submodule do
|
||||
require 'tmpdir'
|
||||
|
||||
temp_dir = File.join(Dir.tmpdir, 'jasmine-standalone-project')
|
||||
puts "Building Example Project in #{temp_dir}"
|
||||
FileUtils.rm_r temp_dir if File.exists?(temp_dir)
|
||||
Dir.mkdir(temp_dir)
|
||||
|
||||
root = File.expand_path(File.dirname(__FILE__))
|
||||
FileUtils.cp_r File.join(root, 'example/.'), File.join(temp_dir)
|
||||
substitute_jasmine_version(File.join(temp_dir, "SpecRunner.html"))
|
||||
|
||||
lib_dir = File.join(temp_dir, "lib/jasmine-#{jasmine_version}")
|
||||
FileUtils.mkdir_p(lib_dir)
|
||||
{
|
||||
"lib/jasmine.js" => "jasmine.js",
|
||||
"lib/jasmine-html.js" => "jasmine-html.js",
|
||||
"src/html/jasmine.css" => "jasmine.css"
|
||||
}.each_pair do |src, dest|
|
||||
FileUtils.cp(File.join(root, src), File.join(lib_dir, dest))
|
||||
end
|
||||
|
||||
dist_dir = File.join(root, 'pages/downloads')
|
||||
zip_file_name = File.join(dist_dir, "jasmine-standalone-#{jasmine_version}.zip")
|
||||
puts "Zipping Example Project and moving to #{zip_file_name}"
|
||||
FileUtils.mkdir(dist_dir) unless File.exist?(dist_dir)
|
||||
if File.exist?(zip_file_name)
|
||||
puts "WARNING!!! #{zip_file_name} already exists!"
|
||||
FileUtils.rm(zip_file_name)
|
||||
end
|
||||
exec "cd #{temp_dir} && zip -r #{zip_file_name} . -x .[a-zA-Z0-9]*"
|
||||
end
|
||||
|
||||
task :fill_index_downloads do
|
||||
require 'digest/sha1'
|
||||
|
||||
download_html = "<!-- START_DOWNLOADS -->\n"
|
||||
download_html += "<table>\n<tr><th/><th>Version</th><th>Size</th><th>Date</th><th>SHA1</th></tr>\n"
|
||||
Dir.glob('pages/downloads/*.zip').sort.reverse.each do |f|
|
||||
sha1 = Digest::SHA1.hexdigest File.read(f)
|
||||
|
||||
fn = f.sub(/^pages\//, '')
|
||||
version = /jasmine-standalone-(.*).zip/.match(f)[1]
|
||||
download_html += "<td><a href='#{fn}'>#{fn.sub(/downloads\//, '')}</a></td>"
|
||||
download_html += "<td>#{version}</td>\n"
|
||||
download_html += "<td>#{File.size(f) / 1024}k</td>\n"
|
||||
download_html += "<td>#{File.mtime(f).strftime("%Y/%m/%d %H:%M:%S")}</td>\n"
|
||||
download_html += "<td>#{sha1}</td>\n"
|
||||
end
|
||||
download_html += "</table>\n<!-- END_DOWNLOADS -->"
|
||||
|
||||
index_page = File.read('pages/index.html')
|
||||
matcher = /<!-- START_DOWNLOADS -->.*<!-- END_DOWNLOADS -->/m
|
||||
index_page = index_page.sub(matcher, download_html)
|
||||
File.open('pages/index.html', 'w') {|f| f.write(index_page)}
|
||||
puts "rewrote that file"
|
||||
end
|
||||
class String
|
||||
include Term::ANSIColor
|
||||
end
|
||||
|
||||
task :jasmine => ['jasmine:dist']
|
||||
Term::ANSIColor.coloring = STDOUT.isatty
|
||||
|
||||
40
Release.markdown
Normal file
@@ -0,0 +1,40 @@
|
||||
# How to work on a Jasmine Release
|
||||
|
||||
## Development
|
||||
___Jasmine Core Maintainers Only___
|
||||
|
||||
Follow the instructions in `Contribute.markdown` during development.
|
||||
|
||||
### Git Commits
|
||||
|
||||
|
||||
### Version
|
||||
|
||||
We attempt to stick to [Semantic Versioning](). Most of the time, development should be against a new minor version - fixing bugs and adding new features that are backwards compatible.
|
||||
|
||||
The current version lives in the file `src/version.json`. This file should be set to the version that is _currently_ under development. That is, if version 1.0.0 is the current release then version should be incremented say, to 1.1.0.
|
||||
|
||||
This version is used by both `jasmine.js` and the `jasmine-core` Ruby gem.
|
||||
|
||||
|
||||
### Update the Github Pages (as needed)
|
||||
|
||||
Github pages have to exist in a branch called gh-pages in order for their app to serve them. This repo adds that branch as a submodule under the `pages` directory. This is a bit of a hack, but it allows us to work with the pages and the source at the same time and with one set of rake tasks.
|
||||
|
||||
If you want to submit changes to this repo and aren't a Pivotal Labs employee, you can fork and work in the `gh-pages` branch. You won't be able to edit the pages in the submodule off of master.
|
||||
|
||||
The pages are built with [Frank](https://github.com/blahed/frank). All the source for these pages live in the `pages/pages_source` directory.
|
||||
|
||||
## Release
|
||||
|
||||
When ready to release - specs are all green and the stories are done:
|
||||
|
||||
1. Update the version in `version.json` to a release candidate - add an `rc` property with a value of 1
|
||||
1. Update any comments on the public interfaces
|
||||
1. `rake doc` - builds the `jsdoc` pages
|
||||
1. Update any links or top-level landing page for the Github Pages
|
||||
1. `rake standalone` - builds the standalone distribution ZIP file
|
||||
1. `rake build_pages` - builds the Github Pages
|
||||
1. `rake release` - tags the repo with the version, builds the `jasmine-core` gem, pushes the gem to Rubygems.org
|
||||
|
||||
There should be a post to Pivotal Labs blog and a tweet to that link.
|
||||
@@ -1,21 +0,0 @@
|
||||
# Project-specific configuration for CruiseControl.rb
|
||||
Project.configure do |project|
|
||||
|
||||
# Send email notifications about broken and fixed builds to email1@your.site, email2@your.site (default: send to nobody)
|
||||
# project.email_notifier.emails = ['email1@your.site', 'email2@your.site']
|
||||
|
||||
# Set email 'from' field to john@doe.com:
|
||||
# project.email_notifier.from = 'john@doe.com'
|
||||
|
||||
# Build the project by invoking rake task 'custom'
|
||||
project.rake_task = 'jasmine:test:ci:saucelabs'
|
||||
|
||||
# Build the project by invoking shell script "build_my_app.sh". Keep in mind that when the script is invoked,
|
||||
# current working directory is <em>[cruise data]</em>/projects/your_project/work, so if you do not keep build_my_app.sh
|
||||
# in version control, it should be '../build_my_app.sh' instead
|
||||
#project.build_command = 'cp ../saucelabs.yml .'
|
||||
|
||||
# Ping Subversion for new revisions every 5 minutes (default: 30 seconds)
|
||||
# project.scheduler.polling_interval = 5.minutes
|
||||
|
||||
end
|
||||
@@ -1,27 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Jasmine Test Runner</title>
|
||||
<link rel="stylesheet" type="text/css" href="lib/jasmine-##JASMINE_VERSION##/jasmine.css">
|
||||
<script type="text/javascript" src="lib/jasmine-##JASMINE_VERSION##/jasmine.js"></script>
|
||||
<script type="text/javascript" src="lib/jasmine-##JASMINE_VERSION##/jasmine-html.js"></script>
|
||||
|
||||
<!-- include source files here... -->
|
||||
<script type="text/javascript" src="src/Player.js"></script>
|
||||
<script type="text/javascript" src="src/Song.js"></script>
|
||||
|
||||
<!-- include spec files here... -->
|
||||
<script type="text/javascript" src="spec/SpecHelper.js"></script>
|
||||
<script type="text/javascript" src="spec/PlayerSpec.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
|
||||
jasmine.getEnv().execute();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
Before Width: | Height: | Size: 722 B |
BIN
images/fail.png
|
Before Width: | Height: | Size: 2.1 KiB |
BIN
images/go-16.png
|
Before Width: | Height: | Size: 759 B |
BIN
images/go.png
|
Before Width: | Height: | Size: 2.2 KiB |
BIN
images/jasmine_favicon.png
Normal file
|
After Width: | Height: | Size: 905 B |
|
Before Width: | Height: | Size: 802 B |
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 768 B |
|
Before Width: | Height: | Size: 1.7 KiB |
22
jasmine-core.gemspec
Normal file
@@ -0,0 +1,22 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
$:.push File.expand_path("../lib", __FILE__)
|
||||
require "jasmine-core/version"
|
||||
|
||||
Gem::Specification.new do |s|
|
||||
s.name = "jasmine-core"
|
||||
s.version = Jasmine::Core::VERSION
|
||||
s.platform = Gem::Platform::RUBY
|
||||
s.authors = ["Rajan Agaskar", "Davis Frank", "Christian Williams"]
|
||||
s.summary = %q{JavaScript BDD framework}
|
||||
s.description = %q{Test your JavaScript without any framework dependencies, in any environment, and with a nice descriptive syntax.}
|
||||
s.email = %q{jasmine-js@googlegroups.com}
|
||||
s.homepage = "http://pivotal.github.com/jasmine"
|
||||
s.rubyforge_project = "jasmine-core"
|
||||
|
||||
s.files = Dir.glob("./lib/**/*") + Dir.glob("./lib/jasmine-core/spec/**/*.js")
|
||||
s.require_paths = ["lib"]
|
||||
s.add_development_dependency "term-ansicolor"
|
||||
s.add_development_dependency "json_pure", ">= 1.4.3"
|
||||
s.add_development_dependency "frank"
|
||||
s.add_development_dependency "ragaskar-jsdoc_helper"
|
||||
end
|
||||
17
jsdoc-template/allclasses.tmpl
Normal file
@@ -0,0 +1,17 @@
|
||||
<div align="center">{+new Link().toFile("index.html").withText("Class Index")+}
|
||||
| {+new Link().toFile("files.html").withText("File Index")+}</div>
|
||||
<hr />
|
||||
<h2>Classes</h2>
|
||||
<ul class="classList">
|
||||
<for each="thisClass" in="data">
|
||||
<li>{!
|
||||
if (thisClass.alias == "_global_") {
|
||||
output += "<i>"+new Link().toClass(thisClass.alias)+"</i>";
|
||||
}
|
||||
else {
|
||||
output += new Link().toClass(thisClass.alias);
|
||||
}
|
||||
!}</li>
|
||||
</for>
|
||||
</ul>
|
||||
<hr />
|
||||
56
jsdoc-template/allfiles.tmpl
Normal file
@@ -0,0 +1,56 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset={+IO.encoding+}"" />
|
||||
{! Link.base = ""; /* all generated links will be relative to this */ !}
|
||||
<title>JsDoc Reference - File Index</title>
|
||||
<meta name="generator" content="JsDoc Toolkit" />
|
||||
|
||||
<style type="text/css">
|
||||
{+include("static/default.css")+}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{+include("static/header.html")+}
|
||||
|
||||
<div id="index">
|
||||
{+publish.classesIndex+}
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<h1 class="classTitle">File Index</h1>
|
||||
|
||||
<for each="item" in="data">
|
||||
<div>
|
||||
<h2>{+new Link().toSrc(item.alias).withText(item.name)+}</h2>
|
||||
<if test="item.desc">{+resolveLinks(summarize(item.desc))+}</if>
|
||||
<dl>
|
||||
<if test="item.author">
|
||||
<dt class="heading">Author:</dt>
|
||||
<dd>{+item.author+}</dd>
|
||||
</if>
|
||||
<if test="item.version">
|
||||
<dt class="heading">Version:</dt>
|
||||
<dd>{+item.version+}</dd>
|
||||
</if>
|
||||
{! var locations = item.comment.getTag('location').map(function($){return $.toString().replace(/(^\$ ?| ?\$$)/g, '').replace(/^HeadURL: https:/g, 'http:');}) !}
|
||||
<if test="locations.length">
|
||||
<dt class="heading">Location:</dt>
|
||||
<for each="location" in="locations">
|
||||
<dd><a href="{+location+}">{+location+}</a></dd>
|
||||
</for>
|
||||
</if>
|
||||
</dl>
|
||||
</div>
|
||||
<hr />
|
||||
</for>
|
||||
|
||||
</div>
|
||||
<div class="fineprint" style="clear:both">
|
||||
<if test="JSDOC.opt.D.copyright">©{+JSDOC.opt.D.copyright+}<br /></if>
|
||||
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blankt">JsDoc Toolkit</a> {+JSDOC.VERSION+} on {+new Date()+}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
646
jsdoc-template/class.tmpl
Normal file
@@ -0,0 +1,646 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset={+IO.encoding+}" />
|
||||
<meta name="generator" content="JsDoc Toolkit" />
|
||||
{! Link.base = "../"; /* all generated links will be relative to this */ !}
|
||||
<title>JsDoc Reference - {+data.alias+}</title>
|
||||
|
||||
<style type="text/css">
|
||||
{+include("static/default.css")+}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- ============================== header ================================= -->
|
||||
<!-- begin static/header.html -->
|
||||
{+include("static/header.html")+}
|
||||
<!-- end static/header.html -->
|
||||
|
||||
<!-- ============================== classes index ============================ -->
|
||||
<div id="index">
|
||||
<!-- begin publish.classesIndex -->
|
||||
{+publish.classesIndex+}
|
||||
<!-- end publish.classesIndex -->
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<!-- ============================== class title ============================ -->
|
||||
<h1 class="classTitle">
|
||||
{!
|
||||
var classType = "";
|
||||
|
||||
if (data.isBuiltin()) {
|
||||
classType += "Built-In ";
|
||||
}
|
||||
|
||||
if (data.isNamespace) {
|
||||
if (data.is('FUNCTION')) {
|
||||
classType += "Function ";
|
||||
}
|
||||
classType += "Namespace ";
|
||||
}
|
||||
else {
|
||||
classType += "Class ";
|
||||
}
|
||||
!}
|
||||
{+classType+}{+data.alias+}
|
||||
</h1>
|
||||
|
||||
<!-- ============================== class summary ========================== -->
|
||||
<p class="description">
|
||||
<if test="data.augments.length"><br />Extends
|
||||
{+
|
||||
data.augments
|
||||
.sort()
|
||||
.map(
|
||||
function($) { return new Link().toSymbol($); }
|
||||
)
|
||||
.join(", ")
|
||||
+}.<br />
|
||||
</if>
|
||||
|
||||
{+resolveLinks(data.classDesc)+}
|
||||
|
||||
<if test="!data.isBuiltin()">{# isn't defined in any file #}
|
||||
<br /><i>Defined in: </i> {+new Link().toSrc(data.srcFile)+}.
|
||||
</if>
|
||||
</p>
|
||||
|
||||
<!-- ============================== constructor summary ==================== -->
|
||||
<if test="!data.isBuiltin() && (data.isNamespace || data.is('CONSTRUCTOR'))">
|
||||
<table class="summaryTable" cellspacing="0" summary="A summary of the constructor documented in the class {+data.alias+}.">
|
||||
<caption>{+classType+}Summary</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Constructor Attributes</th>
|
||||
<th scope="col">Constructor Name and Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="attributes">{!
|
||||
if (data.isPrivate) output += "<private> ";
|
||||
if (data.isInner) output += "<inner> ";
|
||||
!} </td>
|
||||
<td class="nameDescription" {!if (data.comment.getTag("hilited").length){output += 'style="color: red"'}!}>
|
||||
<div class="fixedFont">
|
||||
<b>{+ new Link().toSymbol(data.alias).inner('constructor')+}</b><if test="classType != 'Namespace '">{+ makeSignature(data.params) +}</if>
|
||||
</div>
|
||||
<div class="description">{+resolveLinks(summarize(data.desc))+}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</if>
|
||||
|
||||
<!-- ============================== properties summary ===================== -->
|
||||
<if test="data.properties.length">
|
||||
{! var ownProperties = data.properties.filter(function($){return $.memberOf == data.alias && !$.isNamespace}).sort(makeSortby("name")); !}
|
||||
<if test="ownProperties.length">
|
||||
<table class="summaryTable" cellspacing="0" summary="A summary of the fields documented in the class {+data.alias+}.">
|
||||
<caption>Field Summary</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Field Attributes</th>
|
||||
<th scope="col">Field Name and Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<for each="member" in="ownProperties">
|
||||
<tr>
|
||||
<td class="attributes">{!
|
||||
if (member.isPrivate) output += "<private> ";
|
||||
if (member.isInner) output += "<inner> ";
|
||||
if (member.isStatic) output += "<static> ";
|
||||
if (member.isConstant) output += "<constant> ";
|
||||
!} </td>
|
||||
<td class="nameDescription">
|
||||
<div class="fixedFont">
|
||||
<if test="member.isStatic && member.memberOf != '_global_'">{+member.memberOf+}.</if><b>{+new Link().toSymbol(member.alias).withText(member.name)+}</b>
|
||||
</div>
|
||||
<div class="description">{+resolveLinks(summarize(member.desc))+}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</for>
|
||||
</tbody>
|
||||
</table>
|
||||
</if>
|
||||
|
||||
<if test="data.inheritsFrom.length">
|
||||
<dl class="inheritsList">
|
||||
{!
|
||||
var borrowedMembers = data.properties.filter(function($) {return $.memberOf != data.alias});
|
||||
|
||||
var contributers = [];
|
||||
borrowedMembers.map(function($) {if (contributers.indexOf($.memberOf) < 0) contributers.push($.memberOf)});
|
||||
for (var i = 0, l = contributers.length; i < l; i++) {
|
||||
output +=
|
||||
"<dt>Fields borrowed from class "+new Link().toSymbol(contributers[i])+": </dt>"
|
||||
+
|
||||
"<dd>" +
|
||||
borrowedMembers
|
||||
.filter(
|
||||
function($) { return $.memberOf == contributers[i] }
|
||||
)
|
||||
.sort(makeSortby("name"))
|
||||
.map(
|
||||
function($) { return new Link().toSymbol($.alias).withText($.name) }
|
||||
)
|
||||
.join(", ")
|
||||
+
|
||||
"</dd>";
|
||||
}
|
||||
!}
|
||||
</dl>
|
||||
</if>
|
||||
</if>
|
||||
|
||||
<!-- ============================== methods summary ======================== -->
|
||||
<if test="data.methods.length">
|
||||
{! var ownMethods = data.methods.filter(function($){return $.memberOf == data.alias && !$.isNamespace}).sort(makeSortby("name")); !}
|
||||
<if test="ownMethods.length">
|
||||
<table class="summaryTable" cellspacing="0" summary="A summary of the methods documented in the class {+data.alias+}.">
|
||||
<caption>Method Summary</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Method Attributes</th>
|
||||
<th scope="col">Method Name and Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<for each="member" in="ownMethods">
|
||||
<tr>
|
||||
<td class="attributes">{!
|
||||
if (member.isPrivate) output += "<private> ";
|
||||
if (member.isInner) output += "<inner> ";
|
||||
if (member.isStatic) output += "<static> ";
|
||||
!} </td>
|
||||
<td class="nameDescription">
|
||||
<div class="fixedFont"><if test="member.isStatic && member.memberOf != '_global_'">{+member.memberOf+}.</if><b>{+new Link().toSymbol(member.alias).withText(member.name)+}</b>{+makeSignature(member.params)+}
|
||||
</div>
|
||||
<div class="description">{+resolveLinks(summarize(member.desc))+}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</for>
|
||||
</tbody>
|
||||
</table>
|
||||
</if>
|
||||
|
||||
<if test="data.inheritsFrom.length">
|
||||
<dl class="inheritsList">
|
||||
{!
|
||||
var borrowedMembers = data.methods.filter(function($) {return $.memberOf != data.alias});
|
||||
var contributers = [];
|
||||
borrowedMembers.map(function($) {if (contributers.indexOf($.memberOf) < 0) contributers.push($.memberOf)});
|
||||
for (var i = 0, l = contributers.length; i < l; i++) {
|
||||
output +=
|
||||
"<dt>Methods borrowed from class "+new Link().toSymbol(contributers[i])+": </dt>"
|
||||
+
|
||||
"<dd>" +
|
||||
borrowedMembers
|
||||
.filter(
|
||||
function($) { return $.memberOf == contributers[i] }
|
||||
)
|
||||
.sort(makeSortby("name"))
|
||||
.map(
|
||||
function($) { return new Link().toSymbol($.alias).withText($.name) }
|
||||
)
|
||||
.join(", ")
|
||||
+
|
||||
"</dd>";
|
||||
}
|
||||
|
||||
!}
|
||||
</dl>
|
||||
</if>
|
||||
</if>
|
||||
<!-- ============================== events summary ======================== -->
|
||||
<if test="data.events.length">
|
||||
{! var ownEvents = data.events.filter(function($){return $.memberOf == data.alias && !$.isNamespace}).sort(makeSortby("name")); !}
|
||||
<if test="ownEvents.length">
|
||||
<table class="summaryTable" cellspacing="0" summary="A summary of the events documented in the class {+data.alias+}.">
|
||||
<caption>Event Summary</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Event Attributes</th>
|
||||
<th scope="col">Event Name and Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<for each="member" in="ownEvents">
|
||||
<tr>
|
||||
<td class="attributes">{!
|
||||
if (member.isPrivate) output += "<private> ";
|
||||
if (member.isInner) output += "<inner> ";
|
||||
if (member.isStatic) output += "<static> ";
|
||||
!} </td>
|
||||
<td class="nameDescription">
|
||||
<div class="fixedFont"><if test="member.isStatic && member.memberOf != '_global_'">{+member.memberOf+}.</if><b>{+new Link().toSymbol(member.alias).withText(member.name)+}</b>{+makeSignature(member.params)+}
|
||||
</div>
|
||||
<div class="description">{+resolveLinks(summarize(member.desc))+}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</for>
|
||||
</tbody>
|
||||
</table>
|
||||
</if>
|
||||
|
||||
<if test="data.inheritsFrom.length">
|
||||
<dl class="inheritsList">
|
||||
{!
|
||||
var borrowedMembers = data.events.filter(function($) {return $.memberOf != data.alias});
|
||||
var contributers = [];
|
||||
borrowedMembers.map(function($) {if (contributers.indexOf($.memberOf) < 0) contributers.push($.memberOf)});
|
||||
for (var i = 0, l = contributers.length; i < l; i++) {
|
||||
output +=
|
||||
"<dt>Events borrowed from class "+new Link().toSymbol(contributers[i])+": </dt>"
|
||||
+
|
||||
"<dd>" +
|
||||
borrowedMembers
|
||||
.filter(
|
||||
function($) { return $.memberOf == contributers[i] }
|
||||
)
|
||||
.sort(makeSortby("name"))
|
||||
.map(
|
||||
function($) { return new Link().toSymbol($.alias).withText($.name) }
|
||||
)
|
||||
.join(", ")
|
||||
+
|
||||
"</dd>";
|
||||
}
|
||||
|
||||
!}
|
||||
</dl>
|
||||
</if>
|
||||
</if>
|
||||
|
||||
<!-- ============================== constructor details ==================== -->
|
||||
<if test="!data.isBuiltin() && (data.isNamespace || data.is('CONSTRUCTOR'))">
|
||||
<div class="details"><a name="constructor"> </a>
|
||||
<div class="sectionTitle">
|
||||
{+classType+}Detail
|
||||
</div>
|
||||
|
||||
<div class="fixedFont">{!
|
||||
if (data.isPrivate) output += "<private> ";
|
||||
if (data.isInner) output += "<inner> ";
|
||||
!}
|
||||
<b>{+ data.alias +}</b><if test="classType != 'Namespace '">{+ makeSignature(data.params) +}</if>
|
||||
</div>
|
||||
|
||||
<div class="description">
|
||||
{+resolveLinks(data.desc)+}
|
||||
<if test="data.author"><br /><i>Author: </i>{+data.author+}.</if>
|
||||
</div>
|
||||
|
||||
<if test="data.example.length">
|
||||
<for each="example" in="data.example">
|
||||
<pre class="code">{+example+}</pre>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
|
||||
<if test="data.params.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Parameters:</dt>
|
||||
<for each="item" in="data.params">
|
||||
<dt>
|
||||
{+((item.type)?""+("<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type)+"}</span> ")) : "")+} <b>{+item.name+}</b>
|
||||
<if test="item.isOptional"><i>Optional<if test="item.defaultValue">, Default: {+item.defaultValue+}</if></i></if>
|
||||
</dt>
|
||||
<dd>{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="data.deprecated">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Deprecated:</dt>
|
||||
<dt>
|
||||
{+resolveLinks(data.deprecated)+}
|
||||
</dt>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="data.since">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Since:</dt>
|
||||
<dd>{+ data.since +}</dd>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="data.exceptions.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Throws:</dt>
|
||||
<for each="item" in="data.exceptions">
|
||||
<dt>
|
||||
{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+} <b>{+item.name+}</b>
|
||||
</dt>
|
||||
<dd>{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="data.returns.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Returns:</dt>
|
||||
<for each="item" in="data.returns">
|
||||
<dd>{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+}{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="data.requires.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Requires:</dt>
|
||||
<for each="item" in="data.requires">
|
||||
<dd>{+ resolveLinks(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="data.see.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">See:</dt>
|
||||
<for each="item" in="data.see">
|
||||
<dd>{+ new Link().toSymbol(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
|
||||
</div>
|
||||
</if>
|
||||
|
||||
<!-- ============================== field details ========================== -->
|
||||
<if test="defined(ownProperties) && ownProperties.length">
|
||||
<div class="sectionTitle">
|
||||
Field Detail
|
||||
</div>
|
||||
<for each="member" in="ownProperties">
|
||||
<a name="{+Link.symbolNameToLinkName(member)+}"> </a>
|
||||
<div class="fixedFont">{!
|
||||
if (member.isPrivate) output += "<private> ";
|
||||
if (member.isInner) output += "<inner> ";
|
||||
if (member.isStatic) output += "<static> ";
|
||||
if (member.isConstant) output += "<constant> ";
|
||||
!}
|
||||
|
||||
<if test="member.type"><span class="light">{{+new Link().toSymbol(member.type)+}}</span></if>
|
||||
<if test="member.isStatic && member.memberOf != '_global_'"><span class="light">{+member.memberOf+}.</span></if><b>{+member.name+}</b>
|
||||
|
||||
</div>
|
||||
<div class="description">
|
||||
{+resolveLinks(member.desc)+}
|
||||
<if test="member.srcFile != data.srcFile">
|
||||
<br />
|
||||
<i>Defined in: </i> {+new Link().toSrc(member.srcFile)+}.
|
||||
</if>
|
||||
<if test="member.author"><br /><i>Author: </i>{+member.author+}.</if>
|
||||
</div>
|
||||
|
||||
<if test="member.example.length">
|
||||
<for each="example" in="member.example">
|
||||
<pre class="code">{+example+}</pre>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
<if test="member.deprecated">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Deprecated:</dt>
|
||||
<dt>
|
||||
{+ member.deprecated +}
|
||||
</dt>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.since">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Since:</dt>
|
||||
<dd>{+ member.since +}</dd>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.see.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">See:</dt>
|
||||
<for each="item" in="member.see">
|
||||
<dd>{+ new Link().toSymbol(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.defaultValue">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Default Value:</dt>
|
||||
<dd>
|
||||
{+resolveLinks(member.defaultValue)+}
|
||||
</dd>
|
||||
</dl>
|
||||
</if>
|
||||
|
||||
<if test="!$member_last"><hr /></if>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
<!-- ============================== method details ========================= -->
|
||||
<if test="defined(ownMethods) && ownMethods.length">
|
||||
<div class="sectionTitle">
|
||||
Method Detail
|
||||
</div>
|
||||
<for each="member" in="ownMethods">
|
||||
<a name="{+Link.symbolNameToLinkName(member)+}"> </a>
|
||||
<div class="fixedFont">{!
|
||||
if (member.isPrivate) output += "<private> ";
|
||||
if (member.isInner) output += "<inner> ";
|
||||
if (member.isStatic) output += "<static> ";
|
||||
!}
|
||||
|
||||
<if test="member.type"><span class="light">{{+new Link().toSymbol(member.type)+}}</span></if>
|
||||
<if test="member.isStatic && member.memberOf != '_global_'"><span class="light">{+member.memberOf+}.</span></if><b>{+member.name+}</b>{+makeSignature(member.params)+}
|
||||
|
||||
</div>
|
||||
<div class="description">
|
||||
{+resolveLinks(member.desc)+}
|
||||
<if test="member.srcFile != data.srcFile">
|
||||
<br />
|
||||
<i>Defined in: </i> {+new Link().toSrc(member.srcFile)+}.
|
||||
</if>
|
||||
<if test="member.author"><br /><i>Author: </i>{+member.author+}.</if>
|
||||
</div>
|
||||
|
||||
<if test="member.example.length">
|
||||
<for each="example" in="member.example">
|
||||
<pre class="code">{+example+}</pre>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
<if test="member.params.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Parameters:</dt>
|
||||
<for each="item" in="member.params">
|
||||
<dt>
|
||||
{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+}<b>{+item.name+}</b>
|
||||
<if test="item.isOptional"><i>Optional<if test="item.defaultValue">, Default: {+item.defaultValue+}</if></i></if>
|
||||
</dt>
|
||||
<dd>{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.deprecated">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Deprecated:</dt>
|
||||
<dt>
|
||||
{+member.deprecated+}
|
||||
</dt>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.since">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Since:</dt>
|
||||
<dd>{+ member.since +}</dd>
|
||||
</dl>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.exceptions.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Throws:</dt>
|
||||
<for each="item" in="member.exceptions">
|
||||
<dt>
|
||||
{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+} <b>{+item.name+}</b>
|
||||
</dt>
|
||||
<dd>{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.returns.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Returns:</dt>
|
||||
<for each="item" in="member.returns">
|
||||
<dd>{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+}{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.requires.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Requires:</dt>
|
||||
<for each="item" in="member.requires">
|
||||
<dd>{+ resolveLinks(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.see.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">See:</dt>
|
||||
<for each="item" in="member.see">
|
||||
<dd>{+ new Link().toSymbol(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
|
||||
<if test="!$member_last"><hr /></if>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
<!-- ============================== event details ========================= -->
|
||||
<if test="defined(ownEvents) && ownEvents.length">
|
||||
<div class="sectionTitle">
|
||||
Event Detail
|
||||
</div>
|
||||
<for each="member" in="ownEvents">
|
||||
<a name="event:{+Link.symbolNameToLinkName(member)+}"> </a>
|
||||
<div class="fixedFont">{!
|
||||
if (member.isPrivate) output += "<private> ";
|
||||
if (member.isInner) output += "<inner> ";
|
||||
if (member.isStatic) output += "<static> ";
|
||||
!}
|
||||
|
||||
<if test="member.type"><span class="light">{{+new Link().toSymbol(member.type)+}}</span></if>
|
||||
<if test="member.isStatic && member.memberOf != '_global_'"><span class="light">{+member.memberOf+}.</span></if><b>{+member.name+}</b>{+makeSignature(member.params)+}
|
||||
|
||||
</div>
|
||||
<div class="description">
|
||||
{+resolveLinks(member.desc)+}
|
||||
<if test="member.srcFile != data.srcFile">
|
||||
<br />
|
||||
<i>Defined in: </i> {+new Link().toSrc(member.srcFile)+}.
|
||||
</if>
|
||||
<if test="member.author"><br /><i>Author: </i>{+member.author+}.</if>
|
||||
</div>
|
||||
|
||||
<if test="member.example.length">
|
||||
<for each="example" in="member.example">
|
||||
<pre class="code">{+example+}</pre>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
<if test="member.params.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Parameters:</dt>
|
||||
<for each="item" in="member.params">
|
||||
<dt>
|
||||
{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+}<b>{+item.name+}</b>
|
||||
<if test="item.isOptional"><i>Optional<if test="item.defaultValue">, Default: {+item.defaultValue+}</if></i></if>
|
||||
</dt>
|
||||
<dd>{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.deprecated">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Deprecated:</dt>
|
||||
<dt>
|
||||
{+member.deprecated+}
|
||||
</dt>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.since">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Since:</dt>
|
||||
<dd>{+ member.since +}</dd>
|
||||
</dl>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.exceptions.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Throws:</dt>
|
||||
<for each="item" in="member.exceptions">
|
||||
<dt>
|
||||
{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+} <b>{+item.name+}</b>
|
||||
</dt>
|
||||
<dd>{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.returns.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Returns:</dt>
|
||||
<for each="item" in="member.returns">
|
||||
<dd>{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+}{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.requires.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Requires:</dt>
|
||||
<for each="item" in="member.requires">
|
||||
<dd>{+ resolveLinks(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.see.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">See:</dt>
|
||||
<for each="item" in="member.see">
|
||||
<dd>{+ new Link().toSymbol(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
|
||||
<if test="!$member_last"><hr /></if>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
<hr />
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ============================== footer ================================= -->
|
||||
<div class="fineprint" style="clear:both">
|
||||
<if test="JSDOC.opt.D.copyright">©{+JSDOC.opt.D.copyright+}<br /></if>
|
||||
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> {+JSDOC.VERSION+} on {+new Date()+}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
39
jsdoc-template/index.tmpl
Normal file
@@ -0,0 +1,39 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset={+IO.encoding+}"" />
|
||||
|
||||
<title>JsDoc Reference - Index</title>
|
||||
<meta name="generator" content="JsDoc Toolkit" />
|
||||
|
||||
<style type="text/css">
|
||||
{+include("static/default.css")+}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{+include("static/header.html")+}
|
||||
|
||||
<div id="index">
|
||||
{+publish.classesIndex+}
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<h1 class="classTitle">Class Index</h1>
|
||||
|
||||
<for each="thisClass" in="data">
|
||||
<div>
|
||||
<h2>{+(new Link().toSymbol(thisClass.alias))+}</h2>
|
||||
{+resolveLinks(summarize(thisClass.classDesc))+}
|
||||
</div>
|
||||
<hr />
|
||||
</for>
|
||||
|
||||
</div>
|
||||
<div class="fineprint" style="clear:both">
|
||||
<if test="JSDOC.opt.D.copyright">©{+JSDOC.opt.D.copyright+}<br /></if>
|
||||
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blankt">JsDoc Toolkit</a> {+JSDOC.VERSION+} on {+new Date()+}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
184
jsdoc-template/publish.js
Normal file
@@ -0,0 +1,184 @@
|
||||
/** Called automatically by JsDoc Toolkit. */
|
||||
function publish(symbolSet) {
|
||||
publish.conf = { // trailing slash expected for dirs
|
||||
ext: ".html",
|
||||
outDir: JSDOC.opt.d || SYS.pwd+"../out/jsdoc/",
|
||||
templatesDir: JSDOC.opt.t || SYS.pwd+"../templates/jsdoc/",
|
||||
symbolsDir: "symbols/",
|
||||
srcDir: "symbols/src/"
|
||||
};
|
||||
|
||||
// is source output is suppressed, just display the links to the source file
|
||||
if (JSDOC.opt.s && defined(Link) && Link.prototype._makeSrcLink) {
|
||||
Link.prototype._makeSrcLink = function(srcFilePath) {
|
||||
return "<"+srcFilePath+">";
|
||||
}
|
||||
}
|
||||
|
||||
// create the folders and subfolders to hold the output
|
||||
IO.mkPath((publish.conf.outDir+"symbols/src").split("/"));
|
||||
|
||||
// used to allow Link to check the details of things being linked to
|
||||
Link.symbolSet = symbolSet;
|
||||
|
||||
// create the required templates
|
||||
try {
|
||||
var classTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"class.tmpl");
|
||||
var classesTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"allclasses.tmpl");
|
||||
}
|
||||
catch(e) {
|
||||
print("Couldn't create the required templates: "+e);
|
||||
quit();
|
||||
}
|
||||
|
||||
// some ustility filters
|
||||
function hasNoParent($) {return ($.memberOf == "")}
|
||||
function isaFile($) {return ($.is("FILE"))}
|
||||
function isaClass($) {return ($.is("CONSTRUCTOR") || $.isNamespace)}
|
||||
|
||||
// get an array version of the symbolset, useful for filtering
|
||||
var symbols = symbolSet.toArray();
|
||||
|
||||
// create the hilited source code files
|
||||
var files = JSDOC.opt.srcFiles;
|
||||
for (var i = 0, l = files.length; i < l; i++) {
|
||||
var file = files[i];
|
||||
var srcDir = publish.conf.outDir + "symbols/src/";
|
||||
makeSrcFile(file, srcDir);
|
||||
}
|
||||
|
||||
// get a list of all the classes in the symbolset
|
||||
var classes = symbols.filter(isaClass).sort(makeSortby("alias"));
|
||||
|
||||
// create a class index, displayed in the left-hand column of every class page
|
||||
Link.base = "../";
|
||||
publish.classesIndex = classesTemplate.process(classes); // kept in memory
|
||||
|
||||
// create each of the class pages
|
||||
for (var i = 0, l = classes.length; i < l; i++) {
|
||||
var symbol = classes[i];
|
||||
|
||||
symbol.events = symbol.getEvents(); // 1 order matters
|
||||
symbol.methods = symbol.getMethods(); // 2
|
||||
|
||||
var output = "";
|
||||
output = classTemplate.process(symbol);
|
||||
|
||||
IO.saveFile(publish.conf.outDir+"symbols/", symbol.alias+publish.conf.ext, output);
|
||||
}
|
||||
|
||||
// regenerate the index with different relative links, used in the index pages
|
||||
Link.base = "";
|
||||
publish.classesIndex = classesTemplate.process(classes);
|
||||
|
||||
// create the class index page
|
||||
try {
|
||||
var classesindexTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"index.tmpl");
|
||||
}
|
||||
catch(e) { print(e.message); quit(); }
|
||||
|
||||
var classesIndex = classesindexTemplate.process(classes);
|
||||
IO.saveFile(publish.conf.outDir, "index"+publish.conf.ext, classesIndex);
|
||||
classesindexTemplate = classesIndex = classes = null;
|
||||
|
||||
// create the file index page
|
||||
try {
|
||||
var fileindexTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"allfiles.tmpl");
|
||||
}
|
||||
catch(e) { print(e.message); quit(); }
|
||||
|
||||
var documentedFiles = symbols.filter(isaFile); // files that have file-level docs
|
||||
var allFiles = []; // not all files have file-level docs, but we need to list every one
|
||||
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
allFiles.push(new JSDOC.Symbol(files[i], [], "FILE", new JSDOC.DocComment("/** */")));
|
||||
}
|
||||
|
||||
for (var i = 0; i < documentedFiles.length; i++) {
|
||||
var offset = files.indexOf(documentedFiles[i].alias);
|
||||
allFiles[offset] = documentedFiles[i];
|
||||
}
|
||||
|
||||
allFiles = allFiles.sort(makeSortby("name"));
|
||||
|
||||
// output the file index page
|
||||
var filesIndex = fileindexTemplate.process(allFiles);
|
||||
IO.saveFile(publish.conf.outDir, "files"+publish.conf.ext, filesIndex);
|
||||
fileindexTemplate = filesIndex = files = null;
|
||||
}
|
||||
|
||||
|
||||
/** Just the first sentence (up to a full stop). Should not break on dotted variable names. */
|
||||
function summarize(desc) {
|
||||
if (typeof desc != "undefined")
|
||||
return desc.match(/([\w\W]+?\.)[^a-z0-9_$]/i)? RegExp.$1 : desc;
|
||||
}
|
||||
|
||||
/** Make a symbol sorter by some attribute. */
|
||||
function makeSortby(attribute) {
|
||||
return function(a, b) {
|
||||
if (a[attribute] != undefined && b[attribute] != undefined) {
|
||||
a = a[attribute].toLowerCase();
|
||||
b = b[attribute].toLowerCase();
|
||||
if (a < b) return -1;
|
||||
if (a > b) return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Pull in the contents of an external file at the given path. */
|
||||
function include(path) {
|
||||
var path = publish.conf.templatesDir+path;
|
||||
return IO.readFile(path);
|
||||
}
|
||||
|
||||
/** Turn a raw source file into a code-hilited page in the docs. */
|
||||
function makeSrcFile(path, srcDir, name) {
|
||||
if (JSDOC.opt.s) return;
|
||||
|
||||
if (!name) {
|
||||
name = path.replace(/\.\.?[\\\/]/g, "").replace(/[\\\/]/g, "_");
|
||||
name = name.replace(/\:/g, "_");
|
||||
}
|
||||
|
||||
var src = {path: path, name:name, charset: IO.encoding, hilited: ""};
|
||||
|
||||
if (defined(JSDOC.PluginManager)) {
|
||||
JSDOC.PluginManager.run("onPublishSrc", src);
|
||||
}
|
||||
|
||||
if (src.hilited) {
|
||||
IO.saveFile(srcDir, name+publish.conf.ext, src.hilited);
|
||||
}
|
||||
}
|
||||
|
||||
/** Build output for displaying function parameters. */
|
||||
function makeSignature(params) {
|
||||
if (!params) return "()";
|
||||
var signature = "("
|
||||
+
|
||||
params.filter(
|
||||
function($) {
|
||||
return $.name.indexOf(".") == -1; // don't show config params in signature
|
||||
}
|
||||
).map(
|
||||
function($) {
|
||||
return $.name;
|
||||
}
|
||||
).join(", ")
|
||||
+
|
||||
")";
|
||||
return signature;
|
||||
}
|
||||
|
||||
/** Find symbol {@link ...} strings in text and turn into html links */
|
||||
function resolveLinks(str, from) {
|
||||
str = str.replace(/\{@link ([^} ]+) ?\}/gi,
|
||||
function(match, symbolName) {
|
||||
return new Link().toSymbol(symbolName);
|
||||
}
|
||||
);
|
||||
|
||||
return str;
|
||||
}
|
||||
162
jsdoc-template/static/default.css
Normal file
@@ -0,0 +1,162 @@
|
||||
/* default.css */
|
||||
body
|
||||
{
|
||||
font: 12px "Lucida Grande", Tahoma, Arial, Helvetica, sans-serif;
|
||||
width: 800px;
|
||||
}
|
||||
|
||||
.header
|
||||
{
|
||||
clear: both;
|
||||
background-color: #ccc;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
h1
|
||||
{
|
||||
font-size: 150%;
|
||||
font-weight: bold;
|
||||
padding: 0;
|
||||
margin: 1em 0 0 .3em;
|
||||
}
|
||||
|
||||
hr
|
||||
{
|
||||
border: none 0;
|
||||
border-top: 1px solid #7F8FB1;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
pre.code
|
||||
{
|
||||
display: block;
|
||||
padding: 8px;
|
||||
border: 1px dashed #ccc;
|
||||
}
|
||||
|
||||
#index
|
||||
{
|
||||
margin-top: 24px;
|
||||
float: left;
|
||||
width: 160px;
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
background-color: #F3F3F3;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
#content
|
||||
{
|
||||
margin-left: 190px;
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
.classList
|
||||
{
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0 0 0 8px;
|
||||
font-family: arial, sans-serif;
|
||||
font-size: 1em;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.classList li
|
||||
{
|
||||
padding: 0;
|
||||
margin: 0 0 8px 0;
|
||||
}
|
||||
|
||||
.summaryTable { width: 100%; }
|
||||
|
||||
h1.classTitle
|
||||
{
|
||||
font-size:170%;
|
||||
line-height:130%;
|
||||
}
|
||||
|
||||
h2 { font-size: 110%; }
|
||||
caption, div.sectionTitle
|
||||
{
|
||||
background-color: #7F8FB1;
|
||||
color: #fff;
|
||||
font-size:130%;
|
||||
text-align: left;
|
||||
padding: 2px 6px 2px 6px;
|
||||
border: 1px #7F8FB1 solid;
|
||||
}
|
||||
|
||||
div.sectionTitle { margin-bottom: 8px; }
|
||||
.summaryTable thead { display: none; }
|
||||
|
||||
.summaryTable td
|
||||
{
|
||||
vertical-align: top;
|
||||
padding: 4px;
|
||||
border-bottom: 1px #7F8FB1 solid;
|
||||
border-right: 1px #7F8FB1 solid;
|
||||
}
|
||||
|
||||
/*col#summaryAttributes {}*/
|
||||
.summaryTable td.attributes
|
||||
{
|
||||
border-left: 1px #7F8FB1 solid;
|
||||
width: 140px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
td.attributes, .fixedFont
|
||||
{
|
||||
line-height: 15px;
|
||||
color: #002EBE;
|
||||
font-family: "Courier New",Courier,monospace;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.summaryTable td.nameDescription
|
||||
{
|
||||
text-align: left;
|
||||
font-size: 13px;
|
||||
line-height: 15px;
|
||||
}
|
||||
|
||||
.summaryTable td.nameDescription, .description
|
||||
{
|
||||
line-height: 15px;
|
||||
padding: 4px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.summaryTable { margin-bottom: 8px; }
|
||||
|
||||
ul.inheritsList
|
||||
{
|
||||
list-style: square;
|
||||
margin-left: 20px;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.detailList {
|
||||
margin-left: 20px;
|
||||
line-height: 15px;
|
||||
}
|
||||
.detailList dt { margin-left: 20px; }
|
||||
|
||||
.detailList .heading
|
||||
{
|
||||
font-weight: bold;
|
||||
padding-bottom: 6px;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.light, td.attributes, .light a:link, .light a:visited
|
||||
{
|
||||
color: #777;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.fineprint
|
||||
{
|
||||
text-align: right;
|
||||
font-size: 10px;
|
||||
}
|
||||
2
jsdoc-template/static/header.html
Normal file
@@ -0,0 +1,2 @@
|
||||
<div id="header">
|
||||
</div>
|
||||
19
jsdoc-template/static/index.html
Normal file
@@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>Generated Javascript Documentation</title>
|
||||
</head>
|
||||
<frameset cols="20%,80%">
|
||||
<frame src="allclasses-frame.html" name="packageFrame" />
|
||||
<frame src="splash.html" name="classFrame" />
|
||||
<noframes>
|
||||
<body>
|
||||
<p>
|
||||
This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
|
||||
</p>
|
||||
</body>
|
||||
</noframes>
|
||||
</frameset>
|
||||
</html>
|
||||
35
jsdoc-template/symbol.tmpl
Normal file
@@ -0,0 +1,35 @@
|
||||
<symbol alias="{+data.alias+}">
|
||||
<name>{+data.name+}</name>
|
||||
<memberOf>{+data.memberOf+}</memberOf>
|
||||
<isStatic>{+data.isStatic+}</isStatic>
|
||||
<isa>{+data.isa+}</isa>
|
||||
<desc>{+data.desc+}</desc>
|
||||
<classDesc>{+data.classDesc+}</classDesc>
|
||||
|
||||
<methods><for each="method" in="data.methods">
|
||||
<method>
|
||||
<name>{+method.name+}</name>
|
||||
<memberOf>{+method.memberOf+}</memberOf>
|
||||
<isStatic>{+method.isStatic+}</isStatic>
|
||||
<desc>{+method.desc+}</desc>
|
||||
<params><for each="param" in="method.params">
|
||||
<param>
|
||||
<type>{+param.type+}</type>
|
||||
<name>{+param.name+}</name>
|
||||
<desc>{+param.desc+}</desc>
|
||||
<defaultValue>{+param.defaultValue+}</defaultValue>
|
||||
</param></for>
|
||||
</params>
|
||||
</method></for>
|
||||
</methods>
|
||||
|
||||
<properties><for each="property" in="data.properties">
|
||||
<property>
|
||||
<name>{+property.name+}</name>
|
||||
<memberOf>{+property.memberOf+}</memberOf>
|
||||
<isStatic>{+property.isStatic+}</isStatic>
|
||||
<desc>{+property.desc+}</desc>
|
||||
<type>{+property.type+}</type>
|
||||
</property></for>
|
||||
</properties>
|
||||
</symbol>
|
||||
5919
jshint/jshint.js
Executable file
99
jshint/run.js
Normal file
@@ -0,0 +1,99 @@
|
||||
var fs = require("fs");
|
||||
var sys = require("sys");
|
||||
var path = require("path");
|
||||
var JSHINT = require("./jshint").JSHINT;
|
||||
|
||||
// DWF TODO: Standardize this?
|
||||
function isExcluded(fullPath) {
|
||||
var fileName = path.basename(fullPath);
|
||||
var excludeFiles = ["json2.js", "jshint.js", "publish.js", "node_suite.js", "jasmine.js", "jasmine-html.js"];
|
||||
for (var i = 0; i < excludeFiles.length; i++) {
|
||||
if (fileName == excludeFiles[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// DWF TODO: This function could/should be re-written
|
||||
function allJasmineJsFiles(rootDir) {
|
||||
var files = [];
|
||||
fs.readdirSync(rootDir).filter(function(filename) {
|
||||
|
||||
var fullPath = rootDir + "/" + filename;
|
||||
if (fs.statSync(fullPath).isDirectory() && !fullPath.match(/pages/)) {
|
||||
var subDirFiles = allJasmineJsFiles(fullPath);
|
||||
if (subDirFiles.length > 0) {
|
||||
files = files.concat();
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (fullPath.match(/\.js$/) && !isExcluded(fullPath)) {
|
||||
files.push(fullPath);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
var jasmineJsFiles = allJasmineJsFiles(".");
|
||||
jasmineJsFiles.reverse(); //cheap way to do the stuff in src stuff first
|
||||
|
||||
var jasmineJsHintConfig = {
|
||||
|
||||
forin:true, //while it's possible that we could be
|
||||
//considering unwanted prototype methods, mostly
|
||||
//we're doing this because the jsobjects are being
|
||||
//used as maps.
|
||||
|
||||
loopfunc:true //we're fine with functions defined inside loops (setTimeout functions, etc)
|
||||
|
||||
};
|
||||
|
||||
var jasmineGlobals = {};
|
||||
|
||||
|
||||
//jasmine.undefined is a jasmine-ism, let's let it go...
|
||||
function removeJasmineUndefinedErrors(errors) {
|
||||
var keepErrors = [];
|
||||
for (var i = 0; i < errors.length; i++) {
|
||||
if (!(errors[i] &&
|
||||
errors[i].raw &&
|
||||
errors[i].evidence &&
|
||||
( errors[i].evidence.match(/jasmine\.undefined/) ||
|
||||
errors[i].evidence.match(/diz be undefined yo/) )
|
||||
)) {
|
||||
keepErrors.push(errors[i]);
|
||||
}
|
||||
}
|
||||
return keepErrors;
|
||||
}
|
||||
|
||||
(function() {
|
||||
var ansi = {
|
||||
green: '\033[32m',
|
||||
red: '\033[31m',
|
||||
yellow: '\033[33m',
|
||||
none: '\033[0m'
|
||||
};
|
||||
|
||||
for (var i = 0; i < jasmineJsFiles.length; i++) {
|
||||
var file = jasmineJsFiles[i];
|
||||
JSHINT(fs.readFileSync(file, "utf8"), jasmineJsHintConfig);
|
||||
var errors = JSHINT.data().errors || [];
|
||||
errors = removeJasmineUndefinedErrors(errors);
|
||||
|
||||
if (errors.length >= 1) {
|
||||
console.log(ansi.red + "Jasmine JSHint failure: " + ansi.none);
|
||||
console.log(file);
|
||||
console.log(errors);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(ansi.green + "Jasmine JSHint PASSED." + ansi.none);
|
||||
})();
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
/** Console X
|
||||
* http://github.com/deadlyicon/consolex.js
|
||||
*
|
||||
* By Jared Grippe <jared@jaredgrippe.com>
|
||||
*
|
||||
* Copyright (c) 2009 Jared Grippe
|
||||
* Licensed under the MIT license.
|
||||
*
|
||||
* consolex avoids ever having to see javascript bugs in browsers that do not implement the entire
|
||||
* firebug console suit
|
||||
*
|
||||
*/
|
||||
(function(window) {
|
||||
window.console || (window.console = {});
|
||||
|
||||
var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
|
||||
"group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
|
||||
|
||||
function emptyFunction(){}
|
||||
|
||||
for (var i = 0; i < names.length; ++i){
|
||||
window.console[names[i]] || (window.console[names[i]] = emptyFunction);
|
||||
if (typeof window.console[names[i]] !== 'function')
|
||||
window.console[names[i]] = (function(method) {
|
||||
return function(){ return Function.prototype.apply.apply(method, [console,arguments]); };
|
||||
})(window.console[names[i]]);
|
||||
}
|
||||
})(this);
|
||||
36
lib/jasmine-core.rb
Normal file
@@ -0,0 +1,36 @@
|
||||
module Jasmine
|
||||
module Core
|
||||
class << self
|
||||
def path
|
||||
File.join(File.dirname(__FILE__), "jasmine-core")
|
||||
end
|
||||
|
||||
def js_files
|
||||
(["jasmine.js"] + Dir.glob(File.join(path, "*.js"))).map { |f| File.basename(f) }.uniq
|
||||
end
|
||||
|
||||
SPEC_TYPES = ["core", "html", "node"]
|
||||
|
||||
def core_spec_files
|
||||
spec_files("core")
|
||||
end
|
||||
|
||||
def html_spec_files
|
||||
spec_files("html")
|
||||
end
|
||||
|
||||
def node_spec_files
|
||||
spec_files("node")
|
||||
end
|
||||
|
||||
def spec_files(type)
|
||||
raise ArgumentError.new("Unrecognized spec type") unless SPEC_TYPES.include?(type)
|
||||
(Dir.glob(File.join(path, "spec", type, "*.js"))).map { |f| File.join("spec", type, File.basename(f)) }.uniq
|
||||
end
|
||||
|
||||
def css_files
|
||||
Dir.glob(File.join(path, "*.css")).map { |f| File.basename(f) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
54
lib/jasmine-core/example/SpecRunner.html
Normal file
@@ -0,0 +1,54 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Jasmine Spec Runner</title>
|
||||
|
||||
<link rel="shortcut icon" type="image/png" href="lib/jasmine-1.1.0.rc1/jasmine_favicon.png">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="lib/jasmine-1.1.0.rc1/jasmine.css">
|
||||
<script type="text/javascript" src="lib/jasmine-1.1.0.rc1/jasmine.js"></script>
|
||||
<script type="text/javascript" src="lib/jasmine-1.1.0.rc1/jasmine-html.js"></script>
|
||||
|
||||
<!-- include spec files here... -->
|
||||
<script type="text/javascript" src="spec/SpecHelper.js"></script>
|
||||
<script type="text/javascript" src="spec/PlayerSpec.js"></script>
|
||||
|
||||
<!-- include source files here... -->
|
||||
<script type="text/javascript" src="src/Player.js"></script>
|
||||
<script type="text/javascript" src="src/Song.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var jasmineEnv = jasmine.getEnv();
|
||||
jasmineEnv.updateInterval = 1000;
|
||||
|
||||
var trivialReporter = new jasmine.TrivialReporter();
|
||||
|
||||
jasmineEnv.addReporter(trivialReporter);
|
||||
|
||||
jasmineEnv.specFilter = function(spec) {
|
||||
return trivialReporter.specFilter(spec);
|
||||
};
|
||||
|
||||
var currentWindowOnload = window.onload;
|
||||
|
||||
window.onload = function() {
|
||||
if (currentWindowOnload) {
|
||||
currentWindowOnload();
|
||||
}
|
||||
execJasmine();
|
||||
};
|
||||
|
||||
function execJasmine() {
|
||||
jasmineEnv.execute();
|
||||
}
|
||||
|
||||
})();
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
@@ -2,8 +2,8 @@ beforeEach(function() {
|
||||
this.addMatchers({
|
||||
toBePlaying: function(expectedSong) {
|
||||
var player = this.actual;
|
||||
return player.currentlyPlayingSong === expectedSong
|
||||
&& player.isPlaying;
|
||||
return player.currentlyPlayingSong === expectedSong &&
|
||||
player.isPlaying;
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
@@ -34,7 +34,7 @@ jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
|
||||
this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' },
|
||||
this.createDom('div', { className: 'banner' },
|
||||
this.createDom('div', { className: 'logo' },
|
||||
"Jasmine",
|
||||
this.createDom('span', { className: 'title' }, "Jasmine"),
|
||||
this.createDom('span', { className: 'version' }, runner.env.versionString())),
|
||||
this.createDom('div', { className: 'options' },
|
||||
"Show ",
|
||||
@@ -70,16 +70,16 @@ jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
|
||||
this.startedAt = new Date();
|
||||
|
||||
var self = this;
|
||||
showPassed.onchange = function(evt) {
|
||||
if (evt.target.checked) {
|
||||
showPassed.onclick = function(evt) {
|
||||
if (showPassed.checked) {
|
||||
self.outerDiv.className += ' show-passed';
|
||||
} else {
|
||||
self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
|
||||
}
|
||||
};
|
||||
|
||||
showSkipped.onchange = function(evt) {
|
||||
if (evt.target.checked) {
|
||||
showSkipped.onclick = function(evt) {
|
||||
if (showSkipped.checked) {
|
||||
self.outerDiv.className += ' show-skipped';
|
||||
} else {
|
||||
self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
|
||||
@@ -110,7 +110,7 @@ jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
|
||||
jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
|
||||
var results = suite.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.totalCount == 0) { // todo: change this to check results.skipped
|
||||
if (results.totalCount === 0) { // todo: change this to check results.skipped
|
||||
status = 'skipped';
|
||||
}
|
||||
this.suiteDivs[suite.id].className += " " + status;
|
||||
@@ -162,7 +162,13 @@ jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
|
||||
|
||||
jasmine.TrivialReporter.prototype.log = function() {
|
||||
var console = jasmine.getGlobal().console;
|
||||
if (console && console.log) console.log.apply(console, arguments);
|
||||
if (console && console.log) {
|
||||
if (console.log.apply) {
|
||||
console.log.apply(console, arguments);
|
||||
} else {
|
||||
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.getLocation = function() {
|
||||
@@ -177,6 +183,8 @@ jasmine.TrivialReporter.prototype.specFilter = function(spec) {
|
||||
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
|
||||
}
|
||||
|
||||
if (!paramMap["spec"]) return true;
|
||||
return spec.getFullName().indexOf(paramMap["spec"]) == 0;
|
||||
if (!paramMap.spec) {
|
||||
return true;
|
||||
}
|
||||
return spec.getFullName().indexOf(paramMap.spec) === 0;
|
||||
};
|
||||
@@ -1,10 +1,12 @@
|
||||
var isCommonJS = typeof window == "undefined";
|
||||
|
||||
/**
|
||||
* Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
|
||||
*
|
||||
* @namespace
|
||||
*/
|
||||
var jasmine = {};
|
||||
|
||||
if (isCommonJS) exports.jasmine = jasmine;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
@@ -21,11 +23,22 @@ jasmine.unimplementedMethod_ = function() {
|
||||
jasmine.undefined = jasmine.___undefined___;
|
||||
|
||||
/**
|
||||
* Default interval for event loop yields. Small values here may result in slow test running. Zero means no updates until all tests have completed.
|
||||
* Show diagnostic messages in the console if set to true
|
||||
*
|
||||
*/
|
||||
jasmine.VERBOSE = false;
|
||||
|
||||
/**
|
||||
* Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.
|
||||
*
|
||||
*/
|
||||
jasmine.DEFAULT_UPDATE_INTERVAL = 250;
|
||||
|
||||
/**
|
||||
* Default timeout interval in milliseconds for waitsFor() blocks.
|
||||
*/
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
|
||||
|
||||
jasmine.getGlobal = function() {
|
||||
function getGlobal() {
|
||||
return this;
|
||||
@@ -67,7 +80,7 @@ jasmine.MessageResult = function(values) {
|
||||
|
||||
jasmine.MessageResult.prototype.toString = function() {
|
||||
var text = "";
|
||||
for(var i = 0; i < this.values.length; i++) {
|
||||
for (var i = 0; i < this.values.length; i++) {
|
||||
if (i > 0) text += " ";
|
||||
if (jasmine.isString_(this.values[i])) {
|
||||
text += this.values[i];
|
||||
@@ -84,9 +97,10 @@ jasmine.ExpectationResult = function(params) {
|
||||
this.passed_ = params.passed;
|
||||
this.expected = params.expected;
|
||||
this.actual = params.actual;
|
||||
|
||||
this.message = this.passed_ ? 'Passed.' : params.message;
|
||||
this.trace = this.passed_ ? '' : new Error(this.message);
|
||||
|
||||
var trace = (params.trace || new Error(this.message));
|
||||
this.trace = this.passed_ ? '' : trace;
|
||||
};
|
||||
|
||||
jasmine.ExpectationResult.prototype.toString = function () {
|
||||
@@ -101,7 +115,8 @@ jasmine.ExpectationResult.prototype.passed = function () {
|
||||
* Getter for the Jasmine environment. Ensures one gets created
|
||||
*/
|
||||
jasmine.getEnv = function() {
|
||||
return jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
|
||||
var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
|
||||
return env;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -111,7 +126,7 @@ jasmine.getEnv = function() {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
jasmine.isArray_ = function(value) {
|
||||
return jasmine.isA_("Array", value);
|
||||
return jasmine.isA_("Array", value);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -164,7 +179,7 @@ jasmine.pp = function(value) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
jasmine.isDomNode = function(obj) {
|
||||
return obj['nodeType'] > 0;
|
||||
return obj.nodeType > 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -400,7 +415,7 @@ jasmine.isSpy = function(putativeSpy) {
|
||||
* @param {Array} methodNames array of names of methods to make spies
|
||||
*/
|
||||
jasmine.createSpyObj = function(baseName, methodNames) {
|
||||
if (!jasmine.isArray_(methodNames) || methodNames.length == 0) {
|
||||
if (!jasmine.isArray_(methodNames) || methodNames.length === 0) {
|
||||
throw new Error('createSpyObj requires a non-empty array of method names to create spies for');
|
||||
}
|
||||
var obj = {};
|
||||
@@ -438,6 +453,7 @@ jasmine.log = function() {
|
||||
var spyOn = function(obj, methodName) {
|
||||
return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
|
||||
};
|
||||
if (isCommonJS) exports.spyOn = spyOn;
|
||||
|
||||
/**
|
||||
* Creates a Jasmine spec that will be added to the current suite.
|
||||
@@ -455,6 +471,7 @@ var spyOn = function(obj, methodName) {
|
||||
var it = function(desc, func) {
|
||||
return jasmine.getEnv().it(desc, func);
|
||||
};
|
||||
if (isCommonJS) exports.it = it;
|
||||
|
||||
/**
|
||||
* Creates a <em>disabled</em> Jasmine spec.
|
||||
@@ -467,6 +484,7 @@ var it = function(desc, func) {
|
||||
var xit = function(desc, func) {
|
||||
return jasmine.getEnv().xit(desc, func);
|
||||
};
|
||||
if (isCommonJS) exports.xit = xit;
|
||||
|
||||
/**
|
||||
* Starts a chain for a Jasmine expectation.
|
||||
@@ -479,6 +497,7 @@ var xit = function(desc, func) {
|
||||
var expect = function(actual) {
|
||||
return jasmine.getEnv().currentSpec.expect(actual);
|
||||
};
|
||||
if (isCommonJS) exports.expect = expect;
|
||||
|
||||
/**
|
||||
* Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs.
|
||||
@@ -488,25 +507,30 @@ var expect = function(actual) {
|
||||
var runs = function(func) {
|
||||
jasmine.getEnv().currentSpec.runs(func);
|
||||
};
|
||||
if (isCommonJS) exports.runs = runs;
|
||||
|
||||
/**
|
||||
* Waits for a timeout before moving to the next runs()-defined block.
|
||||
* @param {Number} timeout
|
||||
* Waits a fixed time period before moving to the next block.
|
||||
*
|
||||
* @deprecated Use waitsFor() instead
|
||||
* @param {Number} timeout milliseconds to wait
|
||||
*/
|
||||
var waits = function(timeout) {
|
||||
jasmine.getEnv().currentSpec.waits(timeout);
|
||||
};
|
||||
if (isCommonJS) exports.waits = waits;
|
||||
|
||||
/**
|
||||
* Waits for the latchFunction to return true before proceeding to the next runs()-defined block.
|
||||
* Waits for the latchFunction to return true before proceeding to the next block.
|
||||
*
|
||||
* @param {Number} timeout
|
||||
* @param {Function} latchFunction
|
||||
* @param {String} message
|
||||
* @param {String} optional_timeoutMessage
|
||||
* @param {Number} optional_timeout
|
||||
*/
|
||||
var waitsFor = function(timeout, latchFunction, message) {
|
||||
jasmine.getEnv().currentSpec.waitsFor(timeout, latchFunction, message);
|
||||
var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
|
||||
jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);
|
||||
};
|
||||
if (isCommonJS) exports.waitsFor = waitsFor;
|
||||
|
||||
/**
|
||||
* A function that is called before each spec in a suite.
|
||||
@@ -518,6 +542,7 @@ var waitsFor = function(timeout, latchFunction, message) {
|
||||
var beforeEach = function(beforeEachFunction) {
|
||||
jasmine.getEnv().beforeEach(beforeEachFunction);
|
||||
};
|
||||
if (isCommonJS) exports.beforeEach = beforeEach;
|
||||
|
||||
/**
|
||||
* A function that is called after each spec in a suite.
|
||||
@@ -529,6 +554,7 @@ var beforeEach = function(beforeEachFunction) {
|
||||
var afterEach = function(afterEachFunction) {
|
||||
jasmine.getEnv().afterEach(afterEachFunction);
|
||||
};
|
||||
if (isCommonJS) exports.afterEach = afterEach;
|
||||
|
||||
/**
|
||||
* Defines a suite of specifications.
|
||||
@@ -548,6 +574,7 @@ var afterEach = function(afterEachFunction) {
|
||||
var describe = function(description, specDefinitions) {
|
||||
return jasmine.getEnv().describe(description, specDefinitions);
|
||||
};
|
||||
if (isCommonJS) exports.describe = describe;
|
||||
|
||||
/**
|
||||
* Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development.
|
||||
@@ -558,27 +585,35 @@ var describe = function(description, specDefinitions) {
|
||||
var xdescribe = function(description, specDefinitions) {
|
||||
return jasmine.getEnv().xdescribe(description, specDefinitions);
|
||||
};
|
||||
if (isCommonJS) exports.xdescribe = xdescribe;
|
||||
|
||||
|
||||
// Provide the XMLHttpRequest class for IE 5.x-6.x:
|
||||
jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() {
|
||||
try {
|
||||
function tryIt(f) {
|
||||
try {
|
||||
return f();
|
||||
} catch(e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
var xhr = tryIt(function() {
|
||||
return new ActiveXObject("Msxml2.XMLHTTP.6.0");
|
||||
} catch(e) {
|
||||
}
|
||||
try {
|
||||
return new ActiveXObject("Msxml2.XMLHTTP.3.0");
|
||||
} catch(e) {
|
||||
}
|
||||
try {
|
||||
return new ActiveXObject("Msxml2.XMLHTTP");
|
||||
} catch(e) {
|
||||
}
|
||||
try {
|
||||
return new ActiveXObject("Microsoft.XMLHTTP");
|
||||
} catch(e) {
|
||||
}
|
||||
throw new Error("This browser does not support XMLHttpRequest.");
|
||||
}) ||
|
||||
tryIt(function() {
|
||||
return new ActiveXObject("Msxml2.XMLHTTP.3.0");
|
||||
}) ||
|
||||
tryIt(function() {
|
||||
return new ActiveXObject("Msxml2.XMLHTTP");
|
||||
}) ||
|
||||
tryIt(function() {
|
||||
return new ActiveXObject("Microsoft.XMLHTTP");
|
||||
});
|
||||
|
||||
if (!xhr) throw new Error("This browser does not support XMLHttpRequest.");
|
||||
|
||||
return xhr;
|
||||
} : XMLHttpRequest;
|
||||
/**
|
||||
* @namespace
|
||||
@@ -599,7 +634,7 @@ jasmine.util.inherit = function(childClass, parentClass) {
|
||||
var subclass = function() {
|
||||
};
|
||||
subclass.prototype = parentClass.prototype;
|
||||
childClass.prototype = new subclass;
|
||||
childClass.prototype = new subclass();
|
||||
};
|
||||
|
||||
jasmine.util.formatException = function(e) {
|
||||
@@ -660,6 +695,7 @@ jasmine.Env = function() {
|
||||
this.reporter = new jasmine.MultiReporter();
|
||||
|
||||
this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL;
|
||||
this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL;
|
||||
this.lastUpdate = 0;
|
||||
this.specFilter = function() {
|
||||
return true;
|
||||
@@ -699,12 +735,17 @@ jasmine.Env.prototype.version = function () {
|
||||
* @returns string containing jasmine version build info, if set.
|
||||
*/
|
||||
jasmine.Env.prototype.versionString = function() {
|
||||
if (jasmine.version_) {
|
||||
var version = this.version();
|
||||
return version.major + "." + version.minor + "." + version.build + " revision " + version.revision;
|
||||
} else {
|
||||
if (!jasmine.version_) {
|
||||
return "version unknown";
|
||||
}
|
||||
|
||||
var version = this.version();
|
||||
var versionString = version.major + "." + version.minor + "." + version.build;
|
||||
if (version.release_candidate) {
|
||||
versionString += ".rc" + version.release_candidate;
|
||||
}
|
||||
versionString += " revision " + version.revision;
|
||||
return versionString;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -752,14 +793,14 @@ jasmine.Env.prototype.describe = function(description, specDefinitions) {
|
||||
declarationError = e;
|
||||
}
|
||||
|
||||
this.currentSuite = parentSuite;
|
||||
|
||||
if (declarationError) {
|
||||
this.it("encountered a declaration exception", function() {
|
||||
throw declarationError;
|
||||
});
|
||||
}
|
||||
|
||||
this.currentSuite = parentSuite;
|
||||
|
||||
return suite;
|
||||
};
|
||||
|
||||
@@ -820,7 +861,7 @@ jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchVal
|
||||
b.__Jasmine_been_here_before__ = a;
|
||||
|
||||
var hasKey = function(obj, keyName) {
|
||||
return obj != null && obj[keyName] !== jasmine.undefined;
|
||||
return obj !== null && obj[keyName] !== jasmine.undefined;
|
||||
};
|
||||
|
||||
for (var property in b) {
|
||||
@@ -846,7 +887,7 @@ jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchVal
|
||||
|
||||
delete a.__Jasmine_been_here_before__;
|
||||
delete b.__Jasmine_been_here_before__;
|
||||
return (mismatchKeys.length == 0 && mismatchValues.length == 0);
|
||||
return (mismatchKeys.length === 0 && mismatchValues.length === 0);
|
||||
};
|
||||
|
||||
jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
|
||||
@@ -1135,7 +1176,7 @@ jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {
|
||||
message: message
|
||||
});
|
||||
this.spec.addMatcherResult(expectationResult);
|
||||
return result;
|
||||
return jasmine.undefined;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1153,6 +1194,7 @@ jasmine.Matchers.prototype.toBe = function(expected) {
|
||||
/**
|
||||
* toNotBe: compares the actual to the expected using !==
|
||||
* @param expected
|
||||
* @deprecated as of 1.0. Use not.toBe() instead.
|
||||
*/
|
||||
jasmine.Matchers.prototype.toNotBe = function(expected) {
|
||||
return this.actual !== expected;
|
||||
@@ -1170,6 +1212,7 @@ jasmine.Matchers.prototype.toEqual = function(expected) {
|
||||
/**
|
||||
* toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual
|
||||
* @param expected
|
||||
* @deprecated as of 1.0. Use not.toNotEqual() instead.
|
||||
*/
|
||||
jasmine.Matchers.prototype.toNotEqual = function(expected) {
|
||||
return !this.env.equals_(this.actual, expected);
|
||||
@@ -1188,6 +1231,7 @@ jasmine.Matchers.prototype.toMatch = function(expected) {
|
||||
/**
|
||||
* Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch
|
||||
* @param expected
|
||||
* @deprecated as of 1.0. Use not.toMatch() instead.
|
||||
*/
|
||||
jasmine.Matchers.prototype.toNotMatch = function(expected) {
|
||||
return !(new RegExp(expected).test(this.actual));
|
||||
@@ -1230,11 +1274,6 @@ jasmine.Matchers.prototype.toBeFalsy = function() {
|
||||
};
|
||||
|
||||
|
||||
/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */
|
||||
jasmine.Matchers.prototype.wasCalled = function() {
|
||||
return this.toHaveBeenCalled();
|
||||
};
|
||||
|
||||
/**
|
||||
* Matcher that checks to see if the actual, a Jasmine spy, was called.
|
||||
*/
|
||||
@@ -1248,12 +1287,18 @@ jasmine.Matchers.prototype.toHaveBeenCalled = function() {
|
||||
}
|
||||
|
||||
this.message = function() {
|
||||
return "Expected spy " + this.actual.identity + " to have been called.";
|
||||
return [
|
||||
"Expected spy " + this.actual.identity + " to have been called.",
|
||||
"Expected spy " + this.actual.identity + " not to have been called."
|
||||
];
|
||||
};
|
||||
|
||||
return this.actual.wasCalled;
|
||||
};
|
||||
|
||||
/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */
|
||||
jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled;
|
||||
|
||||
/**
|
||||
* Matcher that checks to see if the actual, a Jasmine spy, was not called.
|
||||
*
|
||||
@@ -1269,17 +1314,15 @@ jasmine.Matchers.prototype.wasNotCalled = function() {
|
||||
}
|
||||
|
||||
this.message = function() {
|
||||
return "Expected spy " + this.actual.identity + " to not have been called.";
|
||||
return [
|
||||
"Expected spy " + this.actual.identity + " to not have been called.",
|
||||
"Expected spy " + this.actual.identity + " to have been called."
|
||||
];
|
||||
};
|
||||
|
||||
return !this.actual.wasCalled;
|
||||
};
|
||||
|
||||
/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */
|
||||
jasmine.Matchers.prototype.wasCalledWith = function() {
|
||||
return this.toHaveBeenCalledWith.apply(this, arguments);
|
||||
};
|
||||
|
||||
/**
|
||||
* Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters.
|
||||
*
|
||||
@@ -1292,16 +1335,26 @@ jasmine.Matchers.prototype.toHaveBeenCalledWith = function() {
|
||||
throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
|
||||
}
|
||||
this.message = function() {
|
||||
if (this.actual.callCount == 0) {
|
||||
return "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.";
|
||||
if (this.actual.callCount === 0) {
|
||||
// todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw]
|
||||
return [
|
||||
"Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.",
|
||||
"Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was."
|
||||
];
|
||||
} else {
|
||||
return "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall);
|
||||
return [
|
||||
"Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall),
|
||||
"Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall)
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
return this.env.contains_(this.actual.argsForCall, expectedArgs);
|
||||
};
|
||||
|
||||
/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */
|
||||
jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith;
|
||||
|
||||
/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */
|
||||
jasmine.Matchers.prototype.wasNotCalledWith = function() {
|
||||
var expectedArgs = jasmine.util.argsToArray(arguments);
|
||||
@@ -1310,7 +1363,10 @@ jasmine.Matchers.prototype.wasNotCalledWith = function() {
|
||||
}
|
||||
|
||||
this.message = function() {
|
||||
return "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was";
|
||||
return [
|
||||
"Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was",
|
||||
"Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was"
|
||||
];
|
||||
};
|
||||
|
||||
return !this.env.contains_(this.actual.argsForCall, expectedArgs);
|
||||
@@ -1329,6 +1385,7 @@ jasmine.Matchers.prototype.toContain = function(expected) {
|
||||
* Matcher that checks that the expected item is NOT an element in the actual Array.
|
||||
*
|
||||
* @param {Object} expected
|
||||
* @deprecated as of 1.0. Use not.toNotContain() instead.
|
||||
*/
|
||||
jasmine.Matchers.prototype.toNotContain = function(expected) {
|
||||
return !this.env.contains_(this.actual, expected);
|
||||
@@ -1342,6 +1399,23 @@ jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
|
||||
return this.actual > expected;
|
||||
};
|
||||
|
||||
/**
|
||||
* Matcher that checks that the expected item is equal to the actual item
|
||||
* up to a given level of decimal precision (default 2).
|
||||
*
|
||||
* @param {Number} expected
|
||||
* @param {Number} precision
|
||||
*/
|
||||
jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {
|
||||
if (!(precision === 0)) {
|
||||
precision = precision || 2;
|
||||
}
|
||||
var multiplier = Math.pow(10, precision);
|
||||
var actual = Math.round(this.actual * multiplier);
|
||||
expected = Math.round(expected * multiplier);
|
||||
return expected == actual;
|
||||
};
|
||||
|
||||
/**
|
||||
* Matcher that checks that the expected exception was thrown by the actual.
|
||||
*
|
||||
@@ -1362,9 +1436,11 @@ jasmine.Matchers.prototype.toThrow = function(expected) {
|
||||
result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));
|
||||
}
|
||||
|
||||
var not = this.isNot ? "not " : "";
|
||||
|
||||
this.message = function() {
|
||||
if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
|
||||
return ["Expected function to throw", expected.message || expected, ", but it threw", exception.message || exception].join(' ');
|
||||
return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' ');
|
||||
} else {
|
||||
return "Expected function to throw an exception.";
|
||||
}
|
||||
@@ -1576,7 +1652,8 @@ jasmine.PrettyPrinter.prototype.format = function(value) {
|
||||
jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
|
||||
for (var property in obj) {
|
||||
if (property == '__Jasmine_been_here_before__') continue;
|
||||
fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) != null) : false);
|
||||
fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined &&
|
||||
obj.__lookupGetter__(property) !== null) : false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1644,6 +1721,7 @@ jasmine.Queue = function(env) {
|
||||
this.running = false;
|
||||
this.index = 0;
|
||||
this.offset = 0;
|
||||
this.abort = false;
|
||||
};
|
||||
|
||||
jasmine.Queue.prototype.addBefore = function(block) {
|
||||
@@ -1678,7 +1756,7 @@ jasmine.Queue.prototype.next_ = function() {
|
||||
while (goAgain) {
|
||||
goAgain = false;
|
||||
|
||||
if (self.index < self.blocks.length) {
|
||||
if (self.index < self.blocks.length && !this.abort) {
|
||||
var calledSynchronously = true;
|
||||
var completedSynchronously = false;
|
||||
|
||||
@@ -1688,6 +1766,10 @@ jasmine.Queue.prototype.next_ = function() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.blocks[self.index].abort) {
|
||||
self.abort = true;
|
||||
}
|
||||
|
||||
self.offset = 0;
|
||||
self.index++;
|
||||
|
||||
@@ -1884,14 +1966,46 @@ jasmine.Spec.prototype.expect = function(actual) {
|
||||
return positive;
|
||||
};
|
||||
|
||||
/**
|
||||
* Waits a fixed time period before moving to the next block.
|
||||
*
|
||||
* @deprecated Use waitsFor() instead
|
||||
* @param {Number} timeout milliseconds to wait
|
||||
*/
|
||||
jasmine.Spec.prototype.waits = function(timeout) {
|
||||
var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);
|
||||
this.addToQueue(waitsFunc);
|
||||
return this;
|
||||
};
|
||||
|
||||
jasmine.Spec.prototype.waitsFor = function(timeout, latchFunction, timeoutMessage) {
|
||||
var waitsForFunc = new jasmine.WaitsForBlock(this.env, timeout, latchFunction, timeoutMessage, this);
|
||||
/**
|
||||
* Waits for the latchFunction to return true before proceeding to the next block.
|
||||
*
|
||||
* @param {Function} latchFunction
|
||||
* @param {String} optional_timeoutMessage
|
||||
* @param {Number} optional_timeout
|
||||
*/
|
||||
jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
|
||||
var latchFunction_ = null;
|
||||
var optional_timeoutMessage_ = null;
|
||||
var optional_timeout_ = null;
|
||||
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
var arg = arguments[i];
|
||||
switch (typeof arg) {
|
||||
case 'function':
|
||||
latchFunction_ = arg;
|
||||
break;
|
||||
case 'string':
|
||||
optional_timeoutMessage_ = arg;
|
||||
break;
|
||||
case 'number':
|
||||
optional_timeout_ = arg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this);
|
||||
this.addToQueue(waitsForFunc);
|
||||
return this;
|
||||
};
|
||||
@@ -1899,7 +2013,8 @@ jasmine.Spec.prototype.waitsFor = function(timeout, latchFunction, timeoutMessag
|
||||
jasmine.Spec.prototype.fail = function (e) {
|
||||
var expectationResult = new jasmine.ExpectationResult({
|
||||
passed: false,
|
||||
message: e ? jasmine.util.formatException(e) : 'Exception'
|
||||
message: e ? jasmine.util.formatException(e) : 'Exception',
|
||||
trace: { stack: e.stack }
|
||||
});
|
||||
this.results_.addResult(expectationResult);
|
||||
};
|
||||
@@ -2109,46 +2224,65 @@ jasmine.WaitsBlock = function(env, timeout, spec) {
|
||||
jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
|
||||
|
||||
jasmine.WaitsBlock.prototype.execute = function (onComplete) {
|
||||
this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
|
||||
if (jasmine.VERBOSE) {
|
||||
this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
|
||||
}
|
||||
this.env.setTimeout(function () {
|
||||
onComplete();
|
||||
}, this.timeout);
|
||||
};
|
||||
/**
|
||||
* A block which waits for some condition to become true, with timeout.
|
||||
*
|
||||
* @constructor
|
||||
* @extends jasmine.Block
|
||||
* @param {jasmine.Env} env The Jasmine environment.
|
||||
* @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true.
|
||||
* @param {Function} latchFunction A function which returns true when the desired condition has been met.
|
||||
* @param {String} message The message to display if the desired condition hasn't been met within the given time period.
|
||||
* @param {jasmine.Spec} spec The Jasmine spec.
|
||||
*/
|
||||
jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {
|
||||
this.timeout = timeout;
|
||||
this.timeout = timeout || env.defaultTimeoutInterval;
|
||||
this.latchFunction = latchFunction;
|
||||
this.message = message;
|
||||
this.totalTimeSpentWaitingForLatch = 0;
|
||||
jasmine.Block.call(this, env, null, spec);
|
||||
};
|
||||
|
||||
jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
|
||||
|
||||
jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 100;
|
||||
jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;
|
||||
|
||||
jasmine.WaitsForBlock.prototype.execute = function (onComplete) {
|
||||
var self = this;
|
||||
self.env.reporter.log('>> Jasmine waiting for ' + (self.message || 'something to happen'));
|
||||
jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
|
||||
if (jasmine.VERBOSE) {
|
||||
this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));
|
||||
}
|
||||
var latchFunctionResult;
|
||||
try {
|
||||
latchFunctionResult = self.latchFunction.apply(self.spec);
|
||||
latchFunctionResult = this.latchFunction.apply(this.spec);
|
||||
} catch (e) {
|
||||
self.spec.fail(e);
|
||||
this.spec.fail(e);
|
||||
onComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
if (latchFunctionResult) {
|
||||
onComplete();
|
||||
} else if (self.totalTimeSpentWaitingForLatch >= self.timeout) {
|
||||
var message = 'timed out after ' + self.timeout + ' msec waiting for ' + (self.message || 'something to happen');
|
||||
self.spec.fail({
|
||||
} else if (this.totalTimeSpentWaitingForLatch >= this.timeout) {
|
||||
var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen');
|
||||
this.spec.fail({
|
||||
name: 'timeout',
|
||||
message: message
|
||||
});
|
||||
|
||||
this.abort = true;
|
||||
onComplete();
|
||||
} else {
|
||||
self.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;
|
||||
self.env.setTimeout(function () { self.execute(onComplete); }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
|
||||
this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;
|
||||
var self = this;
|
||||
this.env.setTimeout(function() {
|
||||
self.execute(onComplete);
|
||||
}, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
|
||||
}
|
||||
};
|
||||
// Mock setTimeout, clearTimeout
|
||||
@@ -2334,10 +2468,9 @@ jasmine.getGlobal().clearInterval = function(timeoutKey) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
jasmine.version_= {
|
||||
"major": 0,
|
||||
"minor": 11,
|
||||
"build": 1,
|
||||
"revision": 1277514571
|
||||
"major": 1,
|
||||
"minor": 1,
|
||||
"build": 0,
|
||||
"revision": 1315677058
|
||||
};
|
||||
1
lib/jasmine-core/spec
Symbolic link
@@ -0,0 +1 @@
|
||||
../../spec
|
||||
6
lib/jasmine-core/version.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
module Jasmine
|
||||
module Core
|
||||
VERSION = "1.1.0"
|
||||
end
|
||||
end
|
||||
|
||||
2
pages
451
spec/console/ConsoleReporterSpec.js
Normal file
@@ -0,0 +1,451 @@
|
||||
describe("ConsoleReporter", function() {
|
||||
//keep these literal. otherwise the test loses value as a test.
|
||||
function green(str) {
|
||||
return '\033[32m' + str + '\033[0m';
|
||||
}
|
||||
|
||||
function red(str) {
|
||||
return '\033[31m' + str + '\033[0m';
|
||||
}
|
||||
|
||||
function yellow(str) {
|
||||
return '\033[33m' + str + '\033[0m';
|
||||
}
|
||||
|
||||
function prefixGreen(str) {
|
||||
return '\033[32m' + str;
|
||||
}
|
||||
|
||||
function prefixRed(str) {
|
||||
return '\033[31m' + str;
|
||||
}
|
||||
|
||||
var newline = "\n";
|
||||
|
||||
var passingSpec = {
|
||||
results: function() {
|
||||
return {
|
||||
passed: function() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
failingSpec = {
|
||||
results: function() {
|
||||
return {
|
||||
passed: function() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
skippedSpec = {
|
||||
results: function() {
|
||||
return {skipped: true};
|
||||
}
|
||||
},
|
||||
passingRun = {
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results: function() {
|
||||
return {failedCount: 0, items_: [null, null, null]};
|
||||
}
|
||||
},
|
||||
failingRun = {
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results: function() {
|
||||
return {
|
||||
failedCount: 7, items_: [null, null, null]};
|
||||
}
|
||||
};
|
||||
|
||||
function repeatedlyInvoke(f, times) {
|
||||
for (var i = 0; i < times; i++) f(times + 1);
|
||||
}
|
||||
|
||||
function repeat(thing, times) {
|
||||
var arr = [];
|
||||
for (var i = 0; i < times; i++) arr.push(thing);
|
||||
return arr;
|
||||
}
|
||||
|
||||
function simulateRun(reporter, specResults, suiteResults, finalRunner, startTime, endTime) {
|
||||
reporter.reportRunnerStarting();
|
||||
for (var i = 0; i < specResults.length; i++) {
|
||||
reporter.reportSpecResults(specResults[i]);
|
||||
}
|
||||
for (i = 0; i < suiteResults.length; i++) {
|
||||
reporter.reportSuiteResults(suiteResults[i]);
|
||||
}
|
||||
reporter.runnerStartTime = startTime;
|
||||
reporter.now = function() {
|
||||
return endTime;
|
||||
};
|
||||
reporter.reportRunnerResults(finalRunner);
|
||||
}
|
||||
|
||||
var reporter, out, done;
|
||||
|
||||
beforeEach(function() {
|
||||
out = (function() {
|
||||
var output = "";
|
||||
return {
|
||||
print:function(str) {
|
||||
output += str;
|
||||
},
|
||||
getOutput:function() {
|
||||
return output;
|
||||
},
|
||||
clear: function() {
|
||||
output = "";
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
done = false;
|
||||
reporter = new jasmine.ConsoleReporter(out.print, function(runner) {
|
||||
done = true
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('Integration', function() {
|
||||
it("prints the proper output under a pass scenario - small numbers.", function() {
|
||||
simulateRun(reporter,
|
||||
repeat(passingSpec, 3),
|
||||
[],
|
||||
{
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results:function() {
|
||||
return {
|
||||
items_: [null, null, null],
|
||||
totalCount: 7,
|
||||
failedCount: 0
|
||||
};
|
||||
}
|
||||
},
|
||||
1000,
|
||||
1777
|
||||
);
|
||||
|
||||
var output = out.getOutput();
|
||||
expect(output).toMatch(/^Started/);
|
||||
expect(output).toMatch(/\.\.\./);
|
||||
expect(output).toMatch(/3 specs, 0 failures/);
|
||||
});
|
||||
|
||||
it("prints the proper output under a pass scenario. large numbers.", function() {
|
||||
simulateRun(reporter,
|
||||
repeat(passingSpec, 57),
|
||||
[],
|
||||
{
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results:function() {
|
||||
return {
|
||||
items_: [null, null, null],
|
||||
totalCount: 7,
|
||||
failedCount: 0
|
||||
};
|
||||
}
|
||||
},
|
||||
1000,
|
||||
1777);
|
||||
|
||||
var output = out.getOutput();
|
||||
expect(output).toMatch(/^Started/);
|
||||
expect(output).toMatch(/\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\./);
|
||||
expect(output).toMatch(/3 specs, 0 failures/);
|
||||
});
|
||||
|
||||
it("prints the proper output under a failure scenario.", function() {
|
||||
simulateRun(reporter,
|
||||
[failingSpec, passingSpec, failingSpec],
|
||||
[
|
||||
{description:"The oven",
|
||||
results:function() {
|
||||
return {
|
||||
items_:[
|
||||
{failedCount:2,
|
||||
description:"heats up",
|
||||
items_:[
|
||||
{trace:{stack:"stack trace one\n second line"}},
|
||||
{trace:{stack:"stack trace two"}}
|
||||
]}
|
||||
]
|
||||
};
|
||||
}},
|
||||
{description:"The washing machine",
|
||||
results:function() {
|
||||
return {
|
||||
items_:[
|
||||
{failedCount:2,
|
||||
description:"washes clothes",
|
||||
items_:[
|
||||
{trace:{stack:"stack trace one"}}
|
||||
]}
|
||||
]
|
||||
};
|
||||
}}
|
||||
],
|
||||
{
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results:function() {
|
||||
return {
|
||||
items_: [null, null, null],
|
||||
totalCount: 7,
|
||||
failedCount: 2
|
||||
};
|
||||
}
|
||||
},
|
||||
1000,
|
||||
1777);
|
||||
|
||||
var output = out.getOutput();
|
||||
expect(output).toMatch(/^Started/);
|
||||
expect(output).toMatch(/F\.F/);
|
||||
expect(output).toMatch(/The oven heats up\n stack trace one\n second line\n stack trace two/);
|
||||
expect(output).toMatch(/The washing machine washes clothes\n stack trace one/);
|
||||
expect(output).toMatch(/3 specs, 2 failures/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('When a Jasmine environment executes', function() {
|
||||
beforeEach(function() {
|
||||
reporter.reportRunnerStarting();
|
||||
});
|
||||
|
||||
it("should print 'Started' to the console", function() {
|
||||
expect(out.getOutput()).toEqual("Started" + newline);
|
||||
});
|
||||
|
||||
describe('when a spec reports', function() {
|
||||
beforeEach(function() {
|
||||
out.clear();
|
||||
});
|
||||
|
||||
it("prints a green dot if the spec passes", function() {
|
||||
reporter.reportSpecResults(passingSpec);
|
||||
|
||||
expect(out.getOutput()).toMatch(/\./);
|
||||
});
|
||||
|
||||
it("prints a red dot if the spec fails", function() {
|
||||
reporter.reportSpecResults(failingSpec);
|
||||
|
||||
expect(out.getOutput()).toMatch(/F/);
|
||||
});
|
||||
|
||||
it("prints a yellow star if the spec was skipped", function() {
|
||||
reporter.reportSpecResults(skippedSpec);
|
||||
|
||||
expect(out.getOutput()).toMatch(/\*/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when a suite reports', function() {
|
||||
var emptyResults;
|
||||
beforeEach(function() {
|
||||
emptyResults = function() {
|
||||
return {
|
||||
items_:[]
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
it("remembers suite results", function() {
|
||||
reporter.reportSuiteResults({description: "Oven", results: emptyResults});
|
||||
reporter.reportSuiteResults({description: "Mixer", results: emptyResults});
|
||||
|
||||
expect(reporter.suiteResults[0].description).toEqual('Oven');
|
||||
expect(reporter.suiteResults[1].description).toEqual('Mixer');
|
||||
});
|
||||
|
||||
it("creates a description out of the current suite and any parent suites", function() {
|
||||
var grandparentSuite = {
|
||||
description: "My house",
|
||||
results: emptyResults
|
||||
};
|
||||
var parentSuite = {
|
||||
description: "kitchen",
|
||||
parentSuite: grandparentSuite,
|
||||
results: emptyResults
|
||||
};
|
||||
reporter.reportSuiteResults({ description: "oven", parentSuite: parentSuite, results: emptyResults });
|
||||
|
||||
expect(reporter.suiteResults[0].description).toEqual("My house kitchen oven");
|
||||
});
|
||||
|
||||
it("gathers failing spec results from the suite - the spec must have a description.", function() {
|
||||
reporter.reportSuiteResults({description:"Oven",
|
||||
results: function() {
|
||||
return {
|
||||
items_:[
|
||||
{ failedCount: 0, description: "specOne" },
|
||||
{ failedCount: 99, description: "specTwo" },
|
||||
{ failedCount: 0, description: "specThree" },
|
||||
{ failedCount: 88, description: "specFour" },
|
||||
{ failedCount: 3 }
|
||||
]
|
||||
};
|
||||
}});
|
||||
|
||||
expect(reporter.suiteResults[0].failedSpecResults).
|
||||
toEqual([
|
||||
{ failedCount: 99, description: "specTwo" },
|
||||
{ failedCount: 88, description: "specFour" }
|
||||
]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('and finishes', function() {
|
||||
|
||||
describe('when reporting spec failure information', function() {
|
||||
|
||||
it("prints suite and spec descriptions together as a sentence", function() {
|
||||
reporter.suiteResults = [
|
||||
{description:"The oven", failedSpecResults:[
|
||||
{description:"heats up", items_:[]},
|
||||
{description:"cleans itself", items_:[]}
|
||||
]},
|
||||
{description:"The mixer", failedSpecResults:[
|
||||
{description:"blends things together", items_:[]}
|
||||
]}
|
||||
];
|
||||
|
||||
reporter.reportRunnerResults(failingRun);
|
||||
|
||||
expect(out.getOutput()).toContain("The oven heats up");
|
||||
expect(out.getOutput()).toContain("The oven cleans itself");
|
||||
expect(out.getOutput()).toContain("The mixer blends things together");
|
||||
});
|
||||
|
||||
it("prints stack trace of spec failure", function() {
|
||||
reporter.suiteResults = [
|
||||
{description:"The oven", failedSpecResults:[
|
||||
{description:"heats up",
|
||||
items_:[
|
||||
{trace:{stack:"stack trace one"}},
|
||||
{trace:{stack:"stack trace two"}}
|
||||
]}
|
||||
]}
|
||||
];
|
||||
|
||||
reporter.reportRunnerResults(failingRun);
|
||||
|
||||
expect(out.getOutput()).toContain("The oven heats up");
|
||||
expect(out.getOutput()).toContain("stack trace one");
|
||||
expect(out.getOutput()).toContain("stack trace two");
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('when reporting the execution time', function() {
|
||||
|
||||
it("prints the full finished message", function() {
|
||||
reporter.now = function() {
|
||||
return 1000;
|
||||
};
|
||||
reporter.reportRunnerStarting();
|
||||
reporter.now = function() {
|
||||
return 1777;
|
||||
};
|
||||
reporter.reportRunnerResults(failingRun);
|
||||
expect(out.getOutput()).toContain("Finished in 0.777 seconds");
|
||||
});
|
||||
|
||||
it("prints round time numbers correctly", function() {
|
||||
function run(startTime, endTime) {
|
||||
out.clear();
|
||||
reporter.runnerStartTime = startTime;
|
||||
reporter.now = function() {
|
||||
return endTime;
|
||||
};
|
||||
reporter.reportRunnerResults(passingRun);
|
||||
}
|
||||
|
||||
run(1000, 11000);
|
||||
expect(out.getOutput()).toContain("10 seconds");
|
||||
|
||||
run(1000, 2000);
|
||||
expect(out.getOutput()).toContain("1 seconds");
|
||||
|
||||
run(1000, 1100);
|
||||
expect(out.getOutput()).toContain("0.1 seconds");
|
||||
|
||||
run(1000, 1010);
|
||||
expect(out.getOutput()).toContain("0.01 seconds");
|
||||
|
||||
run(1000, 1001);
|
||||
expect(out.getOutput()).toContain("0.001 seconds");
|
||||
});
|
||||
});
|
||||
|
||||
describe("when reporting the results summary", function() {
|
||||
it("prints statistics in green if there were no failures", function() {
|
||||
reporter.reportRunnerResults({
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results:function() {
|
||||
return {items_: [null, null, null], totalCount: 7, failedCount: 0};
|
||||
}
|
||||
});
|
||||
expect(out.getOutput()).
|
||||
toContain("3 specs, 0 failures");
|
||||
});
|
||||
|
||||
it("prints statistics in red if there was a failure", function() {
|
||||
reporter.reportRunnerResults({
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results:function() {
|
||||
return {items_: [null, null, null], totalCount: 7, failedCount: 3};
|
||||
}
|
||||
});
|
||||
expect(out.getOutput()).
|
||||
toContain("3 specs, 3 failures");
|
||||
});
|
||||
|
||||
it("handles pluralization with 1's ones appropriately", function() {
|
||||
reporter.reportRunnerResults({
|
||||
specs: function() {
|
||||
return [null];
|
||||
},
|
||||
results:function() {
|
||||
return {items_: [null], totalCount: 1, failedCount: 1};
|
||||
}
|
||||
});
|
||||
expect(out.getOutput()).
|
||||
toContain("1 spec, 1 failure");
|
||||
});
|
||||
});
|
||||
|
||||
describe("done callback", function() {
|
||||
it("calls back when done", function() {
|
||||
expect(done).toBeFalsy();
|
||||
reporter.reportRunnerResults({
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results:function() {
|
||||
return {items_: [null, null, null], totalCount: 7, failedCount: 0};
|
||||
}
|
||||
});
|
||||
expect(done).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -11,15 +11,21 @@ describe("Custom Matchers", function() {
|
||||
var spec1, spec2, spec1Matcher, spec2Matcher;
|
||||
var suite = env.describe('some suite', function() {
|
||||
env.beforeEach(function() {
|
||||
this.addMatchers({ matcherForSuite: function(expected) {
|
||||
return "matcherForSuite: actual: " + this.actual + "; expected: " + expected;
|
||||
} });
|
||||
this.addMatchers({
|
||||
matcherForSuite: function(expected) {
|
||||
this.message = "matcherForSuite: actual: " + this.actual + "; expected: " + expected;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
spec1 = env.it('spec with an expectation').runs(function () {
|
||||
this.addMatchers({ matcherForSpec: function(expected) {
|
||||
return "matcherForSpec: actual: " + this.actual + "; expected: " + expected;
|
||||
} });
|
||||
this.addMatchers({
|
||||
matcherForSpec: function(expected) {
|
||||
this.message = "matcherForSpec: actual: " + this.actual + "; expected: " + expected;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
spec1Matcher = this.expect("xxx");
|
||||
});
|
||||
|
||||
@@ -30,10 +36,13 @@ describe("Custom Matchers", function() {
|
||||
|
||||
suite.execute();
|
||||
|
||||
expect(spec1Matcher.matcherForSuite("expected")).toEqual("matcherForSuite: actual: xxx; expected: expected");
|
||||
expect(spec1Matcher.matcherForSpec("expected")).toEqual("matcherForSpec: actual: xxx; expected: expected");
|
||||
spec1Matcher.matcherForSuite("expected");
|
||||
expect(spec1Matcher.message).toEqual("matcherForSuite: actual: xxx; expected: expected");
|
||||
spec1Matcher.matcherForSpec("expected");
|
||||
expect(spec1Matcher.message).toEqual("matcherForSpec: actual: xxx; expected: expected");
|
||||
|
||||
expect(spec2Matcher.matcherForSuite("expected")).toEqual("matcherForSuite: actual: yyy; expected: expected");
|
||||
spec2Matcher.matcherForSuite("expected");
|
||||
expect(spec2Matcher.message).toEqual("matcherForSuite: actual: yyy; expected: expected");
|
||||
expect(spec2Matcher.matcherForSpec).toBe(jasmine.undefined);
|
||||
});
|
||||
|
||||
@@ -64,9 +64,10 @@ describe("jasmine.Env", function() {
|
||||
"major": 1,
|
||||
"minor": 9,
|
||||
"build": 7,
|
||||
"release_candidate": "1",
|
||||
"revision": 8
|
||||
};
|
||||
expect(env.versionString()).toEqual("1.9.7 revision 8");
|
||||
expect(env.versionString()).toEqual("1.9.7.rc1 revision 8");
|
||||
});
|
||||
|
||||
it("should return a nice string when version is unknown", function() {
|
||||
@@ -108,7 +109,7 @@ describe("jasmine.Env", function() {
|
||||
|
||||
it("should give custom equality testers precedence", function() {
|
||||
expect(env.equals_('abc', 'abc')).toBeFalsy();
|
||||
var o = new Object();
|
||||
var o = {};
|
||||
expect(env.equals_(o, o)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
@@ -3,7 +3,7 @@ describe('Exceptions:', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmine.Env();
|
||||
env.updateInterval = 0;
|
||||
env.updateInterval = 0;
|
||||
});
|
||||
|
||||
it('jasmine.formatException formats Firefox exception messages as expected', function() {
|
||||
@@ -89,9 +89,9 @@ describe('Exceptions:', function() {
|
||||
expect(blockResults[0].message).toMatch(/fake error 1/);
|
||||
|
||||
expect(specResults[1].passed()).toEqual(false);
|
||||
var blockResults = specResults[1].getItems();
|
||||
blockResults = specResults[1].getItems();
|
||||
expect(blockResults[0].passed()).toEqual(false);
|
||||
expect(blockResults[0].message).toMatch(/fake error 2/),
|
||||
expect(blockResults[0].message).toMatch(/fake error 2/);
|
||||
expect(blockResults[1].passed()).toEqual(true);
|
||||
|
||||
expect(specResults[2].passed()).toEqual(true);
|
||||
@@ -101,7 +101,49 @@ describe('Exceptions:', function() {
|
||||
expect(blockResults[0].message).toMatch(/fake error 3/);
|
||||
|
||||
expect(specResults[4].passed()).toEqual(true);
|
||||
|
||||
});
|
||||
|
||||
|
||||
it("should handle exceptions thrown directly in top-level describe blocks and continue", function () {
|
||||
var suite = env.describe("a top level describe block that throws an exception", function () {
|
||||
env.it("is a test that should pass", function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
|
||||
throw new Error("top level error");
|
||||
});
|
||||
|
||||
suite.execute();
|
||||
var suiteResults = suite.results();
|
||||
var specResults = suiteResults.getItems();
|
||||
|
||||
expect(suiteResults.passed()).toEqual(false);
|
||||
expect(specResults.length).toEqual(2);
|
||||
|
||||
expect(specResults[1].description).toMatch(/encountered a declaration exception/);
|
||||
});
|
||||
|
||||
it("should handle exceptions thrown directly in nested describe blocks and continue", function () {
|
||||
var suite = env.describe("a top level describe", function () {
|
||||
env.describe("a mid-level describe that throws an exception", function () {
|
||||
env.it("is a test that should pass", function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
|
||||
throw new Error("a mid-level error");
|
||||
});
|
||||
});
|
||||
|
||||
suite.execute();
|
||||
var suiteResults = suite.results();
|
||||
var specResults = suiteResults.getItems();
|
||||
|
||||
expect(suiteResults.passed()).toEqual(false);
|
||||
expect(specResults.length).toEqual(1);
|
||||
|
||||
var nestedSpecResults = specResults[0].getItems();
|
||||
|
||||
expect(nestedSpecResults.length).toEqual(2);
|
||||
expect(nestedSpecResults[1].description).toMatch(/encountered a declaration exception/);
|
||||
});
|
||||
});
|
||||
@@ -21,7 +21,7 @@ describe('jasmine.jsApiReporter', function() {
|
||||
nestedSuite = env.describe("nested suite", function() {
|
||||
nestedSpec = env.it("nested spec", function() {
|
||||
expect(true).toEqual(true);
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
spec3 = env.it("spec 3", function() {
|
||||
@@ -10,6 +10,15 @@ describe("jasmine.Matchers", function() {
|
||||
});
|
||||
});
|
||||
spyOn(spec, 'addMatcherResult');
|
||||
|
||||
this.addMatchers({
|
||||
toPass: function() {
|
||||
return lastResult().passed();
|
||||
},
|
||||
toFail: function() {
|
||||
return !lastResult().passed();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function match(value) {
|
||||
@@ -20,10 +29,19 @@ describe("jasmine.Matchers", function() {
|
||||
return spec.addMatcherResult.mostRecentCall.args[0];
|
||||
}
|
||||
|
||||
it("toEqual with primitives, objects, dates, etc.", function() {
|
||||
expect(match(true).toEqual(true)).toEqual(true);
|
||||
function catchException(fn) {
|
||||
try {
|
||||
fn.call();
|
||||
} catch (e) {
|
||||
return e;
|
||||
}
|
||||
throw new Error("expected function to throw an exception");
|
||||
}
|
||||
|
||||
expect(match({foo:'bar'}).toEqual(null)).toEqual(false);
|
||||
it("toEqual with primitives, objects, dates, etc.", function() {
|
||||
expect(match(true).toEqual(true)).toPass();
|
||||
|
||||
expect(match({foo:'bar'}).toEqual(null)).toFail();
|
||||
|
||||
var functionA = function() {
|
||||
return 'hi';
|
||||
@@ -31,39 +49,32 @@ describe("jasmine.Matchers", function() {
|
||||
var functionB = function() {
|
||||
return 'hi';
|
||||
};
|
||||
expect(match({foo:functionA}).toEqual({foo:functionB})).toEqual(false);
|
||||
expect(match({foo:functionA}).toEqual({foo:functionA})).toEqual(true);
|
||||
expect(match({foo:functionA}).toEqual({foo:functionB})).toFail();
|
||||
expect(match({foo:functionA}).toEqual({foo:functionA})).toPass();
|
||||
|
||||
expect((match(false).toEqual(true))).toEqual(false);
|
||||
expect((match(false).toEqual(true))).toFail();
|
||||
|
||||
var circularGraph = {};
|
||||
circularGraph.referenceToSelf = circularGraph;
|
||||
expect((match(circularGraph).toEqual(circularGraph))).toEqual(true);
|
||||
expect((match(circularGraph).toEqual(circularGraph))).toPass();
|
||||
|
||||
expect((match(new Date(2008, 1, 3, 15, 17, 19, 1234)).toEqual(new Date(2009, 1, 3, 15, 17, 19, 1234)))).toEqual(false);
|
||||
expect((match(new Date(2008, 1, 3, 15, 17, 19, 1234)).toEqual(new Date(2008, 1, 3, 15, 17, 19, 1234)))).toEqual(true);
|
||||
expect((match(new Date(2008, 1, 3, 15, 17, 19, 1234)).toEqual(new Date(2009, 1, 3, 15, 17, 19, 1234)))).toFail();
|
||||
expect((match(new Date(2008, 1, 3, 15, 17, 19, 1234)).toEqual(new Date(2008, 1, 3, 15, 17, 19, 1234)))).toPass();
|
||||
|
||||
|
||||
expect(match(true).toNotEqual(false)).toEqual(true);
|
||||
expect((match(true).toNotEqual(true))).toEqual(false);
|
||||
expect(match(true).toNotEqual(false)).toPass();
|
||||
expect((match(true).toNotEqual(true))).toFail();
|
||||
|
||||
expect((match(['a', 'b']).toEqual(['a', jasmine.undefined]))).toEqual(false);
|
||||
expect((match(['a', 'b']).toEqual(['a', 'b', jasmine.undefined]))).toEqual(false);
|
||||
expect((match(['a', 'b']).toEqual(['a', jasmine.undefined]))).toFail();
|
||||
expect((match(['a', 'b']).toEqual(['a', 'b', jasmine.undefined]))).toFail();
|
||||
|
||||
expect((match(new String("cat")).toEqual("cat"))).toBe(true);
|
||||
expect((match(new String("cat")).toNotEqual("cat"))).toBe(false);
|
||||
expect((match("cat").toEqual("cat"))).toPass();
|
||||
expect((match("cat").toNotEqual("cat"))).toFail();
|
||||
|
||||
expect((match(new Number(5)).toEqual(5))).toBe(true);
|
||||
expect((match(new Number('5')).toEqual(5))).toBe(true);
|
||||
expect((match(new Number(5)).toNotEqual(5))).toBe(false);
|
||||
expect((match(new Number('5')).toNotEqual(5))).toBe(false);
|
||||
});
|
||||
|
||||
it("toEqual with DOM nodes", function() {
|
||||
var nodeA = document.createElement('div');
|
||||
var nodeB = document.createElement('div');
|
||||
expect((match(nodeA).toEqual(nodeA))).toEqual(true);
|
||||
expect((match(nodeA).toEqual(nodeB))).toEqual(false);
|
||||
expect((match(5).toEqual(5))).toPass();
|
||||
expect((match(parseInt('5', 10)).toEqual(5))).toPass();
|
||||
expect((match(5).toNotEqual(5))).toFail();
|
||||
expect((match(parseInt('5', 10)).toNotEqual(5))).toFail();
|
||||
});
|
||||
|
||||
it("toEqual to build an Expectation Result", function() {
|
||||
@@ -75,7 +86,7 @@ describe("jasmine.Matchers", function() {
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toEqual");
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch(jasmine.pp(expected));
|
||||
expect(result.expected).toEqual(expected);
|
||||
@@ -90,7 +101,7 @@ describe("jasmine.Matchers", function() {
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toNotEqual");
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(str));
|
||||
expect(result.message).toMatch('not');
|
||||
expect(result.expected).toEqual(str);
|
||||
@@ -102,12 +113,12 @@ describe("jasmine.Matchers", function() {
|
||||
var b = {};
|
||||
//noinspection UnnecessaryLocalVariableJS
|
||||
var c = a;
|
||||
expect((match(a).toBe(b))).toEqual(false);
|
||||
expect((match(a).toBe(a))).toEqual(true);
|
||||
expect((match(a).toBe(c))).toEqual(true);
|
||||
expect((match(a).toNotBe(b))).toEqual(true);
|
||||
expect((match(a).toNotBe(a))).toEqual(false);
|
||||
expect((match(a).toNotBe(c))).toEqual(false);
|
||||
expect((match(a).toBe(b))).toFail();
|
||||
expect((match(a).toBe(a))).toPass();
|
||||
expect((match(a).toBe(c))).toPass();
|
||||
expect((match(a).toNotBe(b))).toPass();
|
||||
expect((match(a).toNotBe(a))).toFail();
|
||||
expect((match(a).toNotBe(c))).toFail();
|
||||
});
|
||||
|
||||
it("toBe to build an ExpectationResult", function() {
|
||||
@@ -119,7 +130,7 @@ describe("jasmine.Matchers", function() {
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBe");
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch(jasmine.pp(expected));
|
||||
expect(result.expected).toEqual(expected);
|
||||
@@ -134,24 +145,24 @@ describe("jasmine.Matchers", function() {
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toNotBe");
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(str);
|
||||
expect(result.expected).toEqual(str);
|
||||
expect(result.actual).toEqual(str);
|
||||
});
|
||||
|
||||
it("toMatch and #toNotMatch should perform regular expression matching on strings", function() {
|
||||
expect((match('foobarbel').toMatch(/bar/))).toEqual(true);
|
||||
expect((match('foobazbel').toMatch(/bar/))).toEqual(false);
|
||||
expect((match('foobarbel').toMatch(/bar/))).toPass();
|
||||
expect((match('foobazbel').toMatch(/bar/))).toFail();
|
||||
|
||||
expect((match('foobarbel').toMatch("bar"))).toEqual(true);
|
||||
expect((match('foobazbel').toMatch("bar"))).toEqual(false);
|
||||
expect((match('foobarbel').toMatch("bar"))).toPass();
|
||||
expect((match('foobazbel').toMatch("bar"))).toFail();
|
||||
|
||||
expect((match('foobarbel').toNotMatch(/bar/))).toEqual(false);
|
||||
expect((match('foobazbel').toNotMatch(/bar/))).toEqual(true);
|
||||
expect((match('foobarbel').toNotMatch(/bar/))).toFail();
|
||||
expect((match('foobazbel').toNotMatch(/bar/))).toPass();
|
||||
|
||||
expect((match('foobarbel').toNotMatch("bar"))).toEqual(false);
|
||||
expect((match('foobazbel').toNotMatch("bar"))).toEqual(true);
|
||||
expect((match('foobarbel').toNotMatch("bar"))).toFail();
|
||||
expect((match('foobazbel').toNotMatch("bar"))).toPass();
|
||||
});
|
||||
|
||||
it("toMatch w/ RegExp to build an ExpectationResult", function() {
|
||||
@@ -163,7 +174,7 @@ describe("jasmine.Matchers", function() {
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toMatch");
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch(expected.toString());
|
||||
expect(result.expected).toEqual(expected);
|
||||
@@ -179,7 +190,7 @@ describe("jasmine.Matchers", function() {
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toMatch");
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toEqual("Expected 'a' to match 'b'.");
|
||||
expect(result.expected).toEqual(expected);
|
||||
expect(result.actual).toEqual(actual);
|
||||
@@ -194,7 +205,7 @@ describe("jasmine.Matchers", function() {
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toNotMatch");
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toEqual("Expected 'a' to not match /a/.");
|
||||
expect(result.expected).toEqual(expected);
|
||||
expect(result.actual).toEqual(actual);
|
||||
@@ -208,15 +219,15 @@ describe("jasmine.Matchers", function() {
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toNotMatch");
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toEqual("Expected 'a' to not match 'a'.");
|
||||
expect(result.expected).toEqual(str);
|
||||
expect(result.actual).toEqual(str);
|
||||
});
|
||||
|
||||
it("toBeDefined", function() {
|
||||
expect(match('foo').toBeDefined()).toEqual(true);
|
||||
expect(match(jasmine.undefined).toBeDefined()).toEqual(false);
|
||||
expect(match('foo').toBeDefined()).toPass();
|
||||
expect(match(jasmine.undefined).toBeDefined()).toFail();
|
||||
});
|
||||
|
||||
it("toBeDefined to build an ExpectationResult", function() {
|
||||
@@ -226,20 +237,20 @@ describe("jasmine.Matchers", function() {
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeDefined");
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toEqual('Expected undefined to be defined.');
|
||||
expect(result.actual).toEqual(jasmine.undefined);
|
||||
});
|
||||
|
||||
it("toBeUndefined", function() {
|
||||
expect(match('foo').toBeUndefined()).toEqual(false);
|
||||
expect(match(jasmine.undefined).toBeUndefined()).toEqual(true);
|
||||
expect(match('foo').toBeUndefined()).toFail();
|
||||
expect(match(jasmine.undefined).toBeUndefined()).toPass();
|
||||
});
|
||||
|
||||
it("toBeNull", function() {
|
||||
expect(match(null).toBeNull()).toEqual(true);
|
||||
expect(match(jasmine.undefined).toBeNull()).toEqual(false);
|
||||
expect(match("foo").toBeNull()).toEqual(false);
|
||||
expect(match(null).toBeNull()).toPass();
|
||||
expect(match(jasmine.undefined).toBeNull()).toFail();
|
||||
expect(match("foo").toBeNull()).toFail();
|
||||
});
|
||||
|
||||
it("toBeNull w/ String to build an ExpectationResult", function() {
|
||||
@@ -250,7 +261,7 @@ describe("jasmine.Matchers", function() {
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeNull");
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch('null');
|
||||
expect(result.actual).toEqual(actual);
|
||||
@@ -264,18 +275,18 @@ describe("jasmine.Matchers", function() {
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeNull");
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch('null');
|
||||
expect(result.actual).toEqual(actual);
|
||||
});
|
||||
|
||||
it("toBeFalsy", function() {
|
||||
expect(match(false).toBeFalsy()).toEqual(true);
|
||||
expect(match(true).toBeFalsy()).toEqual(false);
|
||||
expect(match(jasmine.undefined).toBeFalsy()).toEqual(true);
|
||||
expect(match(0).toBeFalsy()).toEqual(true);
|
||||
expect(match("").toBeFalsy()).toEqual(true);
|
||||
expect(match(false).toBeFalsy()).toPass();
|
||||
expect(match(true).toBeFalsy()).toFail();
|
||||
expect(match(jasmine.undefined).toBeFalsy()).toPass();
|
||||
expect(match(0).toBeFalsy()).toPass();
|
||||
expect(match("").toBeFalsy()).toPass();
|
||||
});
|
||||
|
||||
it("toBeFalsy to build an ExpectationResult", function() {
|
||||
@@ -286,21 +297,21 @@ describe("jasmine.Matchers", function() {
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeFalsy");
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch('falsy');
|
||||
expect(result.actual).toEqual(actual);
|
||||
});
|
||||
|
||||
it("toBeTruthy", function() {
|
||||
expect(match(false).toBeTruthy()).toEqual(false);
|
||||
expect(match(true).toBeTruthy()).toEqual(true);
|
||||
expect(match(jasmine.undefined).toBeTruthy()).toEqual(false);
|
||||
expect(match(0).toBeTruthy()).toEqual(false);
|
||||
expect(match("").toBeTruthy()).toEqual(false);
|
||||
expect(match("hi").toBeTruthy()).toEqual(true);
|
||||
expect(match(5).toBeTruthy()).toEqual(true);
|
||||
expect(match({foo: 1}).toBeTruthy()).toEqual(true);
|
||||
expect(match(false).toBeTruthy()).toFail();
|
||||
expect(match(true).toBeTruthy()).toPass();
|
||||
expect(match(jasmine.undefined).toBeTruthy()).toFail();
|
||||
expect(match(0).toBeTruthy()).toFail();
|
||||
expect(match("").toBeTruthy()).toFail();
|
||||
expect(match("hi").toBeTruthy()).toPass();
|
||||
expect(match(5).toBeTruthy()).toPass();
|
||||
expect(match({foo: 1}).toBeTruthy()).toPass();
|
||||
});
|
||||
|
||||
it("toBeTruthy to build an ExpectationResult", function() {
|
||||
@@ -310,69 +321,71 @@ describe("jasmine.Matchers", function() {
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeTruthy");
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toEqual("Expected false to be truthy.");
|
||||
expect(result.actual).toEqual(false);
|
||||
expect(result.actual).toFail();
|
||||
});
|
||||
|
||||
it("toEqual", function() {
|
||||
expect(match(jasmine.undefined).toEqual(jasmine.undefined)).toEqual(true);
|
||||
expect(match({foo:'bar'}).toEqual({foo:'bar'})).toEqual(true);
|
||||
expect(match("foo").toEqual({bar: jasmine.undefined})).toEqual(false);
|
||||
expect(match({foo: jasmine.undefined}).toEqual("goo")).toEqual(false);
|
||||
expect(match({foo: {bar :jasmine.undefined}}).toEqual("goo")).toEqual(false);
|
||||
expect(match(jasmine.undefined).toEqual(jasmine.undefined)).toPass();
|
||||
expect(match({foo:'bar'}).toEqual({foo:'bar'})).toPass();
|
||||
expect(match("foo").toEqual({bar: jasmine.undefined})).toFail();
|
||||
expect(match({foo: jasmine.undefined}).toEqual("goo")).toFail();
|
||||
expect(match({foo: {bar :jasmine.undefined}}).toEqual("goo")).toFail();
|
||||
});
|
||||
|
||||
it("toEqual with jasmine.any()", function() {
|
||||
expect(match("foo").toEqual(jasmine.any(String))).toEqual(true);
|
||||
expect(match(3).toEqual(jasmine.any(Number))).toEqual(true);
|
||||
expect(match("foo").toEqual(jasmine.any(Function))).toEqual(false);
|
||||
expect(match("foo").toEqual(jasmine.any(Object))).toEqual(false);
|
||||
expect(match({someObj:'foo'}).toEqual(jasmine.any(Object))).toEqual(true);
|
||||
expect(match({someObj:'foo'}).toEqual(jasmine.any(Function))).toEqual(false);
|
||||
expect(match(function() {
|
||||
}).toEqual(jasmine.any(Object))).toEqual(false);
|
||||
expect(match(["foo", "goo"]).toEqual(["foo", jasmine.any(String)])).toEqual(true);
|
||||
expect(match(function() {
|
||||
}).toEqual(jasmine.any(Function))).toEqual(true);
|
||||
expect(match("foo").toEqual(jasmine.any(String))).toPass();
|
||||
expect(match(3).toEqual(jasmine.any(Number))).toPass();
|
||||
expect(match("foo").toEqual(jasmine.any(Function))).toFail();
|
||||
expect(match("foo").toEqual(jasmine.any(Object))).toFail();
|
||||
expect(match({someObj:'foo'}).toEqual(jasmine.any(Object))).toPass();
|
||||
expect(match({someObj:'foo'}).toEqual(jasmine.any(Function))).toFail();
|
||||
expect(match(
|
||||
function() {
|
||||
}).toEqual(jasmine.any(Object))).toFail();
|
||||
expect(match(["foo", "goo"]).toEqual(["foo", jasmine.any(String)])).toPass();
|
||||
expect(match(
|
||||
function() {
|
||||
}).toEqual(jasmine.any(Function))).toPass();
|
||||
expect(match(["a", function() {
|
||||
}]).toEqual(["a", jasmine.any(Function)])).toEqual(true);
|
||||
}]).toEqual(["a", jasmine.any(Function)])).toPass();
|
||||
});
|
||||
|
||||
it("toEqual handles circular objects ok", function() {
|
||||
expect(match({foo: "bar", baz: jasmine.undefined}).toEqual({foo: "bar", baz: jasmine.undefined})).toEqual(true);
|
||||
expect(match({foo:['bar','baz','quux']}).toEqual({foo:['bar','baz','quux']})).toEqual(true);
|
||||
expect(match({foo: {bar:'baz'}, quux:'corge'}).toEqual({foo:{bar:'baz'}, quux:'corge'})).toEqual(true);
|
||||
expect(match({foo: "bar", baz: jasmine.undefined}).toEqual({foo: "bar", baz: jasmine.undefined})).toPass();
|
||||
expect(match({foo:['bar','baz','quux']}).toEqual({foo:['bar','baz','quux']})).toPass();
|
||||
expect(match({foo: {bar:'baz'}, quux:'corge'}).toEqual({foo:{bar:'baz'}, quux:'corge'})).toPass();
|
||||
|
||||
var circularObject = {};
|
||||
var secondCircularObject = {};
|
||||
circularObject.field = circularObject;
|
||||
secondCircularObject.field = secondCircularObject;
|
||||
expect(match(circularObject).toEqual(secondCircularObject)).toEqual(true);
|
||||
expect(match(circularObject).toEqual(secondCircularObject)).toPass();
|
||||
});
|
||||
|
||||
it("toNotEqual as slightly surprising behavior, but is it intentional?", function() {
|
||||
expect(match({x:"x", y:"y", z:"w"}).toNotEqual({x:"x", y:"y", z:"z"})).toEqual(true);
|
||||
expect(match({x:"x", y:"y", w:"z"}).toNotEqual({x:"x", y:"y", z:"z"})).toEqual(true);
|
||||
expect(match({x:"x", y:"y", z:"z"}).toNotEqual({w: "w", x:"x", y:"y", z:"z"})).toEqual(true);
|
||||
expect(match({w: "w", x:"x", y:"y", z:"z"}).toNotEqual({x:"x", y:"y", z:"z"})).toEqual(true);
|
||||
expect(match({x:"x", y:"y", z:"w"}).toNotEqual({x:"x", y:"y", z:"z"})).toPass();
|
||||
expect(match({x:"x", y:"y", w:"z"}).toNotEqual({x:"x", y:"y", z:"z"})).toPass();
|
||||
expect(match({x:"x", y:"y", z:"z"}).toNotEqual({w: "w", x:"x", y:"y", z:"z"})).toPass();
|
||||
expect(match({w: "w", x:"x", y:"y", z:"z"}).toNotEqual({x:"x", y:"y", z:"z"})).toPass();
|
||||
});
|
||||
|
||||
it("toEqual handles arrays", function() {
|
||||
expect(match([1, "A"]).toEqual([1, "A"])).toEqual(true);
|
||||
expect(match([1, "A"]).toEqual([1, "A"])).toPass();
|
||||
});
|
||||
|
||||
it("toContain and toNotContain", function() {
|
||||
expect(match('ABC').toContain('A')).toEqual(true);
|
||||
expect(match('ABC').toContain('X')).toEqual(false);
|
||||
expect(match('ABC').toContain('A')).toPass();
|
||||
expect(match('ABC').toContain('X')).toFail();
|
||||
|
||||
expect(match(['A', 'B', 'C']).toContain('A')).toEqual(true);
|
||||
expect(match(['A', 'B', 'C']).toContain('F')).toEqual(false);
|
||||
expect(match(['A', 'B', 'C']).toNotContain('F')).toEqual(true);
|
||||
expect(match(['A', 'B', 'C']).toNotContain('A')).toEqual(false);
|
||||
expect(match(['A', 'B', 'C']).toContain('A')).toPass();
|
||||
expect(match(['A', 'B', 'C']).toContain('F')).toFail();
|
||||
expect(match(['A', 'B', 'C']).toNotContain('F')).toPass();
|
||||
expect(match(['A', 'B', 'C']).toNotContain('A')).toFail();
|
||||
|
||||
expect(match(['A', {some:'object'}, 'C']).toContain({some:'object'})).toEqual(true);
|
||||
expect(match(['A', {some:'object'}, 'C']).toContain({some:'other object'})).toEqual(false);
|
||||
expect(match(['A', {some:'object'}, 'C']).toContain({some:'object'})).toPass();
|
||||
expect(match(['A', {some:'object'}, 'C']).toContain({some:'other object'})).toFail();
|
||||
});
|
||||
|
||||
it("toContain to build an ExpectationResult", function() {
|
||||
@@ -384,7 +397,7 @@ describe("jasmine.Matchers", function() {
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toContain");
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch('contain');
|
||||
expect(result.message).toMatch(jasmine.pp(expected));
|
||||
@@ -401,7 +414,7 @@ describe("jasmine.Matchers", function() {
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toNotContain");
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch('not contain');
|
||||
expect(result.message).toMatch(jasmine.pp(expected));
|
||||
@@ -410,9 +423,9 @@ describe("jasmine.Matchers", function() {
|
||||
});
|
||||
|
||||
it("toBeLessThan should pass if actual is less than expected", function() {
|
||||
expect(match(37).toBeLessThan(42)).toEqual(true);
|
||||
expect(match(37).toBeLessThan(-42)).toEqual(false);
|
||||
expect(match(37).toBeLessThan(37)).toEqual(false);
|
||||
expect(match(37).toBeLessThan(42)).toPass();
|
||||
expect(match(37).toBeLessThan(-42)).toFail();
|
||||
expect(match(37).toBeLessThan(37)).toFail();
|
||||
});
|
||||
|
||||
it("toBeLessThan to build an ExpectationResult", function() {
|
||||
@@ -424,7 +437,7 @@ describe("jasmine.Matchers", function() {
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeLessThan");
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual) + ' to be less than');
|
||||
expect(result.message).toMatch(jasmine.pp(expected));
|
||||
expect(result.actual).toEqual(actual);
|
||||
@@ -432,9 +445,9 @@ describe("jasmine.Matchers", function() {
|
||||
});
|
||||
|
||||
it("toBeGreaterThan should pass if actual is greater than expected", function() {
|
||||
expect(match(37).toBeGreaterThan(42)).toEqual(false);
|
||||
expect(match(37).toBeGreaterThan(-42)).toEqual(true);
|
||||
expect(match(37).toBeGreaterThan(37)).toEqual(false);
|
||||
expect(match(37).toBeGreaterThan(42)).toFail();
|
||||
expect(match(37).toBeGreaterThan(-42)).toPass();
|
||||
expect(match(37).toBeGreaterThan(37)).toFail();
|
||||
});
|
||||
|
||||
it("toBeGreaterThan to build an ExpectationResult", function() {
|
||||
@@ -446,54 +459,137 @@ describe("jasmine.Matchers", function() {
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeGreaterThan");
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual) + ' to be greater than');
|
||||
expect(result.message).toMatch(jasmine.pp(expected));
|
||||
expect(result.actual).toEqual(actual);
|
||||
expect(result.expected).toEqual(expected);
|
||||
});
|
||||
|
||||
it("toThrow", function() {
|
||||
var expected = match(function() {
|
||||
throw new Error("Fake Error");
|
||||
describe("toBeCloseTo", function() {
|
||||
it("returns 'true' iff actual and expected are equal within 2 decimal points of precision", function() {
|
||||
expect(0).toBeCloseTo(0);
|
||||
expect(1).toBeCloseTo(1);
|
||||
expect(1).not.toBeCloseTo(1.1);
|
||||
expect(1).not.toBeCloseTo(1.01);
|
||||
expect(1).toBeCloseTo(1.001);
|
||||
|
||||
expect(1.23).toBeCloseTo(1.234);
|
||||
expect(1.23).toBeCloseTo(1.233);
|
||||
expect(1.23).toBeCloseTo(1.232);
|
||||
expect(1.23).not.toBeCloseTo(1.24);
|
||||
|
||||
expect(-1.23).toBeCloseTo(-1.234);
|
||||
expect(-1.23).not.toBeCloseTo(-1.24);
|
||||
});
|
||||
expect(expected.toThrow()).toEqual(true);
|
||||
expect(expected.toThrow("Fake Error")).toEqual(true);
|
||||
expect(expected.toThrow(new Error("Fake Error"))).toEqual(true);
|
||||
|
||||
expect(expected.toThrow("Other Error")).toEqual(false);
|
||||
var result = lastResult();
|
||||
expect(result.message).toMatch("Other Error");
|
||||
it("accepts an optional precision argument", function() {
|
||||
expect(1).toBeCloseTo(1.1, 0);
|
||||
expect(1.2).toBeCloseTo(1.23, 1);
|
||||
|
||||
expect(expected.toThrow(new Error("Other Error"))).toEqual(false);
|
||||
result = lastResult();
|
||||
expect(result.message).toMatch("Other Error");
|
||||
expect(1.234).toBeCloseTo(1.2343, 3);
|
||||
expect(1.234).not.toBeCloseTo(1.233, 3);
|
||||
});
|
||||
|
||||
var exception;
|
||||
try {
|
||||
(function () {
|
||||
new jasmine.Matchers(env, 'not-a-function', spec).toThrow();
|
||||
})();
|
||||
} catch (e) {
|
||||
exception = e;
|
||||
}
|
||||
it("rounds", function() {
|
||||
expect(1.23).toBeCloseTo(1.229);
|
||||
expect(1.23).toBeCloseTo(1.226);
|
||||
expect(1.23).toBeCloseTo(1.225);
|
||||
expect(1.23).not.toBeCloseTo(1.2249999);
|
||||
|
||||
expect(exception).toBeDefined();
|
||||
expect(exception.message).toEqual('Actual is not a function');
|
||||
expect(1.23).toBeCloseTo(1.234);
|
||||
expect(1.23).toBeCloseTo(1.2349999);
|
||||
expect(1.23).not.toBeCloseTo(1.235);
|
||||
|
||||
expect(-1.23).toBeCloseTo(-1.234);
|
||||
expect(-1.23).not.toBeCloseTo(-1.235);
|
||||
expect(-1.23).not.toBeCloseTo(-1.236);
|
||||
});
|
||||
});
|
||||
|
||||
describe("toThrow", function() {
|
||||
describe("when code block throws an exception", function() {
|
||||
var throwingFn;
|
||||
|
||||
beforeEach(function() {
|
||||
throwingFn = function() {
|
||||
throw new Error("Fake Error");
|
||||
};
|
||||
});
|
||||
|
||||
it("should match any exception", function() {
|
||||
expect(match(throwingFn).toThrow()).toPass();
|
||||
});
|
||||
|
||||
it("should match exceptions specified by message", function() {
|
||||
expect(match(throwingFn).toThrow("Fake Error")).toPass();
|
||||
expect(match(throwingFn).toThrow("Other Error")).toFail();
|
||||
expect(lastResult().message).toMatch("Other Error");
|
||||
});
|
||||
|
||||
it("should match exceptions specified by Error", function() {
|
||||
expect(match(throwingFn).toThrow(new Error("Fake Error"))).toPass();
|
||||
expect(match(throwingFn).toThrow(new Error("Other Error"))).toFail();
|
||||
expect(lastResult().message).toMatch("Other Error");
|
||||
});
|
||||
|
||||
describe("and matcher is inverted with .not", function() {
|
||||
it("should match any exception", function() {
|
||||
expect(match(throwingFn).not.toThrow()).toFail();
|
||||
expect(lastResult().message).toMatch(/Expected function not to throw an exception/);
|
||||
});
|
||||
|
||||
it("should match exceptions specified by message", function() {
|
||||
expect(match(throwingFn).not.toThrow("Fake Error")).toFail();
|
||||
// expect(lastResult().message).toMatch(/Expected function not to throw Fake Error./);
|
||||
expect(match(throwingFn).not.toThrow("Other Error")).toPass();
|
||||
});
|
||||
|
||||
it("should match exceptions specified by Error", function() {
|
||||
expect(match(throwingFn).not.toThrow(new Error("Fake Error"))).toFail();
|
||||
// expect(lastResult().message).toMatch("Other Error");
|
||||
expect(match(throwingFn).not.toThrow(new Error("Other Error"))).toPass();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("when actual is not a function", function() {
|
||||
it("should fail with an exception", function() {
|
||||
var exception = catchException(function() {
|
||||
match('not-a-function').toThrow();
|
||||
});
|
||||
expect(exception).toBeDefined();
|
||||
expect(exception.message).toEqual('Actual is not a function');
|
||||
});
|
||||
|
||||
describe("and matcher is inverted with .not", function() {
|
||||
it("should fail with an exception", function() {
|
||||
var exception = catchException(function() {
|
||||
match('not-a-function').not.toThrow();
|
||||
});
|
||||
expect(exception).toBeDefined();
|
||||
expect(exception.message).toEqual('Actual is not a function');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
expect(match(function() {
|
||||
}).toThrow()).toEqual(false);
|
||||
result = lastResult();
|
||||
expect(result.message).toEqual('Expected function to throw an exception.');
|
||||
describe("when code block does not throw an exception", function() {
|
||||
it("should fail (or pass when inverted with .not)", function() {
|
||||
expect(match(
|
||||
function() {
|
||||
}).toThrow()).toFail();
|
||||
expect(lastResult().message).toEqual('Expected function to throw an exception.');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe(".not.matcher", function() {
|
||||
it("should invert the sense of any matcher", function() {
|
||||
expect(match(37).not.toBeGreaterThan(42)).toEqual(true);
|
||||
expect(match(42).not.toBeGreaterThan(37)).toEqual(false);
|
||||
expect(match("abc").not.toEqual("def")).toEqual(true);
|
||||
expect(match("abc").not.toEqual("abc")).toEqual(false);
|
||||
expect(match(37).not.toBeGreaterThan(42)).toPass();
|
||||
expect(match(42).not.toBeGreaterThan(37)).toFail();
|
||||
expect(match("abc").not.toEqual("def")).toPass();
|
||||
expect(match("abc").not.toEqual("abc")).toFail();
|
||||
});
|
||||
|
||||
it("should provide an inverted default message", function() {
|
||||
@@ -537,36 +633,41 @@ describe("jasmine.Matchers", function() {
|
||||
|
||||
function shouldThrowAnExceptionWhenInvokedOnANonSpy(methodName) {
|
||||
return function() {
|
||||
expect(function() {
|
||||
match(TestClass.normalFunction)[methodName]();
|
||||
}).toThrow('Expected a spy, but got Function.');
|
||||
expect(
|
||||
function() {
|
||||
match(TestClass.normalFunction)[methodName]();
|
||||
}).toThrow('Expected a spy, but got Function.');
|
||||
|
||||
expect(function() {
|
||||
match(jasmine.undefined)[methodName]();
|
||||
}).toThrow('Expected a spy, but got undefined.');
|
||||
expect(
|
||||
function() {
|
||||
match(jasmine.undefined)[methodName]();
|
||||
}).toThrow('Expected a spy, but got undefined.');
|
||||
|
||||
expect(function() {
|
||||
match({some:'object'})[methodName]();
|
||||
}).toThrow('Expected a spy, but got { some : \'object\' }.');
|
||||
expect(
|
||||
function() {
|
||||
match({some:'object'})[methodName]();
|
||||
}).toThrow('Expected a spy, but got { some : \'object\' }.');
|
||||
|
||||
expect(function() {
|
||||
match("<b>")[methodName]();
|
||||
}).toThrow('Expected a spy, but got \'<b>\'.');
|
||||
expect(
|
||||
function() {
|
||||
match("<b>")[methodName]();
|
||||
}).toThrow('Expected a spy, but got \'<b>\'.');
|
||||
};
|
||||
}
|
||||
|
||||
describe("toHaveBeenCalled", function() {
|
||||
it("should pass if the spy was called", function() {
|
||||
expect(match(TestClass.spyFunction).toHaveBeenCalled()).toEqual(false);
|
||||
expect(match(TestClass.spyFunction).toHaveBeenCalled()).toFail();
|
||||
|
||||
TestClass.spyFunction();
|
||||
expect(match(TestClass.spyFunction).toHaveBeenCalled()).toEqual(true);
|
||||
expect(match(TestClass.spyFunction).toHaveBeenCalled()).toPass();
|
||||
});
|
||||
|
||||
it("should throw an exception when invoked with any arguments", function() {
|
||||
expect(function() {
|
||||
match(TestClass.normalFunction).toHaveBeenCalled("unwanted argument");
|
||||
}).toThrow('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
|
||||
expect(
|
||||
function() {
|
||||
match(TestClass.normalFunction).toHaveBeenCalled("unwanted argument");
|
||||
}).toThrow('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
|
||||
});
|
||||
|
||||
it('should throw an exception when invoked on a non-spy', shouldThrowAnExceptionWhenInvokedOnANonSpy('toHaveBeenCalled'));
|
||||
@@ -585,16 +686,17 @@ describe("jasmine.Matchers", function() {
|
||||
|
||||
describe("wasNotCalled", function() {
|
||||
it("should pass iff the spy was not called", function() {
|
||||
expect(match(TestClass.spyFunction).wasNotCalled()).toEqual(true);
|
||||
expect(match(TestClass.spyFunction).wasNotCalled()).toPass();
|
||||
|
||||
TestClass.spyFunction();
|
||||
expect(match(TestClass.spyFunction).wasNotCalled()).toEqual(false);
|
||||
expect(match(TestClass.spyFunction).wasNotCalled()).toFail();
|
||||
});
|
||||
|
||||
it("should throw an exception when invoked with any arguments", function() {
|
||||
expect(function() {
|
||||
match(TestClass.normalFunction).wasNotCalled("unwanted argument");
|
||||
}).toThrow('wasNotCalled does not take arguments');
|
||||
expect(
|
||||
function() {
|
||||
match(TestClass.normalFunction).wasNotCalled("unwanted argument");
|
||||
}).toThrow('wasNotCalled does not take arguments');
|
||||
});
|
||||
|
||||
it('should throw an exception when invoked on a non-spy', shouldThrowAnExceptionWhenInvokedOnANonSpy('wasNotCalled'));
|
||||
@@ -603,15 +705,15 @@ describe("jasmine.Matchers", function() {
|
||||
describe("toHaveBeenCalledWith", function() {
|
||||
it('toHaveBeenCalledWith should return true if it was called with the expected args', function() {
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
expect(match(TestClass.spyFunction).toHaveBeenCalledWith('a', 'b', 'c')).toEqual(true);
|
||||
expect(match(TestClass.spyFunction).toHaveBeenCalledWith('a', 'b', 'c')).toPass();
|
||||
});
|
||||
|
||||
it('should return false if it was not called with the expected args', function() {
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.toHaveBeenCalledWith('c', 'b', 'a')).toEqual(false);
|
||||
expect(expected.toHaveBeenCalledWith('c', 'b', 'a')).toFail();
|
||||
var result = lastResult();
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.expected).toEqual(['c', 'b', 'a']);
|
||||
expect(result.actual.mostRecentCall.args).toEqual(['a', 'b', 'c']);
|
||||
expect(result.message).toContain(jasmine.pp(result.expected));
|
||||
@@ -620,21 +722,37 @@ describe("jasmine.Matchers", function() {
|
||||
|
||||
it('should return false if it was not called', function() {
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.toHaveBeenCalledWith('c', 'b', 'a')).toEqual(false);
|
||||
expect(expected.toHaveBeenCalledWith('c', 'b', 'a')).toFail();
|
||||
var result = lastResult();
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.expected).toEqual(['c', 'b', 'a']);
|
||||
expect(result.actual.argsForCall).toEqual([]);
|
||||
expect(result.message).toContain(jasmine.pp(result.expected));
|
||||
});
|
||||
|
||||
it('should allow matches across multiple calls', function() {
|
||||
var expected = match(TestClass.spyFunction);
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
TestClass.spyFunction('d', 'e', 'f');
|
||||
expect(expected.toHaveBeenCalledWith('a', 'b', 'c')).toEqual(true);
|
||||
expect(expected.toHaveBeenCalledWith('d', 'e', 'f')).toEqual(true);
|
||||
expect(expected.toHaveBeenCalledWith('x', 'y', 'z')).toEqual(false);
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.toHaveBeenCalledWith('a', 'b', 'c')).toPass();
|
||||
expect(expected.toHaveBeenCalledWith('d', 'e', 'f')).toPass();
|
||||
expect(expected.toHaveBeenCalledWith('x', 'y', 'z')).toFail();
|
||||
});
|
||||
|
||||
it("should return a decent message", function() {
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
TestClass.spyFunction('d', 'e', 'f');
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.toHaveBeenCalledWith('a', 'b')).toFail();
|
||||
expect(lastResult().message).toEqual("Expected spy My spy to have been called with [ 'a', 'b' ] but was called with [ [ 'a', 'b', 'c' ], [ 'd', 'e', 'f' ] ]");
|
||||
});
|
||||
|
||||
it("should return a decent message when inverted", function() {
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
TestClass.spyFunction('d', 'e', 'f');
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.not.toHaveBeenCalledWith('a', 'b', 'c')).toFail();
|
||||
expect(lastResult().message).toEqual("Expected spy My spy not to have been called with [ 'a', 'b', 'c' ] but was called with [ [ 'a', 'b', 'c' ], [ 'd', 'e', 'f' ] ]");
|
||||
});
|
||||
|
||||
it('should throw an exception when invoked on a non-spy', shouldThrowAnExceptionWhenInvokedOnANonSpy('toHaveBeenCalledWith'));
|
||||
@@ -658,7 +776,7 @@ describe("jasmine.Matchers", function() {
|
||||
|
||||
var result = lastResult();
|
||||
expect(result.matcherName).toEqual("toHaveBeenCalledWith");
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toContain(jasmine.pp(['a', 'b']));
|
||||
expect(result.message).toContain(jasmine.pp(['a', 'c']));
|
||||
expect(result.actual).toEqual(TestClass.someFunction);
|
||||
@@ -680,15 +798,15 @@ describe("jasmine.Matchers", function() {
|
||||
describe("wasNotCalledWith", function() {
|
||||
it('should return true if the spy was NOT called with the expected args', function() {
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
expect(match(TestClass.spyFunction).wasNotCalledWith('c', 'b', 'a')).toEqual(true);
|
||||
expect(match(TestClass.spyFunction).wasNotCalledWith('c', 'b', 'a')).toPass();
|
||||
});
|
||||
|
||||
it('should return false if it WAS called with the expected args', function() {
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.wasNotCalledWith('a', 'b', 'c')).toEqual(false);
|
||||
expect(expected.wasNotCalledWith('a', 'b', 'c')).toFail();
|
||||
var result = lastResult();
|
||||
expect(result.passed()).toEqual(false);
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.expected).toEqual(['a', 'b', 'c']);
|
||||
expect(result.actual.mostRecentCall.args).toEqual(['a', 'b', 'c']);
|
||||
expect(result.message).toContain(jasmine.pp(result.expected));
|
||||
@@ -696,21 +814,25 @@ describe("jasmine.Matchers", function() {
|
||||
|
||||
it('should return true if it was not called', function() {
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.wasNotCalledWith('c', 'b', 'a')).toEqual(true);
|
||||
expect(expected.wasNotCalledWith('c', 'b', 'a')).toPass();
|
||||
});
|
||||
|
||||
it('should allow matches across multiple calls', function() {
|
||||
var expected = match(TestClass.spyFunction);
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
TestClass.spyFunction('d', 'e', 'f');
|
||||
expect(expected.wasNotCalledWith('a', 'b', 'c')).toEqual(false);
|
||||
expect(expected.wasNotCalledWith('d', 'e', 'f')).toEqual(false);
|
||||
expect(expected.wasNotCalledWith('x', 'y', 'z')).toEqual(true);
|
||||
expect(expected.wasNotCalledWith('a', 'b', 'c')).toFail();
|
||||
expect(expected.wasNotCalledWith('d', 'e', 'f')).toFail();
|
||||
expect(expected.wasNotCalledWith('x', 'y', 'z')).toPass();
|
||||
});
|
||||
|
||||
it('should throw an exception when invoked on a non-spy', shouldThrowAnExceptionWhenInvokedOnANonSpy('wasNotCalledWith'));
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe("all matchers", function() {
|
||||
it("should return null, for future-proofing, since we might eventually allow matcher chaining", function() {
|
||||
expect(match(true).toBe(true)).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -18,9 +18,9 @@ describe("jasmine.MultiReporter", function() {
|
||||
delegate[methodName] = jasmine.createSpy(methodName);
|
||||
this.actual[methodName]("whatever argument");
|
||||
|
||||
return delegate[methodName].wasCalled
|
||||
&& delegate[methodName].mostRecentCall.args.length == 1
|
||||
&& delegate[methodName].mostRecentCall.args[0] == "whatever argument";
|
||||
return delegate[methodName].wasCalled &&
|
||||
delegate[methodName].mostRecentCall.args.length == 1 &&
|
||||
delegate[methodName].mostRecentCall.args[0] == "whatever argument";
|
||||
}
|
||||
});
|
||||
|
||||
@@ -58,12 +58,6 @@ describe("jasmine.pp", function () {
|
||||
}
|
||||
});
|
||||
|
||||
it("should stringify HTML nodes properly", function() {
|
||||
var sampleNode = document.createElement('div');
|
||||
sampleNode.innerHTML = 'foo<b>bar</b>';
|
||||
expect(jasmine.pp(sampleNode)).toEqual("HTMLNode");
|
||||
expect(jasmine.pp({foo: sampleNode})).toEqual("{ foo : HTMLNode }");
|
||||
});
|
||||
|
||||
it('should not do HTML escaping of strings', function() {
|
||||
expect(jasmine.pp('some <b>html string</b> &', false)).toEqual('\'some <b>html string</b> &\'');
|
||||
@@ -54,7 +54,7 @@ describe("jasmine spec running", function () {
|
||||
this.expect(foo).toEqual('baz');
|
||||
});
|
||||
|
||||
specWithMultipleExpectations = env.it('spec with multiple assertions').runs(function () {
|
||||
specWithMultipleExpectations = env.it('spec with multiple expectations').runs(function () {
|
||||
var foo = 'bar';
|
||||
var baz = 'quux';
|
||||
|
||||
@@ -258,86 +258,146 @@ describe("jasmine spec running", function () {
|
||||
expect(another_spec.results().getItems()[0].passed()).toEqual(true);
|
||||
});
|
||||
|
||||
it("testWaitsFor", function() {
|
||||
var doneWaiting = false;
|
||||
var runsBlockExecuted = false;
|
||||
|
||||
describe("waitsFor", function() {
|
||||
var latchFunction = function() {
|
||||
return true;
|
||||
};
|
||||
var spec;
|
||||
env.describe('foo', function() {
|
||||
spec = env.it('has a waits for', function() {
|
||||
this.runs(function() {
|
||||
});
|
||||
|
||||
this.waitsFor(500, function() {
|
||||
return doneWaiting;
|
||||
});
|
||||
|
||||
this.runs(function() {
|
||||
runsBlockExecuted = true;
|
||||
function makeWaitsForSpec() {
|
||||
var args = jasmine.util.argsToArray(arguments);
|
||||
env.describe('suite', function() {
|
||||
spec = env.it('spec', function() {
|
||||
this.waitsFor.apply(this, args);
|
||||
});
|
||||
});
|
||||
env.execute();
|
||||
}
|
||||
|
||||
it("should accept args (latchFunction, timeoutMessage, timeout)", function() {
|
||||
makeWaitsForSpec(latchFunction, "message", 123);
|
||||
var block = spec.queue.blocks[1];
|
||||
expect(block.latchFunction).toBe(latchFunction);
|
||||
expect(block.timeout).toEqual(123);
|
||||
expect(block.message).toEqual('message');
|
||||
});
|
||||
|
||||
spec.execute();
|
||||
expect(runsBlockExecuted).toEqual(false); //, 'should not have executed runs block yet');
|
||||
fakeTimer.tick(100);
|
||||
doneWaiting = true;
|
||||
fakeTimer.tick(100);
|
||||
expect(runsBlockExecuted).toEqual(true); //, 'should have executed runs block');
|
||||
});
|
||||
it("should accept args (latchFunction, timeout)", function() {
|
||||
makeWaitsForSpec(latchFunction, 123);
|
||||
var block = spec.queue.blocks[1];
|
||||
expect(block.latchFunction).toBe(latchFunction);
|
||||
expect(block.timeout).toEqual(123);
|
||||
expect(block.message).toEqual(null);
|
||||
});
|
||||
|
||||
it("testWaitsForFailsWithMessage", function() {
|
||||
var spec;
|
||||
env.describe('foo', function() {
|
||||
spec = env.it('has a waits for', function() {
|
||||
this.runs(function() {
|
||||
});
|
||||
it("should accept args (latchFunction, timeoutMessage)", function() {
|
||||
env.defaultTimeoutInterval = 4321;
|
||||
makeWaitsForSpec(latchFunction, "message");
|
||||
var block = spec.queue.blocks[1];
|
||||
expect(block.latchFunction).toBe(latchFunction);
|
||||
expect(block.timeout).toEqual(4321);
|
||||
expect(block.message).toEqual('message');
|
||||
});
|
||||
|
||||
this.waitsFor(500, function() {
|
||||
return false; // force a timeout
|
||||
}, 'my awesome condition');
|
||||
it("should accept args (latchFunction)", function() {
|
||||
env.defaultTimeoutInterval = 4321;
|
||||
makeWaitsForSpec(latchFunction);
|
||||
var block = spec.queue.blocks[1];
|
||||
expect(block.latchFunction).toBe(latchFunction);
|
||||
expect(block.timeout).toEqual(4321);
|
||||
expect(block.message).toEqual(null);
|
||||
});
|
||||
|
||||
this.runs(function() {
|
||||
it("should accept deprecated args order (timeout, latchFunction, timeoutMessage)", function() {
|
||||
makeWaitsForSpec(123, latchFunction, "message");
|
||||
var block = spec.queue.blocks[1];
|
||||
expect(block.latchFunction).toBe(latchFunction);
|
||||
expect(block.timeout).toEqual(123);
|
||||
expect(block.message).toEqual('message');
|
||||
});
|
||||
|
||||
it("testWaitsFor", function() {
|
||||
var doneWaiting = false;
|
||||
var runsBlockExecuted = false;
|
||||
|
||||
var spec;
|
||||
env.describe('foo', function() {
|
||||
spec = env.it('has a waits for', function() {
|
||||
this.runs(function() {
|
||||
});
|
||||
|
||||
this.waitsFor(500, function() {
|
||||
return doneWaiting;
|
||||
});
|
||||
|
||||
this.runs(function() {
|
||||
runsBlockExecuted = true;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
spec.execute();
|
||||
expect(runsBlockExecuted).toEqual(false); //, 'should not have executed runs block yet');
|
||||
fakeTimer.tick(100);
|
||||
doneWaiting = true;
|
||||
fakeTimer.tick(100);
|
||||
expect(runsBlockExecuted).toEqual(true); //, 'should have executed runs block');
|
||||
});
|
||||
|
||||
spec.execute();
|
||||
fakeTimer.tick(1000);
|
||||
var actual = spec.results().getItems()[0].message;
|
||||
var expected = 'timeout: timed out after 500 msec waiting for my awesome condition';
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
it("fails with message", function() {
|
||||
var spec;
|
||||
env.describe('foo', function() {
|
||||
spec = env.it('has a waits for', function() {
|
||||
this.runs(function() {
|
||||
});
|
||||
|
||||
it("waitsFor fails and skips the rest of the spec if timeout is reached and the latch function is still false", function() {
|
||||
var runsBlockExecuted = false;
|
||||
this.waitsFor(500, function() {
|
||||
return false; // force a timeout
|
||||
}, 'my awesome condition');
|
||||
|
||||
var spec;
|
||||
env.describe('foo', function() {
|
||||
spec = env.it('has a waits for', function() {
|
||||
this.runs(function() {
|
||||
});
|
||||
|
||||
this.waitsFor(500, function() {
|
||||
return false;
|
||||
});
|
||||
|
||||
this.runs(function() {
|
||||
runsBlockExecuted = true;
|
||||
this.runs(function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
spec.execute();
|
||||
fakeTimer.tick(1000);
|
||||
expect(spec.results().getItems()[0].message).toEqual('timeout: timed out after 500 msec waiting for my awesome condition');
|
||||
});
|
||||
|
||||
spec.execute();
|
||||
expect(runsBlockExecuted).toEqual(false);
|
||||
fakeTimer.tick(100);
|
||||
expect(runsBlockExecuted).toEqual(false);
|
||||
fakeTimer.tick(400);
|
||||
expect(runsBlockExecuted).toEqual(false);
|
||||
var actual = spec.results().getItems()[0].message;
|
||||
var expected = 'timeout: timed out after 500 msec waiting for something to happen';
|
||||
expect(actual).toEqual(expected,
|
||||
'expected "' + expected + '" but found "' + actual + '"');
|
||||
it("fails and skips the rest of the spec if timeout is reached and the latch function hasn't returned true", function() {
|
||||
var runsBlockExecuted = false;
|
||||
var subsequentSpecRan = false;
|
||||
|
||||
var timeoutSpec, subsequentSpec;
|
||||
var suite = env.describe('foo', function() {
|
||||
timeoutSpec = env.it('has a waits for', function() {
|
||||
this.runs(function() {
|
||||
});
|
||||
|
||||
this.waitsFor(500, function() {
|
||||
return false;
|
||||
});
|
||||
|
||||
this.runs(function() {
|
||||
runsBlockExecuted = true;
|
||||
});
|
||||
});
|
||||
|
||||
subsequentSpec = env.it('then carries on to the next test', function() {
|
||||
subsequentSpecRan = true;
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
expect(runsBlockExecuted).toEqual(false);
|
||||
fakeTimer.tick(100);
|
||||
expect(runsBlockExecuted).toEqual(false);
|
||||
fakeTimer.tick(400);
|
||||
expect(runsBlockExecuted).toEqual(false);
|
||||
expect(timeoutSpec.results().getItems()[0].message).toEqual('timeout: timed out after 500 msec waiting for something to happen');
|
||||
expect(subsequentSpecRan).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("testSpecAfter", function() {
|
||||
@@ -520,17 +580,15 @@ describe("jasmine spec running", function () {
|
||||
});
|
||||
|
||||
describe('#waitsFor should allow consecutive calls', function () {
|
||||
|
||||
var foo;
|
||||
beforeEach(function () {
|
||||
|
||||
foo = 0;
|
||||
});
|
||||
|
||||
it('exits immediately (does not stack) if the latchFunction times out', function () {
|
||||
var reachedFirstWaitsFor = false;
|
||||
var reachedSecondWaitsFor = false;
|
||||
var waitsSuite = env.describe('suite that waits', function () {
|
||||
env.describe('suite that waits', function () {
|
||||
env.it('should stack timeouts', function() {
|
||||
this.waitsFor(500, function () {
|
||||
reachedFirstWaitsFor = true;
|
||||
@@ -546,7 +604,7 @@ describe("jasmine spec running", function () {
|
||||
});
|
||||
|
||||
expect(reachedFirstWaitsFor).toEqual(false);
|
||||
waitsSuite.execute();
|
||||
env.execute();
|
||||
|
||||
expect(reachedFirstWaitsFor).toEqual(true);
|
||||
expect(foo).toEqual(0);
|
||||
@@ -1167,6 +1225,9 @@ describe("jasmine spec running", function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
throw new Error("fake error");
|
||||
|
||||
});
|
||||
} catch(e) {
|
||||
}
|
||||
@@ -1182,14 +1243,16 @@ describe("jasmine spec running", function () {
|
||||
|
||||
expect(specs.join('')).toMatch(new RegExp(
|
||||
'Spec: outer1 inner1 should thingy.' +
|
||||
'Result: Passed.' +
|
||||
'Spec: outer1 encountered a declaration exception.' +
|
||||
'Result: Error: fake error.*' +
|
||||
'Spec: outer1 inner2 should other thingy.' +
|
||||
'Result: Passed.' +
|
||||
'Spec: outer2 should xxx.' +
|
||||
'Result: Passed.'
|
||||
));
|
||||
'Result: Passed.' +
|
||||
'Spec: outer1 inner1 encountered a declaration exception.' +
|
||||
'Result: Error: fake error.*' +
|
||||
'Spec: outer1 inner2 should other thingy.' +
|
||||
'Result: Passed.' +
|
||||
'Spec: outer1 encountered a declaration exception.' +
|
||||
'Result: Error: fake error.*' +
|
||||
'Spec: outer2 should xxx.' +
|
||||
'Result: Passed.'
|
||||
));
|
||||
});
|
||||
|
||||
});
|
||||
@@ -38,7 +38,7 @@ describe('Spec', function () {
|
||||
|
||||
it('getFullName returns suite & spec description', function () {
|
||||
var spec = new jasmine.Spec(env, suite, 'spec 1');
|
||||
expect(spec.getFullName()).toEqual('suite 1 spec 1.')
|
||||
expect(spec.getFullName()).toEqual('suite 1 spec 1.');
|
||||
});
|
||||
|
||||
describe('results', function () {
|
||||
@@ -25,7 +25,6 @@ describe("jasmine.util", function() {
|
||||
it("should return true if the argument is an array", function() {
|
||||
expect(jasmine.isArray_([])).toBe(true);
|
||||
expect(jasmine.isArray_(['a'])).toBe(true);
|
||||
expect(jasmine.isArray_(new Array())).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false if the argument is not an array", function() {
|
||||
@@ -10,12 +10,43 @@ describe('WaitsForBlock', function () {
|
||||
onComplete = jasmine.createSpy("onComplete");
|
||||
});
|
||||
|
||||
describe("jasmine.VERBOSE", function() {
|
||||
var jasmineVerboseOriginal;
|
||||
beforeEach(function() {
|
||||
jasmineVerboseOriginal = jasmine.VERBOSE;
|
||||
spyOn(env.reporter, 'log');
|
||||
|
||||
});
|
||||
it('do not show information if jasmine.VERBOSE is set to false', function () {
|
||||
jasmine.VERBOSE = false;
|
||||
var latchFunction = function() {
|
||||
return true;
|
||||
};
|
||||
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
|
||||
expect(env.reporter.log).not.toHaveBeenCalled();
|
||||
block.execute(onComplete);
|
||||
expect(env.reporter.log).not.toHaveBeenCalled();
|
||||
jasmine.VERBOSE = jasmineVerboseOriginal;
|
||||
});
|
||||
it('show information if jasmine.VERBOSE is set to true', function () {
|
||||
jasmine.VERBOSE = true;
|
||||
var latchFunction = function() {
|
||||
return true;
|
||||
};
|
||||
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
|
||||
expect(env.reporter.log).not.toHaveBeenCalled();
|
||||
block.execute(onComplete);
|
||||
expect(env.reporter.log).toHaveBeenCalled();
|
||||
jasmine.VERBOSE = jasmineVerboseOriginal;
|
||||
});
|
||||
});
|
||||
|
||||
it('onComplete should be called if the latchFunction returns true', function () {
|
||||
var latchFunction = function() {
|
||||
return true;
|
||||
};
|
||||
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
|
||||
expect(onComplete).wasNotCalled();
|
||||
expect(onComplete).not.toHaveBeenCalled();
|
||||
block.execute(onComplete);
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
});
|
||||
@@ -51,22 +82,22 @@ describe('WaitsForBlock', function () {
|
||||
env.clearInterval = fakeTimer.clearInterval;
|
||||
});
|
||||
|
||||
it('latchFunction should be retried after 100 ms', function () {
|
||||
it('latchFunction should be retried after 10 ms', function () {
|
||||
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
|
||||
expect(latchFunction).wasNotCalled();
|
||||
expect(latchFunction).not.toHaveBeenCalled();
|
||||
block.execute(onComplete);
|
||||
expect(latchFunction.callCount).toEqual(1);
|
||||
fakeTimer.tick(50);
|
||||
fakeTimer.tick(5);
|
||||
expect(latchFunction.callCount).toEqual(1);
|
||||
fakeTimer.tick(50);
|
||||
fakeTimer.tick(5);
|
||||
expect(latchFunction.callCount).toEqual(2);
|
||||
});
|
||||
|
||||
it('onComplete should be called if latchFunction returns true before timeout', function () {
|
||||
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
|
||||
expect(onComplete).wasNotCalled();
|
||||
expect(onComplete).not.toHaveBeenCalled();
|
||||
block.execute(onComplete);
|
||||
expect(onComplete).wasNotCalled();
|
||||
expect(onComplete).not.toHaveBeenCalled();
|
||||
latchFunction.andReturn(true);
|
||||
fakeTimer.tick(100);
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
@@ -76,12 +107,12 @@ describe('WaitsForBlock', function () {
|
||||
spyOn(spec, 'fail');
|
||||
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
|
||||
block.execute(onComplete);
|
||||
expect(spec.fail).wasNotCalled();
|
||||
expect(spec.fail).not.toHaveBeenCalled();
|
||||
fakeTimer.tick(timeout);
|
||||
expect(spec.fail).toHaveBeenCalled();
|
||||
var failMessage = spec.fail.mostRecentCall.args[0].message;
|
||||
expect(failMessage).toMatch(message);
|
||||
expect(onComplete).wasNotCalled();
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
38
spec/html/MatchersHtmlSpec.js
Normal file
@@ -0,0 +1,38 @@
|
||||
describe("MatchersSpec - HTML Dependent", function () {
|
||||
var env, spec;
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmine.Env();
|
||||
env.updateInterval = 0;
|
||||
|
||||
var suite = env.describe("suite", function() {
|
||||
spec = env.it("spec", function() {
|
||||
});
|
||||
});
|
||||
spyOn(spec, 'addMatcherResult');
|
||||
|
||||
this.addMatchers({
|
||||
toPass: function() {
|
||||
return lastResult().passed();
|
||||
},
|
||||
toFail: function() {
|
||||
return !lastResult().passed();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function match(value) {
|
||||
return spec.expect(value);
|
||||
}
|
||||
|
||||
function lastResult() {
|
||||
return spec.addMatcherResult.mostRecentCall.args[0];
|
||||
}
|
||||
|
||||
it("toEqual with DOM nodes", function() {
|
||||
var nodeA = document.createElement('div');
|
||||
var nodeB = document.createElement('div');
|
||||
expect((match(nodeA).toEqual(nodeA))).toPass();
|
||||
expect((match(nodeA).toEqual(nodeB))).toFail();
|
||||
});
|
||||
});
|
||||
8
spec/html/PrettyPrintHtmlSpec.js
Normal file
@@ -0,0 +1,8 @@
|
||||
describe("jasmine.pp (HTML Dependent)", function () {
|
||||
it("should stringify HTML nodes properly", function() {
|
||||
var sampleNode = document.createElement('div');
|
||||
sampleNode.innerHTML = 'foo<b>bar</b>';
|
||||
expect(jasmine.pp(sampleNode)).toEqual("HTMLNode");
|
||||
expect(jasmine.pp({foo: sampleNode})).toEqual("{ foo : HTMLNode }");
|
||||
});
|
||||
});
|
||||
@@ -31,7 +31,9 @@ describe("TrivialReporter", function() {
|
||||
|
||||
function findElement(divs, withClass) {
|
||||
var els = findElements(divs, withClass);
|
||||
if (els.length > 0) return els[0];
|
||||
if (els.length > 0) {
|
||||
return els[0];
|
||||
}
|
||||
throw new Error("couldn't find div with class " + withClass);
|
||||
}
|
||||
|
||||
@@ -96,7 +98,6 @@ describe("TrivialReporter", function() {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("failure messages (integration)", function () {
|
||||
var spec, results, expectationResult;
|
||||
|
||||
@@ -172,6 +173,9 @@ describe("TrivialReporter", function() {
|
||||
var errorDiv = findElement(divs, 'resultMessage log');
|
||||
expect(errorDiv.innerHTML).toEqual("this is a multipart log message");
|
||||
});
|
||||
|
||||
xit("should work on IE without console.log.apply", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("duplicate example names", function() {
|
||||
127
spec/node_suite.js
Normal file
@@ -0,0 +1,127 @@
|
||||
var fs = require('fs');
|
||||
var sys = require('sys');
|
||||
var path = require('path');
|
||||
|
||||
// yes, really keep this here to keep us honest, but only for jasmine's own runner! [xw]
|
||||
// undefined = "diz be undefined yo";
|
||||
|
||||
|
||||
var jasmineGlobals = require('../lib/jasmine-core/jasmine.js');
|
||||
for (var k in jasmineGlobals) {
|
||||
global[k] = jasmineGlobals[k];
|
||||
}
|
||||
require('../src/console/ConsoleReporter.js');
|
||||
|
||||
/*
|
||||
Pulling in code from jasmine-node.
|
||||
|
||||
We can't just depend on jasmine-node because it has its own jasmine that it uses.
|
||||
*/
|
||||
|
||||
global.window = {
|
||||
setTimeout: setTimeout,
|
||||
clearTimeout: clearTimeout,
|
||||
setInterval: setInterval,
|
||||
clearInterval: clearInterval
|
||||
};
|
||||
|
||||
delete global.window;
|
||||
|
||||
function noop() {
|
||||
}
|
||||
|
||||
jasmine.executeSpecs = function(specs, done, isVerbose, showColors) {
|
||||
for (var i = 0, len = specs.length; i < len; ++i) {
|
||||
var filename = specs[i];
|
||||
require(filename.replace(/\.\w+$/, ""));
|
||||
}
|
||||
|
||||
var jasmineEnv = jasmine.getEnv();
|
||||
var consoleReporter = new jasmine.ConsoleReporter(sys.print, done, showColors);
|
||||
|
||||
jasmineEnv.addReporter(consoleReporter);
|
||||
jasmineEnv.execute();
|
||||
};
|
||||
|
||||
jasmine.getAllSpecFiles = function(dir, matcher) {
|
||||
var specs = [];
|
||||
|
||||
if (fs.statSync(dir).isFile() && dir.match(matcher)) {
|
||||
specs.push(dir);
|
||||
} else {
|
||||
var files = fs.readdirSync(dir);
|
||||
for (var i = 0, len = files.length; i < len; ++i) {
|
||||
var filename = dir + '/' + files[i];
|
||||
if (fs.statSync(filename).isFile() && filename.match(matcher)) {
|
||||
specs.push(filename);
|
||||
} else if (fs.statSync(filename).isDirectory()) {
|
||||
var subfiles = this.getAllSpecFiles(filename, matcher);
|
||||
subfiles.forEach(function(result) {
|
||||
specs.push(result);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return specs;
|
||||
};
|
||||
|
||||
function now() {
|
||||
return new Date().getTime();
|
||||
}
|
||||
|
||||
jasmine.asyncSpecWait = function() {
|
||||
var wait = jasmine.asyncSpecWait;
|
||||
wait.start = now();
|
||||
wait.done = false;
|
||||
(function innerWait() {
|
||||
waits(10);
|
||||
runs(function() {
|
||||
if (wait.start + wait.timeout < now()) {
|
||||
expect('timeout waiting for spec').toBeNull();
|
||||
} else if (wait.done) {
|
||||
wait.done = false;
|
||||
} else {
|
||||
innerWait();
|
||||
}
|
||||
});
|
||||
})();
|
||||
};
|
||||
jasmine.asyncSpecWait.timeout = 4 * 1000;
|
||||
jasmine.asyncSpecDone = function() {
|
||||
jasmine.asyncSpecWait.done = true;
|
||||
};
|
||||
|
||||
for (var key in jasmine) {
|
||||
exports[key] = jasmine[key];
|
||||
}
|
||||
|
||||
/*
|
||||
End jasmine-node runner
|
||||
*/
|
||||
|
||||
var isVerbose = false;
|
||||
var showColors = true;
|
||||
process.argv.forEach(function(arg) {
|
||||
switch (arg) {
|
||||
case '--color': showColors = true; break;
|
||||
case '--noColor': showColors = false; break;
|
||||
case '--verbose': isVerbose = true; break;
|
||||
}
|
||||
});
|
||||
|
||||
var specs = jasmine.getAllSpecFiles(__dirname, new RegExp(".js$"));
|
||||
var domIndependentSpecs = [];
|
||||
for (var i = 0; i < specs.length; i++) {
|
||||
if (fs.readFileSync(specs[i], "utf8").indexOf("document.createElement") < 0) {
|
||||
domIndependentSpecs.push(specs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
jasmine.executeSpecs(domIndependentSpecs, function(runner, log) {
|
||||
if (runner.results().failedCount === 0) {
|
||||
process.exit(0);
|
||||
} else {
|
||||
process.exit(1);
|
||||
}
|
||||
}, isVerbose, showColors);
|
||||
@@ -2,57 +2,46 @@
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Jasmine Test Runner</title>
|
||||
<title>Jasmine Spec Runner: Jasmine Core</title>
|
||||
|
||||
<link rel="shortcut icon" type="image/png" href="../images/jasmine_favicon.png">
|
||||
|
||||
<link href="../lib/jasmine-core/jasmine.css" rel="stylesheet"/>
|
||||
<script type="text/javascript" src="../lib/jasmine-core/jasmine.js"></script>
|
||||
<script type="text/javascript">
|
||||
// yes, really keep this here to keep us honest, but only for jasmine's own runner! [xw]
|
||||
undefined = "diz be undefined yo";
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="../src/base.js"></script>
|
||||
<script type="text/javascript" src="../src/util.js"></script>
|
||||
<script type="text/javascript" src="../src/Env.js"></script>
|
||||
<script type="text/javascript" src="../src/Reporter.js"></script>
|
||||
<script type="text/javascript" src="../src/Block.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../src/JsApiReporter.js"></script>
|
||||
<script type="text/javascript" src="../src/Matchers.js"></script>
|
||||
<script type="text/javascript" src="../src/mock-timeout.js"></script>
|
||||
<script type="text/javascript" src="../src/MultiReporter.js"></script>
|
||||
<script type="text/javascript" src="../src/NestedResults.js"></script>
|
||||
<script type="text/javascript" src="../src/PrettyPrinter.js"></script>
|
||||
<script type="text/javascript" src="../src/Queue.js"></script>
|
||||
<script type="text/javascript" src="../src/Runner.js"></script>
|
||||
<script type="text/javascript" src="../src/Spec.js"></script>
|
||||
<script type="text/javascript" src="../src/Suite.js"></script>
|
||||
<script type="text/javascript" src="../src/WaitsBlock.js"></script>
|
||||
<script type="text/javascript" src="../src/WaitsForBlock.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../src/html/TrivialReporter.js"></script>
|
||||
<script type="text/javascript" src="../lib/consolex.js"></script>
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript" src="suites/BaseSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/CustomMatchersSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/EnvSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/ExceptionsSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/JsApiReporterSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/MatchersSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/MockClockSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/MultiReporterSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/NestedResultsSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/PrettyPrintSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/ReporterSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/RunnerSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/QueueSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/SpecSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/SpecRunningSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/SpySpec.js"></script>
|
||||
<script type="text/javascript" src="suites/SuiteSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/TrivialReporterSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/WaitsForBlockSpec.js"></script>
|
||||
<!-- include source files here... -->
|
||||
<script type="text/javascript" src=".././src/html/TrivialReporter.js"></script>
|
||||
<script type="text/javascript" src=".././src/console/ConsoleReporter.js"></script>
|
||||
|
||||
<!-- include spec files here... -->
|
||||
<script type="text/javascript" src=".././spec/core/BaseSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/CustomMatchersSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/EnvSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/ExceptionsSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/JsApiReporterSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/MatchersSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/MockClockSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/MultiReporterSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/NestedResultsSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/PrettyPrintSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/QueueSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/ReporterSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/RunnerSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/SpecRunningSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/SpecSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/SpySpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/SuiteSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/UtilSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/WaitsForBlockSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/html/MatchersHtmlSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/html/PrettyPrintHtmlSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/html/TrivialReporterSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/console/ConsoleReporterSpec.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
@@ -67,15 +56,24 @@
|
||||
return trivialReporter.specFilter(spec);
|
||||
};
|
||||
|
||||
var currentWindowOnload = window.onload;
|
||||
|
||||
window.onload = function() {
|
||||
jasmineEnv.execute();
|
||||
if (currentWindowOnload) {
|
||||
currentWindowOnload();
|
||||
}
|
||||
execJasmine();
|
||||
};
|
||||
|
||||
function execJasmine() {
|
||||
jasmineEnv.execute();
|
||||
}
|
||||
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link href="../src/html/jasmine.css" rel="stylesheet"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
49
spec/templates/runner.html.erb
Normal file
@@ -0,0 +1,49 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title><%= title %></title>
|
||||
|
||||
<%= favicon %>
|
||||
<%= jasmine_tags %>
|
||||
|
||||
<!-- include source files here... -->
|
||||
<%= source_tags %>
|
||||
|
||||
<!-- include spec files here... -->
|
||||
<%= spec_file_tags %>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var jasmineEnv = jasmine.getEnv();
|
||||
jasmineEnv.updateInterval = 1000;
|
||||
|
||||
var trivialReporter = new jasmine.TrivialReporter();
|
||||
|
||||
jasmineEnv.addReporter(trivialReporter);
|
||||
|
||||
jasmineEnv.specFilter = function(spec) {
|
||||
return trivialReporter.specFilter(spec);
|
||||
};
|
||||
|
||||
var currentWindowOnload = window.onload;
|
||||
|
||||
window.onload = function() {
|
||||
if (currentWindowOnload) {
|
||||
currentWindowOnload();
|
||||
}
|
||||
execJasmine();
|
||||
};
|
||||
|
||||
function execJasmine() {
|
||||
jasmineEnv.execute();
|
||||
}
|
||||
|
||||
})();
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
1
spec/templates/script_tag.html.erb
Normal file
@@ -0,0 +1 @@
|
||||
<script type="text/javascript" src="<%= file %>"></script>
|
||||
7
src/SourcesList.json
Normal file
@@ -0,0 +1,7 @@
|
||||
[
|
||||
"base.js",
|
||||
"util.js",
|
||||
"Env.js",
|
||||
"Reporter.js",
|
||||
"Block.js"
|
||||
]
|
||||
@@ -1,37 +0,0 @@
|
||||
jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {
|
||||
this.timeout = timeout;
|
||||
this.latchFunction = latchFunction;
|
||||
this.message = message;
|
||||
this.totalTimeSpentWaitingForLatch = 0;
|
||||
jasmine.Block.call(this, env, null, spec);
|
||||
};
|
||||
|
||||
jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
|
||||
|
||||
jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 100;
|
||||
|
||||
jasmine.WaitsForBlock.prototype.execute = function (onComplete) {
|
||||
var self = this;
|
||||
self.env.reporter.log('>> Jasmine waiting for ' + (self.message || 'something to happen'));
|
||||
var latchFunctionResult;
|
||||
try {
|
||||
latchFunctionResult = self.latchFunction.apply(self.spec);
|
||||
} catch (e) {
|
||||
self.spec.fail(e);
|
||||
onComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
if (latchFunctionResult) {
|
||||
onComplete();
|
||||
} else if (self.totalTimeSpentWaitingForLatch >= self.timeout) {
|
||||
var message = 'timed out after ' + self.timeout + ' msec waiting for ' + (self.message || 'something to happen');
|
||||
self.spec.fail({
|
||||
name: 'timeout',
|
||||
message: message
|
||||
});
|
||||
} else {
|
||||
self.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;
|
||||
self.env.setTimeout(function () { self.execute(onComplete); }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
|
||||
}
|
||||
};
|
||||
177
src/console/ConsoleReporter.js
Normal file
@@ -0,0 +1,177 @@
|
||||
jasmine.ConsoleReporter = function(print, doneCallback, showColors) {
|
||||
//inspired by mhevery's jasmine-node reporter
|
||||
//https://github.com/mhevery/jasmine-node
|
||||
|
||||
doneCallback = doneCallback || function() {};
|
||||
|
||||
var ansi = {
|
||||
green: '\033[32m',
|
||||
red: '\033[31m',
|
||||
yellow: '\033[33m',
|
||||
none: '\033[0m'
|
||||
},
|
||||
language = {
|
||||
spec: "spec",
|
||||
failure: "failure"
|
||||
};
|
||||
|
||||
function coloredStr(color, str) {
|
||||
return showColors ? (ansi[color] + str + ansi.none) : str;
|
||||
}
|
||||
|
||||
function greenStr(str) {
|
||||
return coloredStr("green", str);
|
||||
}
|
||||
|
||||
function redStr(str) {
|
||||
return coloredStr("red", str);
|
||||
}
|
||||
|
||||
function yellowStr(str) {
|
||||
return coloredStr("yellow", str);
|
||||
}
|
||||
|
||||
function newline() {
|
||||
print("\n");
|
||||
}
|
||||
|
||||
function started() {
|
||||
print("Started");
|
||||
newline();
|
||||
}
|
||||
|
||||
function greenDot() {
|
||||
print(greenStr("."));
|
||||
}
|
||||
|
||||
function redF() {
|
||||
print(redStr("F"));
|
||||
}
|
||||
|
||||
function yellowStar() {
|
||||
print(yellowStr("*"));
|
||||
}
|
||||
|
||||
function plural(str, count) {
|
||||
return count == 1 ? str : str + "s";
|
||||
}
|
||||
|
||||
function repeat(thing, times) {
|
||||
var arr = [];
|
||||
for (var i = 0; i < times; i++) {
|
||||
arr.push(thing);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
function indent(str, spaces) {
|
||||
var lines = (str || '').split("\n");
|
||||
var newArr = [];
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
newArr.push(repeat(" ", spaces).join("") + lines[i]);
|
||||
}
|
||||
return newArr.join("\n");
|
||||
}
|
||||
|
||||
function specFailureDetails(suiteDescription, specDescription, stackTraces) {
|
||||
newline();
|
||||
print(suiteDescription + " " + specDescription);
|
||||
newline();
|
||||
for (var i = 0; i < stackTraces.length; i++) {
|
||||
print(indent(stackTraces[i], 2));
|
||||
newline();
|
||||
}
|
||||
}
|
||||
|
||||
function finished(elapsed) {
|
||||
newline();
|
||||
print("Finished in " + elapsed / 1000 + " seconds");
|
||||
}
|
||||
|
||||
function summary(colorF, specs, failed) {
|
||||
newline();
|
||||
print(colorF(specs + " " + plural(language.spec, specs) + ", " +
|
||||
failed + " " + plural(language.failure, failed)));
|
||||
newline();
|
||||
newline();
|
||||
}
|
||||
|
||||
function greenSummary(specs, failed) {
|
||||
summary(greenStr, specs, failed);
|
||||
}
|
||||
|
||||
function redSummary(specs, failed) {
|
||||
summary(redStr, specs, failed);
|
||||
}
|
||||
|
||||
function fullSuiteDescription(suite) {
|
||||
var fullDescription = suite.description;
|
||||
if (suite.parentSuite) fullDescription = fullSuiteDescription(suite.parentSuite) + " " + fullDescription;
|
||||
return fullDescription;
|
||||
}
|
||||
|
||||
this.now = function() {
|
||||
return new Date().getTime();
|
||||
};
|
||||
|
||||
this.reportRunnerStarting = function() {
|
||||
this.runnerStartTime = this.now();
|
||||
started();
|
||||
};
|
||||
|
||||
this.reportSpecStarting = function() { /* do nothing */
|
||||
};
|
||||
|
||||
this.reportSpecResults = function(spec) {
|
||||
var results = spec.results();
|
||||
if (results.skipped) {
|
||||
yellowStar();
|
||||
} else if (results.passed()) {
|
||||
greenDot();
|
||||
} else {
|
||||
redF();
|
||||
}
|
||||
};
|
||||
|
||||
this.suiteResults = [];
|
||||
|
||||
this.reportSuiteResults = function(suite) {
|
||||
var suiteResult = {
|
||||
description: fullSuiteDescription(suite),
|
||||
failedSpecResults: []
|
||||
};
|
||||
|
||||
suite.results().items_.forEach(function(spec) {
|
||||
if (spec.failedCount > 0 && spec.description) suiteResult.failedSpecResults.push(spec);
|
||||
});
|
||||
|
||||
this.suiteResults.push(suiteResult);
|
||||
};
|
||||
|
||||
function eachSpecFailure(suiteResults, callback) {
|
||||
for (var i = 0; i < suiteResults.length; i++) {
|
||||
var suiteResult = suiteResults[i];
|
||||
for (var j = 0; j < suiteResult.failedSpecResults.length; j++) {
|
||||
var failedSpecResult = suiteResult.failedSpecResults[j];
|
||||
var stackTraces = [];
|
||||
for (var k = 0; k < failedSpecResult.items_.length; k++) stackTraces.push(failedSpecResult.items_[k].trace.stack);
|
||||
callback(suiteResult.description, failedSpecResult.description, stackTraces);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.reportRunnerResults = function(runner) {
|
||||
newline();
|
||||
|
||||
eachSpecFailure(this.suiteResults, function(suiteDescription, specDescription, stackTraces) {
|
||||
specFailureDetails(suiteDescription, specDescription, stackTraces);
|
||||
});
|
||||
|
||||
finished(this.now() - this.runnerStartTime);
|
||||
|
||||
var results = runner.results();
|
||||
var summaryFunction = results.failedCount === 0 ? greenSummary : redSummary;
|
||||
summaryFunction(runner.specs().length, results.failedCount);
|
||||
doneCallback(runner);
|
||||
};
|
||||
};
|
||||
@@ -19,4 +19,4 @@ jasmine.Block.prototype.execute = function(onComplete) {
|
||||
this.spec.fail(e);
|
||||
}
|
||||
onComplete();
|
||||
};
|
||||
};
|
||||
@@ -11,6 +11,7 @@ jasmine.Env = function() {
|
||||
this.reporter = new jasmine.MultiReporter();
|
||||
|
||||
this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL;
|
||||
this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL;
|
||||
this.lastUpdate = 0;
|
||||
this.specFilter = function() {
|
||||
return true;
|
||||
@@ -50,12 +51,17 @@ jasmine.Env.prototype.version = function () {
|
||||
* @returns string containing jasmine version build info, if set.
|
||||
*/
|
||||
jasmine.Env.prototype.versionString = function() {
|
||||
if (jasmine.version_) {
|
||||
var version = this.version();
|
||||
return version.major + "." + version.minor + "." + version.build + " revision " + version.revision;
|
||||
} else {
|
||||
if (!jasmine.version_) {
|
||||
return "version unknown";
|
||||
}
|
||||
|
||||
var version = this.version();
|
||||
var versionString = version.major + "." + version.minor + "." + version.build;
|
||||
if (version.release_candidate) {
|
||||
versionString += ".rc" + version.release_candidate;
|
||||
}
|
||||
versionString += " revision " + version.revision;
|
||||
return versionString;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -103,14 +109,14 @@ jasmine.Env.prototype.describe = function(description, specDefinitions) {
|
||||
declarationError = e;
|
||||
}
|
||||
|
||||
this.currentSuite = parentSuite;
|
||||
|
||||
if (declarationError) {
|
||||
this.it("encountered a declaration exception", function() {
|
||||
throw declarationError;
|
||||
});
|
||||
}
|
||||
|
||||
this.currentSuite = parentSuite;
|
||||
|
||||
return suite;
|
||||
};
|
||||
|
||||
@@ -171,7 +177,7 @@ jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchVal
|
||||
b.__Jasmine_been_here_before__ = a;
|
||||
|
||||
var hasKey = function(obj, keyName) {
|
||||
return obj != null && obj[keyName] !== jasmine.undefined;
|
||||
return obj !== null && obj[keyName] !== jasmine.undefined;
|
||||
};
|
||||
|
||||
for (var property in b) {
|
||||
@@ -197,7 +203,7 @@ jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchVal
|
||||
|
||||
delete a.__Jasmine_been_here_before__;
|
||||
delete b.__Jasmine_been_here_before__;
|
||||
return (mismatchKeys.length == 0 && mismatchValues.length == 0);
|
||||
return (mismatchKeys.length === 0 && mismatchValues.length === 0);
|
||||
};
|
||||
|
||||
jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
|
||||
@@ -68,7 +68,7 @@ jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {
|
||||
message: message
|
||||
});
|
||||
this.spec.addMatcherResult(expectationResult);
|
||||
return result;
|
||||
return jasmine.undefined;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -86,6 +86,7 @@ jasmine.Matchers.prototype.toBe = function(expected) {
|
||||
/**
|
||||
* toNotBe: compares the actual to the expected using !==
|
||||
* @param expected
|
||||
* @deprecated as of 1.0. Use not.toBe() instead.
|
||||
*/
|
||||
jasmine.Matchers.prototype.toNotBe = function(expected) {
|
||||
return this.actual !== expected;
|
||||
@@ -103,6 +104,7 @@ jasmine.Matchers.prototype.toEqual = function(expected) {
|
||||
/**
|
||||
* toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual
|
||||
* @param expected
|
||||
* @deprecated as of 1.0. Use not.toNotEqual() instead.
|
||||
*/
|
||||
jasmine.Matchers.prototype.toNotEqual = function(expected) {
|
||||
return !this.env.equals_(this.actual, expected);
|
||||
@@ -121,6 +123,7 @@ jasmine.Matchers.prototype.toMatch = function(expected) {
|
||||
/**
|
||||
* Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch
|
||||
* @param expected
|
||||
* @deprecated as of 1.0. Use not.toMatch() instead.
|
||||
*/
|
||||
jasmine.Matchers.prototype.toNotMatch = function(expected) {
|
||||
return !(new RegExp(expected).test(this.actual));
|
||||
@@ -163,11 +166,6 @@ jasmine.Matchers.prototype.toBeFalsy = function() {
|
||||
};
|
||||
|
||||
|
||||
/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */
|
||||
jasmine.Matchers.prototype.wasCalled = function() {
|
||||
return this.toHaveBeenCalled();
|
||||
};
|
||||
|
||||
/**
|
||||
* Matcher that checks to see if the actual, a Jasmine spy, was called.
|
||||
*/
|
||||
@@ -181,12 +179,18 @@ jasmine.Matchers.prototype.toHaveBeenCalled = function() {
|
||||
}
|
||||
|
||||
this.message = function() {
|
||||
return "Expected spy " + this.actual.identity + " to have been called.";
|
||||
return [
|
||||
"Expected spy " + this.actual.identity + " to have been called.",
|
||||
"Expected spy " + this.actual.identity + " not to have been called."
|
||||
];
|
||||
};
|
||||
|
||||
return this.actual.wasCalled;
|
||||
};
|
||||
|
||||
/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */
|
||||
jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled;
|
||||
|
||||
/**
|
||||
* Matcher that checks to see if the actual, a Jasmine spy, was not called.
|
||||
*
|
||||
@@ -202,17 +206,15 @@ jasmine.Matchers.prototype.wasNotCalled = function() {
|
||||
}
|
||||
|
||||
this.message = function() {
|
||||
return "Expected spy " + this.actual.identity + " to not have been called.";
|
||||
return [
|
||||
"Expected spy " + this.actual.identity + " to not have been called.",
|
||||
"Expected spy " + this.actual.identity + " to have been called."
|
||||
];
|
||||
};
|
||||
|
||||
return !this.actual.wasCalled;
|
||||
};
|
||||
|
||||
/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */
|
||||
jasmine.Matchers.prototype.wasCalledWith = function() {
|
||||
return this.toHaveBeenCalledWith.apply(this, arguments);
|
||||
};
|
||||
|
||||
/**
|
||||
* Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters.
|
||||
*
|
||||
@@ -225,16 +227,26 @@ jasmine.Matchers.prototype.toHaveBeenCalledWith = function() {
|
||||
throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
|
||||
}
|
||||
this.message = function() {
|
||||
if (this.actual.callCount == 0) {
|
||||
return "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.";
|
||||
if (this.actual.callCount === 0) {
|
||||
// todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw]
|
||||
return [
|
||||
"Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.",
|
||||
"Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was."
|
||||
];
|
||||
} else {
|
||||
return "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall);
|
||||
return [
|
||||
"Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall),
|
||||
"Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall)
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
return this.env.contains_(this.actual.argsForCall, expectedArgs);
|
||||
};
|
||||
|
||||
/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */
|
||||
jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith;
|
||||
|
||||
/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */
|
||||
jasmine.Matchers.prototype.wasNotCalledWith = function() {
|
||||
var expectedArgs = jasmine.util.argsToArray(arguments);
|
||||
@@ -243,7 +255,10 @@ jasmine.Matchers.prototype.wasNotCalledWith = function() {
|
||||
}
|
||||
|
||||
this.message = function() {
|
||||
return "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was";
|
||||
return [
|
||||
"Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was",
|
||||
"Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was"
|
||||
];
|
||||
};
|
||||
|
||||
return !this.env.contains_(this.actual.argsForCall, expectedArgs);
|
||||
@@ -262,6 +277,7 @@ jasmine.Matchers.prototype.toContain = function(expected) {
|
||||
* Matcher that checks that the expected item is NOT an element in the actual Array.
|
||||
*
|
||||
* @param {Object} expected
|
||||
* @deprecated as of 1.0. Use not.toNotContain() instead.
|
||||
*/
|
||||
jasmine.Matchers.prototype.toNotContain = function(expected) {
|
||||
return !this.env.contains_(this.actual, expected);
|
||||
@@ -275,6 +291,23 @@ jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
|
||||
return this.actual > expected;
|
||||
};
|
||||
|
||||
/**
|
||||
* Matcher that checks that the expected item is equal to the actual item
|
||||
* up to a given level of decimal precision (default 2).
|
||||
*
|
||||
* @param {Number} expected
|
||||
* @param {Number} precision
|
||||
*/
|
||||
jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {
|
||||
if (!(precision === 0)) {
|
||||
precision = precision || 2;
|
||||
}
|
||||
var multiplier = Math.pow(10, precision);
|
||||
var actual = Math.round(this.actual * multiplier);
|
||||
expected = Math.round(expected * multiplier);
|
||||
return expected == actual;
|
||||
};
|
||||
|
||||
/**
|
||||
* Matcher that checks that the expected exception was thrown by the actual.
|
||||
*
|
||||
@@ -295,9 +328,11 @@ jasmine.Matchers.prototype.toThrow = function(expected) {
|
||||
result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));
|
||||
}
|
||||
|
||||
var not = this.isNot ? "not " : "";
|
||||
|
||||
this.message = function() {
|
||||
if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
|
||||
return ["Expected function to throw", expected.message || expected, ", but it threw", exception.message || exception].join(' ');
|
||||
return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' ');
|
||||
} else {
|
||||
return "Expected function to throw an exception.";
|
||||
}
|
||||
@@ -58,7 +58,8 @@ jasmine.PrettyPrinter.prototype.format = function(value) {
|
||||
jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
|
||||
for (var property in obj) {
|
||||
if (property == '__Jasmine_been_here_before__') continue;
|
||||
fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) != null) : false);
|
||||
fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined &&
|
||||
obj.__lookupGetter__(property) !== null) : false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4,6 +4,7 @@ jasmine.Queue = function(env) {
|
||||
this.running = false;
|
||||
this.index = 0;
|
||||
this.offset = 0;
|
||||
this.abort = false;
|
||||
};
|
||||
|
||||
jasmine.Queue.prototype.addBefore = function(block) {
|
||||
@@ -38,7 +39,7 @@ jasmine.Queue.prototype.next_ = function() {
|
||||
while (goAgain) {
|
||||
goAgain = false;
|
||||
|
||||
if (self.index < self.blocks.length) {
|
||||
if (self.index < self.blocks.length && !this.abort) {
|
||||
var calledSynchronously = true;
|
||||
var completedSynchronously = false;
|
||||
|
||||
@@ -48,6 +49,10 @@ jasmine.Queue.prototype.next_ = function() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.blocks[self.index].abort) {
|
||||
self.abort = true;
|
||||
}
|
||||
|
||||
self.offset = 0;
|
||||
self.index++;
|
||||
|
||||
@@ -74,4 +74,4 @@ jasmine.Runner.prototype.topLevelSuites = function() {
|
||||
|
||||
jasmine.Runner.prototype.results = function() {
|
||||
return this.queue.results();
|
||||
};
|
||||
};
|
||||
@@ -73,14 +73,46 @@ jasmine.Spec.prototype.expect = function(actual) {
|
||||
return positive;
|
||||
};
|
||||
|
||||
/**
|
||||
* Waits a fixed time period before moving to the next block.
|
||||
*
|
||||
* @deprecated Use waitsFor() instead
|
||||
* @param {Number} timeout milliseconds to wait
|
||||
*/
|
||||
jasmine.Spec.prototype.waits = function(timeout) {
|
||||
var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);
|
||||
this.addToQueue(waitsFunc);
|
||||
return this;
|
||||
};
|
||||
|
||||
jasmine.Spec.prototype.waitsFor = function(timeout, latchFunction, timeoutMessage) {
|
||||
var waitsForFunc = new jasmine.WaitsForBlock(this.env, timeout, latchFunction, timeoutMessage, this);
|
||||
/**
|
||||
* Waits for the latchFunction to return true before proceeding to the next block.
|
||||
*
|
||||
* @param {Function} latchFunction
|
||||
* @param {String} optional_timeoutMessage
|
||||
* @param {Number} optional_timeout
|
||||
*/
|
||||
jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
|
||||
var latchFunction_ = null;
|
||||
var optional_timeoutMessage_ = null;
|
||||
var optional_timeout_ = null;
|
||||
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
var arg = arguments[i];
|
||||
switch (typeof arg) {
|
||||
case 'function':
|
||||
latchFunction_ = arg;
|
||||
break;
|
||||
case 'string':
|
||||
optional_timeoutMessage_ = arg;
|
||||
break;
|
||||
case 'number':
|
||||
optional_timeout_ = arg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this);
|
||||
this.addToQueue(waitsForFunc);
|
||||
return this;
|
||||
};
|
||||
@@ -88,7 +120,8 @@ jasmine.Spec.prototype.waitsFor = function(timeout, latchFunction, timeoutMessag
|
||||
jasmine.Spec.prototype.fail = function (e) {
|
||||
var expectationResult = new jasmine.ExpectationResult({
|
||||
passed: false,
|
||||
message: e ? jasmine.util.formatException(e) : 'Exception'
|
||||
message: e ? jasmine.util.formatException(e) : 'Exception',
|
||||
trace: { stack: e.stack }
|
||||
});
|
||||
this.results_.addResult(expectationResult);
|
||||
};
|
||||
@@ -79,4 +79,4 @@ jasmine.Suite.prototype.execute = function(onComplete) {
|
||||
this.queue.start(function () {
|
||||
self.finish(onComplete);
|
||||
});
|
||||
};
|
||||
};
|
||||
@@ -6,7 +6,9 @@ jasmine.WaitsBlock = function(env, timeout, spec) {
|
||||
jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
|
||||
|
||||
jasmine.WaitsBlock.prototype.execute = function (onComplete) {
|
||||
this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
|
||||
if (jasmine.VERBOSE) {
|
||||
this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
|
||||
}
|
||||
this.env.setTimeout(function () {
|
||||
onComplete();
|
||||
}, this.timeout);
|
||||
54
src/core/WaitsForBlock.js
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* A block which waits for some condition to become true, with timeout.
|
||||
*
|
||||
* @constructor
|
||||
* @extends jasmine.Block
|
||||
* @param {jasmine.Env} env The Jasmine environment.
|
||||
* @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true.
|
||||
* @param {Function} latchFunction A function which returns true when the desired condition has been met.
|
||||
* @param {String} message The message to display if the desired condition hasn't been met within the given time period.
|
||||
* @param {jasmine.Spec} spec The Jasmine spec.
|
||||
*/
|
||||
jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {
|
||||
this.timeout = timeout || env.defaultTimeoutInterval;
|
||||
this.latchFunction = latchFunction;
|
||||
this.message = message;
|
||||
this.totalTimeSpentWaitingForLatch = 0;
|
||||
jasmine.Block.call(this, env, null, spec);
|
||||
};
|
||||
jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
|
||||
|
||||
jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;
|
||||
|
||||
jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
|
||||
if (jasmine.VERBOSE) {
|
||||
this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));
|
||||
}
|
||||
var latchFunctionResult;
|
||||
try {
|
||||
latchFunctionResult = this.latchFunction.apply(this.spec);
|
||||
} catch (e) {
|
||||
this.spec.fail(e);
|
||||
onComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
if (latchFunctionResult) {
|
||||
onComplete();
|
||||
} else if (this.totalTimeSpentWaitingForLatch >= this.timeout) {
|
||||
var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen');
|
||||
this.spec.fail({
|
||||
name: 'timeout',
|
||||
message: message
|
||||
});
|
||||
|
||||
this.abort = true;
|
||||
onComplete();
|
||||
} else {
|
||||
this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;
|
||||
var self = this;
|
||||
this.env.setTimeout(function() {
|
||||
self.execute(onComplete);
|
||||
}, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
|
||||
}
|
||||
};
|
||||
@@ -1,10 +1,12 @@
|
||||
var isCommonJS = typeof window == "undefined";
|
||||
|
||||
/**
|
||||
* Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
|
||||
*
|
||||
* @namespace
|
||||
*/
|
||||
var jasmine = {};
|
||||
|
||||
if (isCommonJS) exports.jasmine = jasmine;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
@@ -21,11 +23,22 @@ jasmine.unimplementedMethod_ = function() {
|
||||
jasmine.undefined = jasmine.___undefined___;
|
||||
|
||||
/**
|
||||
* Default interval for event loop yields. Small values here may result in slow test running. Zero means no updates until all tests have completed.
|
||||
* Show diagnostic messages in the console if set to true
|
||||
*
|
||||
*/
|
||||
jasmine.VERBOSE = false;
|
||||
|
||||
/**
|
||||
* Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.
|
||||
*
|
||||
*/
|
||||
jasmine.DEFAULT_UPDATE_INTERVAL = 250;
|
||||
|
||||
/**
|
||||
* Default timeout interval in milliseconds for waitsFor() blocks.
|
||||
*/
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
|
||||
|
||||
jasmine.getGlobal = function() {
|
||||
function getGlobal() {
|
||||
return this;
|
||||
@@ -67,7 +80,7 @@ jasmine.MessageResult = function(values) {
|
||||
|
||||
jasmine.MessageResult.prototype.toString = function() {
|
||||
var text = "";
|
||||
for(var i = 0; i < this.values.length; i++) {
|
||||
for (var i = 0; i < this.values.length; i++) {
|
||||
if (i > 0) text += " ";
|
||||
if (jasmine.isString_(this.values[i])) {
|
||||
text += this.values[i];
|
||||
@@ -84,9 +97,10 @@ jasmine.ExpectationResult = function(params) {
|
||||
this.passed_ = params.passed;
|
||||
this.expected = params.expected;
|
||||
this.actual = params.actual;
|
||||
|
||||
this.message = this.passed_ ? 'Passed.' : params.message;
|
||||
this.trace = this.passed_ ? '' : new Error(this.message);
|
||||
|
||||
var trace = (params.trace || new Error(this.message));
|
||||
this.trace = this.passed_ ? '' : trace;
|
||||
};
|
||||
|
||||
jasmine.ExpectationResult.prototype.toString = function () {
|
||||
@@ -101,7 +115,8 @@ jasmine.ExpectationResult.prototype.passed = function () {
|
||||
* Getter for the Jasmine environment. Ensures one gets created
|
||||
*/
|
||||
jasmine.getEnv = function() {
|
||||
return jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
|
||||
var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
|
||||
return env;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -111,7 +126,7 @@ jasmine.getEnv = function() {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
jasmine.isArray_ = function(value) {
|
||||
return jasmine.isA_("Array", value);
|
||||
return jasmine.isA_("Array", value);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -164,7 +179,7 @@ jasmine.pp = function(value) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
jasmine.isDomNode = function(obj) {
|
||||
return obj['nodeType'] > 0;
|
||||
return obj.nodeType > 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -400,7 +415,7 @@ jasmine.isSpy = function(putativeSpy) {
|
||||
* @param {Array} methodNames array of names of methods to make spies
|
||||
*/
|
||||
jasmine.createSpyObj = function(baseName, methodNames) {
|
||||
if (!jasmine.isArray_(methodNames) || methodNames.length == 0) {
|
||||
if (!jasmine.isArray_(methodNames) || methodNames.length === 0) {
|
||||
throw new Error('createSpyObj requires a non-empty array of method names to create spies for');
|
||||
}
|
||||
var obj = {};
|
||||
@@ -438,6 +453,7 @@ jasmine.log = function() {
|
||||
var spyOn = function(obj, methodName) {
|
||||
return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
|
||||
};
|
||||
if (isCommonJS) exports.spyOn = spyOn;
|
||||
|
||||
/**
|
||||
* Creates a Jasmine spec that will be added to the current suite.
|
||||
@@ -455,6 +471,7 @@ var spyOn = function(obj, methodName) {
|
||||
var it = function(desc, func) {
|
||||
return jasmine.getEnv().it(desc, func);
|
||||
};
|
||||
if (isCommonJS) exports.it = it;
|
||||
|
||||
/**
|
||||
* Creates a <em>disabled</em> Jasmine spec.
|
||||
@@ -467,6 +484,7 @@ var it = function(desc, func) {
|
||||
var xit = function(desc, func) {
|
||||
return jasmine.getEnv().xit(desc, func);
|
||||
};
|
||||
if (isCommonJS) exports.xit = xit;
|
||||
|
||||
/**
|
||||
* Starts a chain for a Jasmine expectation.
|
||||
@@ -479,6 +497,7 @@ var xit = function(desc, func) {
|
||||
var expect = function(actual) {
|
||||
return jasmine.getEnv().currentSpec.expect(actual);
|
||||
};
|
||||
if (isCommonJS) exports.expect = expect;
|
||||
|
||||
/**
|
||||
* Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs.
|
||||
@@ -488,25 +507,30 @@ var expect = function(actual) {
|
||||
var runs = function(func) {
|
||||
jasmine.getEnv().currentSpec.runs(func);
|
||||
};
|
||||
if (isCommonJS) exports.runs = runs;
|
||||
|
||||
/**
|
||||
* Waits for a timeout before moving to the next runs()-defined block.
|
||||
* @param {Number} timeout
|
||||
* Waits a fixed time period before moving to the next block.
|
||||
*
|
||||
* @deprecated Use waitsFor() instead
|
||||
* @param {Number} timeout milliseconds to wait
|
||||
*/
|
||||
var waits = function(timeout) {
|
||||
jasmine.getEnv().currentSpec.waits(timeout);
|
||||
};
|
||||
if (isCommonJS) exports.waits = waits;
|
||||
|
||||
/**
|
||||
* Waits for the latchFunction to return true before proceeding to the next runs()-defined block.
|
||||
* Waits for the latchFunction to return true before proceeding to the next block.
|
||||
*
|
||||
* @param {Number} timeout
|
||||
* @param {Function} latchFunction
|
||||
* @param {String} message
|
||||
* @param {String} optional_timeoutMessage
|
||||
* @param {Number} optional_timeout
|
||||
*/
|
||||
var waitsFor = function(timeout, latchFunction, message) {
|
||||
jasmine.getEnv().currentSpec.waitsFor(timeout, latchFunction, message);
|
||||
var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
|
||||
jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);
|
||||
};
|
||||
if (isCommonJS) exports.waitsFor = waitsFor;
|
||||
|
||||
/**
|
||||
* A function that is called before each spec in a suite.
|
||||
@@ -518,6 +542,7 @@ var waitsFor = function(timeout, latchFunction, message) {
|
||||
var beforeEach = function(beforeEachFunction) {
|
||||
jasmine.getEnv().beforeEach(beforeEachFunction);
|
||||
};
|
||||
if (isCommonJS) exports.beforeEach = beforeEach;
|
||||
|
||||
/**
|
||||
* A function that is called after each spec in a suite.
|
||||
@@ -529,6 +554,7 @@ var beforeEach = function(beforeEachFunction) {
|
||||
var afterEach = function(afterEachFunction) {
|
||||
jasmine.getEnv().afterEach(afterEachFunction);
|
||||
};
|
||||
if (isCommonJS) exports.afterEach = afterEach;
|
||||
|
||||
/**
|
||||
* Defines a suite of specifications.
|
||||
@@ -548,6 +574,7 @@ var afterEach = function(afterEachFunction) {
|
||||
var describe = function(description, specDefinitions) {
|
||||
return jasmine.getEnv().describe(description, specDefinitions);
|
||||
};
|
||||
if (isCommonJS) exports.describe = describe;
|
||||
|
||||
/**
|
||||
* Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development.
|
||||
@@ -558,25 +585,33 @@ var describe = function(description, specDefinitions) {
|
||||
var xdescribe = function(description, specDefinitions) {
|
||||
return jasmine.getEnv().xdescribe(description, specDefinitions);
|
||||
};
|
||||
if (isCommonJS) exports.xdescribe = xdescribe;
|
||||
|
||||
|
||||
// Provide the XMLHttpRequest class for IE 5.x-6.x:
|
||||
jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() {
|
||||
try {
|
||||
function tryIt(f) {
|
||||
try {
|
||||
return f();
|
||||
} catch(e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
var xhr = tryIt(function() {
|
||||
return new ActiveXObject("Msxml2.XMLHTTP.6.0");
|
||||
} catch(e) {
|
||||
}
|
||||
try {
|
||||
return new ActiveXObject("Msxml2.XMLHTTP.3.0");
|
||||
} catch(e) {
|
||||
}
|
||||
try {
|
||||
return new ActiveXObject("Msxml2.XMLHTTP");
|
||||
} catch(e) {
|
||||
}
|
||||
try {
|
||||
return new ActiveXObject("Microsoft.XMLHTTP");
|
||||
} catch(e) {
|
||||
}
|
||||
throw new Error("This browser does not support XMLHttpRequest.");
|
||||
}) ||
|
||||
tryIt(function() {
|
||||
return new ActiveXObject("Msxml2.XMLHTTP.3.0");
|
||||
}) ||
|
||||
tryIt(function() {
|
||||
return new ActiveXObject("Msxml2.XMLHTTP");
|
||||
}) ||
|
||||
tryIt(function() {
|
||||
return new ActiveXObject("Microsoft.XMLHTTP");
|
||||
});
|
||||
|
||||
if (!xhr) throw new Error("This browser does not support XMLHttpRequest.");
|
||||
|
||||
return xhr;
|
||||
} : XMLHttpRequest;
|
||||
@@ -17,7 +17,7 @@ jasmine.util.inherit = function(childClass, parentClass) {
|
||||
var subclass = function() {
|
||||
};
|
||||
subclass.prototype = parentClass.prototype;
|
||||
childClass.prototype = new subclass;
|
||||
childClass.prototype = new subclass();
|
||||
};
|
||||
|
||||
jasmine.util.formatException = function(e) {
|
||||
@@ -34,7 +34,7 @@ jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
|
||||
this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' },
|
||||
this.createDom('div', { className: 'banner' },
|
||||
this.createDom('div', { className: 'logo' },
|
||||
"Jasmine",
|
||||
this.createDom('span', { className: 'title' }, "Jasmine"),
|
||||
this.createDom('span', { className: 'version' }, runner.env.versionString())),
|
||||
this.createDom('div', { className: 'options' },
|
||||
"Show ",
|
||||
@@ -70,16 +70,16 @@ jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
|
||||
this.startedAt = new Date();
|
||||
|
||||
var self = this;
|
||||
showPassed.onchange = function(evt) {
|
||||
if (evt.target.checked) {
|
||||
showPassed.onclick = function(evt) {
|
||||
if (showPassed.checked) {
|
||||
self.outerDiv.className += ' show-passed';
|
||||
} else {
|
||||
self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
|
||||
}
|
||||
};
|
||||
|
||||
showSkipped.onchange = function(evt) {
|
||||
if (evt.target.checked) {
|
||||
showSkipped.onclick = function(evt) {
|
||||
if (showSkipped.checked) {
|
||||
self.outerDiv.className += ' show-skipped';
|
||||
} else {
|
||||
self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
|
||||
@@ -110,7 +110,7 @@ jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
|
||||
jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
|
||||
var results = suite.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.totalCount == 0) { // todo: change this to check results.skipped
|
||||
if (results.totalCount === 0) { // todo: change this to check results.skipped
|
||||
status = 'skipped';
|
||||
}
|
||||
this.suiteDivs[suite.id].className += " " + status;
|
||||
@@ -162,7 +162,13 @@ jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
|
||||
|
||||
jasmine.TrivialReporter.prototype.log = function() {
|
||||
var console = jasmine.getGlobal().console;
|
||||
if (console && console.log) console.log.apply(console, arguments);
|
||||
if (console && console.log) {
|
||||
if (console.log.apply) {
|
||||
console.log.apply(console, arguments);
|
||||
} else {
|
||||
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.getLocation = function() {
|
||||
@@ -177,6 +183,8 @@ jasmine.TrivialReporter.prototype.specFilter = function(spec) {
|
||||
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
|
||||
}
|
||||
|
||||
if (!paramMap["spec"]) return true;
|
||||
return spec.getFullName().indexOf(paramMap["spec"]) == 0;
|
||||
if (!paramMap.spec) {
|
||||
return true;
|
||||
}
|
||||
return spec.getFullName().indexOf(paramMap.spec) === 0;
|
||||
};
|
||||
|
||||
3
src/templates/example_project_jasmine_tags.html.erb
Normal file
@@ -0,0 +1,3 @@
|
||||
<link rel="stylesheet" type="text/css" href="lib/jasmine-<%= jasmine_version %>/jasmine.css">
|
||||
<script type="text/javascript" src="lib/jasmine-<%= jasmine_version %>/jasmine.js"></script>
|
||||
<script type="text/javascript" src="lib/jasmine-<%= jasmine_version %>/jasmine-html.js"></script>
|
||||
6
src/templates/version.js.erb
Normal file
@@ -0,0 +1,6 @@
|
||||
jasmine.version_= {
|
||||
"major": <%= major %>,
|
||||
"minor": <%= minor %>,
|
||||
"build": <%= build %>,
|
||||
"revision": <%= revision %><%= %Q{,\n "release_candidate": #{release_candidate}} if release_candidate %>
|
||||
};
|
||||
6
src/templates/version.rb.erb
Normal file
@@ -0,0 +1,6 @@
|
||||
module Jasmine
|
||||
module Core
|
||||
VERSION = "<%= "#{major}.#{minor}.#{build}" %><%= ".rc#{release_candidate}" if release_candidate %>"
|
||||
end
|
||||
end
|
||||
|
||||
6
src/version.js
Normal file
@@ -0,0 +1,6 @@
|
||||
jasmine.version_= {
|
||||
"major": 1,
|
||||
"minor": 1,
|
||||
"build": 0,
|
||||
"revision": 1315677058
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"major": 0,
|
||||
"minor": 11,
|
||||
"build": 1
|
||||
"major": 1,
|
||||
"minor": 1,
|
||||
"build": 0
|
||||
}
|
||||
|
||||
48
tasks/build_dist.rb
Normal file
@@ -0,0 +1,48 @@
|
||||
desc "Build core jasmine.js"
|
||||
task :build_dist => [:lint, :write_version_files] do
|
||||
puts 'Building Jasmine distribution from source'.cyan
|
||||
|
||||
concat_into('./lib/jasmine-core/jasmine.js') { core_sources + version_source_file }
|
||||
concat_into('./lib/jasmine-core/jasmine-html.js') { html_sources }
|
||||
|
||||
FileUtils.cp('./src/html/jasmine.css', './lib/jasmine-core/jasmine.css')
|
||||
end
|
||||
|
||||
def concat_into(output_file, &block)
|
||||
files = yield
|
||||
File.open(output_file, 'w') do |out|
|
||||
files.each do |f|
|
||||
out << File.read(f)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Check jasmine sources for coding problems'
|
||||
task :lint => :require_node do
|
||||
puts "Running JSHint via Node.js".cyan
|
||||
system("node jshint/run.js") || exit(1)
|
||||
end
|
||||
|
||||
task :hint => :lint
|
||||
|
||||
task :write_version_files do
|
||||
scope = OpenStruct.new(:major => version_hash["major"],
|
||||
:minor => version_hash["minor"],
|
||||
:build => version_hash["build"],
|
||||
:release_candidate => version_hash["release_candidate"],
|
||||
:revision => Time.now.to_i)
|
||||
|
||||
js_template = Tilt.new('./src/templates/version.js.erb')
|
||||
File.open('./src/version.js', 'w+') do |f|
|
||||
f << js_template.render(scope)
|
||||
end
|
||||
|
||||
rb_template = Tilt.new('./src/templates/version.rb.erb')
|
||||
File.open('./lib/jasmine-core/version.rb', 'w+') do |f|
|
||||
f << rb_template.render(scope)
|
||||
end
|
||||
end
|
||||
|
||||
def version_source_file
|
||||
Dir.glob('src/version.js')
|
||||
end
|
||||
50
tasks/build_specs.rb
Normal file
@@ -0,0 +1,50 @@
|
||||
require 'ostruct'
|
||||
|
||||
#build the browser spec for Jasmine core based on current tree
|
||||
task :build_runner_html do
|
||||
template = Tilt.new('spec/templates/runner.html.erb')
|
||||
|
||||
File.open('spec/runner.html', 'w+') do |f|
|
||||
scope = OpenStruct.new(:title => "Jasmine Spec Runner: Jasmine Core",
|
||||
:favicon => favicon,
|
||||
:jasmine_tags => jasmine_tags,
|
||||
:source_tags => source_tags,
|
||||
:spec_file_tags => spec_file_tags)
|
||||
f << template.render(scope)
|
||||
end
|
||||
end
|
||||
|
||||
def favicon
|
||||
<<HTML
|
||||
<link rel="shortcut icon" type="image/png" href="../images/jasmine_favicon.png">
|
||||
HTML
|
||||
end
|
||||
|
||||
def jasmine_tags
|
||||
tags = %Q{<link href="../lib/jasmine-core/jasmine.css" rel="stylesheet"/>}
|
||||
tags << "\n "
|
||||
tags << script_tags_for("../lib/jasmine-core/jasmine.js")
|
||||
tags << "\n "
|
||||
tags << undefined_catch
|
||||
tags
|
||||
end
|
||||
|
||||
def undefined_catch
|
||||
<<HTML
|
||||
<script type="text/javascript">
|
||||
// yes, really keep this here to keep us honest, but only for jasmine's own runner! [xw]
|
||||
undefined = "diz be undefined yo";
|
||||
</script>
|
||||
HTML
|
||||
end
|
||||
|
||||
def source_tags
|
||||
other_files = html_sources + console_sources
|
||||
script_tags_for other_files.collect { |f| "../#{f}" }
|
||||
end
|
||||
|
||||
def spec_file_tags
|
||||
spec_files = core_specfiles + html_specfiles + console_specfiles
|
||||
script_tags_for spec_files.collect { |f| "../#{f}" }
|
||||
end
|
||||
|
||||