Doc fixes. Really, markdown? Really?

This commit is contained in:
ragaskar 2009-03-01 05:47:02 -08:00
parent 2c8c3464b2
commit 9404716322
1 changed files with 69 additions and 51 deletions

View File

@ -1,11 +1,11 @@
Jasmine
Jasmine
=======
**YET ANOTHER JavaScript testing framework**
Why Another Frickin' JS TDD/BDD Framework?
-----------
There are some situations when you want to test-drive JavaScript, but you don't want to be bothered with or even have an explicit document. You have no DOM to work with and thus lack HTML elements on which to hang event handlers. You may need to make asynchronous calls (say, to an AJAX API) and cannot mock/stub them.
There are some situations when you want to test-drive JavaScript, but you don't want to be bothered with or even have an explicit document. You have no DOM to work with and thus lack HTML elements on which to hang event handlers. You may need to make asynchronous calls (say, to an AJAX API) and cannot mock/stub them.
But you still need to write tests.
@ -41,7 +41,7 @@ Within your spec you will want/need to make expectations. These are made like t
it('should be a test', function () {
var foo = 0
foo++;
expect(foo).toEqual(1);
});
@ -55,7 +55,7 @@ Well, say you need to make a call that is asynchronous - an AJAX API, or some ot
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:
`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 () {
@ -65,7 +65,7 @@ Jasmine allows you to do this with `runs()` and `waits()` blocks.
expect(foo).toEqual(1);
});
and
and
it('should be a test', function () {
runs( function () {
@ -76,7 +76,7 @@ Jasmine allows you to do this with `runs()` and `waits()` blocks.
});
});
multiple `runs()` blocks in a spec will run serially. For example,
multiple `runs()` blocks in a spec will run serially. For example,
it('should be a test', function () {
runs( function () {
@ -93,7 +93,7 @@ Jasmine allows you to do this with `runs()` and `waits()` blocks.
});
});
`runs()` blocks share functional scope -- `this` properties will be common to all blocks, but simple vars will not!
`runs()` blocks share functional scope -- `this` properties will be common to all blocks, but simple `vars` will not!
it('should be a test', function () {
runs( function () {
@ -115,8 +115,8 @@ Jasmine allows you to do this with `runs()` and `waits()` blocks.
});
});
`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:
`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 () {
@ -129,7 +129,7 @@ Jasmine allows you to do this with `runs()` and `waits()` blocks.
runs(function () {
this.expects_that(this.foo).should_equal(0);
});
});
waits(500);
@ -138,22 +138,22 @@ Jasmine allows you to do this with `runs()` and `waits()` blocks.
});
});
What's happening here?
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.
* 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`.
### 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 a test', function () {
...
});
});
it('has another test', function () {
...
@ -196,7 +196,7 @@ Here's the example HTML file (in `jasmine/example`):
### Reports
If a reporter exists on the Jasmine instance (named `jasmine`), it will be called when each spec, suite and the overall runner complete. If you're at the single-spec result level, you'll get a spec description, whether it passed or failed, and what the failure message was. At the suite & runner report level, you'll get the total specs run so far, the passed counts, failed counts, and a description (of the suite or runner).
If a reporter exists on the Jasmine instance (named `jasmine`), it will be called when each spec, suite and the overall runner complete. If you're at the single-spec result level, you'll get a spec description, whether it passed or failed, and what the failure message was. At the suite & runner report level, you'll get the total specs run so far, the passed counts, failed counts, and a description (of the suite or runner).
There is a `Jasmine.Reporters` namespace for you to see how to handle reporting. See the file `json_reporter.js`, which takes the results objects and turns them into JSON strings, for two examples of how to make the results callbacks work for you.
@ -205,17 +205,29 @@ There is a `Jasmine.Reporters` namespace for you to see how to handle reporting.
Jasmine has several matchers:
`toEqual` compares objects or primitives and returns true if they are equal
`toNotEqual` compares objects or primitives and returns true if they are not equal
`toMatch` takes a regex or a string and returns true if it matches
`toNotMatch` takes a regex or a string and returns true if it does not match
`toBeDefined` returns true if the object or primitive is not `undefined`
`toBeNull` returns true if the object or primitive is not `null`
`toBeTruthy` returns true if the object or primitive evaluates to true
`toBeFalsy` returns true if the object or primitive evaluates to false
`wasCalled` returns true if the object is a spy and was called
`wasNotCalled` returns true if the object is a spy and was not called
`wasNotCalledWith` returns true if the object is a spy and was called with the passed arguments
`toContain` returns true if an array or string contains the passed variable.
`toNotContain` returns true if an array or string does not contain the passed variable.
### Writing new Matchers
@ -225,7 +237,7 @@ A Matcher has a method name, takes an expected value as it's only parameter, has
return this.report((this.actual === expected),
'Expected ' + expected + ' but got ' + this.actual + '.');
});
Feel free to define your own matcher as needed in your code. If you'd like to add Matchers to Jasmine, please write tests.
### Disabling Tests & Suites
@ -237,79 +249,85 @@ suites may be disabled by calling `xdescribe()` instead of `describe()`
beforeEach takes a function that is run before each spec. For example:
describe('some suite', function () {
describe('some suite', function () {
var suiteWideFoo;
beforeEach(function () {
suiteWideFoo = 1;
}
var suiteWideFoo;
beforeEach(function () {
suiteWideFoo = 1;
}
it('should equal bar', function () {
expect(suiteWideFoo).toEqual(1);
};
});
it('should equal bar', function () {
expect(suiteWideFoo).toEqual(1);
};
});
### afterEach
afterEach takes a function that is run after each spec. For example:
describe('some suite', function () {
describe('some suite', function () {
var suiteWideFoo;
afterEach(function () {
suiteWideFoo = 0;
}
var suiteWideFoo;
afterEach(function () {
suiteWideFoo = 0;
}
it('should equal 1', function () {
expect(suiteWideFoo).toEqual(1);
};
it('should equal 1', function () {
expect(suiteWideFoo).toEqual(1);
};
it('should equal 0 after', function () {
expect(suiteWideFoo).toEqual(0);
};
});
it('should equal 0 after', function () {
expect(suiteWideFoo).toEqual(0);
};
});
### Spies
Jasmine integrates 'spies' that permit many spying, mocking, and faking behaviors.
Here is an few examples:
Here are a few examples:
var Klass = function () {
}
var Klass = function () {
}
var Klass.prototype.method = function (arg) {
var Klass.prototype.method = function (arg) {
return arg;
}
}
var Klass.prototype.methodWithCallback = function (callback) {
var Klass.prototype.methodWithCallback = function (callback) {
return callback('foo');
}
}
...
it('should spy on Klass#method') {
it('should spy on Klass#method') {
spyOn(Klass, 'method');
Klass.method('foo argument');
expect(Klass.method).wasCalledWith('foo argument');
}
});
it('should spy on Klass#methodWithCallback') {
it('should spy on Klass#methodWithCallback') {
var callback = Jasmine.createSpy();
Klass.method(callback);
expect(callback).wasCalledWith('foo');
}
});
Many other options are available for spies:
`andCallThrough()`: spies on AND calls the original function spied on
`andReturn()`: returns passed arguments when spy is called
`andThrow()`: throws passed exception when spy is called
`andCallFake()`: calls passed function when spy is called
`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.