diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 5eb1fc9f5..9a087a7aa 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -148,6 +148,7 @@ All definitions files include a header with the author and editors, so at some p
* [Jasmine-data_driven_tests](https://github.com/gburghardt/jasmine-data_driven_tests) (by [Anthony MacKinnon](https://github.com/AnthonyMacKinnon))
* [Jasmine-jQuery](https://github.com/velesin/jasmine-jquery) (by [Gregor Stamac](https://github.com/gstamac))
* [jDataView](https://github.com/jDataView/jDataView) (by [Ingvar Stepanyan](https://github.com/RReverser))
+* [Jest](http://facebook.github.io/jest/) (by [Joshua Smith](https://github.com/Josh211ua))
* [JointJS](http://www.jointjs.com/) (by [Aidan Reel](http://github.com/areel))
* [jQRangeSlider](http://ghusse.github.com/jQRangeSlider) (by [Dániel Tar](https://github.com/qcz))
* [jQuery](http://jquery.com/) (from TypeScript samples)
diff --git a/jest/jest-tests.ts b/jest/jest-tests.ts
new file mode 100644
index 000000000..764daf142
--- /dev/null
+++ b/jest/jest-tests.ts
@@ -0,0 +1,123 @@
+///
+
+// Tests based on the Jest website
+jest.dontMock('../sum');
+
+describe('sum', function() {
+ it('adds 1 + 2 to equal 3', function() {
+ var sum: (a: number, b: number) => number = require('../sum');
+ expect(sum(1, 2)).toBe(3);
+ });
+});
+
+describe('fetchCurrentUser', function() {
+ it('calls the callback when $.ajax requests are finished', function() {
+ var $ = require('jquery');
+ var fetchCurrentUser = require('../fetchCurrentUser');
+
+ // Create a mock function for our callback
+ var callback = jest.genMockFunction();
+ fetchCurrentUser(callback);
+
+ // Now we emulate the process by which `$.ajax` would execute its own
+ // callback
+ $.ajax.mock.calls[0 /*first call*/][0 /*first argument*/].success({
+ firstName: 'Bobby',
+ lastName: '");DROP TABLE Users;--'
+ });
+
+ // And finally we assert that this emulated call by `$.ajax` incurred a
+ // call back into the mock function we provided as a callback
+ expect(callback.mock.calls[0/*first call*/][0/*first arg*/]).toEqual({
+ loggedIn: true,
+ fullName: 'Bobby ");DROP TABLE Users;--'
+ });
+ });
+});
+
+jest.dontMock('../displayUser.js')
+jest.dontMock('jquery');
+
+describe('displayUser', function() {
+ it('displays a user after a click', function() {
+ // Set up our document body
+ document.body.innerHTML =
+ '
' +
+ ' ' +
+ ' ' +
+ '
';
+
+ var displayUser = require('../displayUser');
+ var $ = require('jquery');
+ var fetchCurrentUser = require('../fetchCurrentUser');
+
+ // Tell the fetchCurrentUser mock function to automatically invoke
+ // its callback with some data
+ fetchCurrentUser.mockImplementation(function(cb: Function) {
+ cb({
+ loggedIn: true,
+ fullName: 'Johnny Cash'
+ });
+ });
+
+ // Use jquery to emulate a click on our button
+ $('#button').click();
+
+ // Assert that the fetchCurrentUser function was called, and that the
+ // #username span's innter text was updated as we'd it expect.
+ expect(fetchCurrentUser).toBeCalled();
+ expect($('#username').text()).toEqual('Johnny Cash - Logged In');
+ });
+});
+
+jest.dontMock('../CheckboxWithLabel.js');
+describe('CheckboxWithLabel', function() {
+ it('changes the text after click', function() {
+ var React = require('react/addons');
+ var CheckboxWithLabel = require('../CheckboxWithLabel.js');
+ var TestUtils = React.addons.TestUtils;
+
+ // Render a checkbox with label in the document
+ var checkbox = TestUtils.renderIntoDocument(
+ CheckboxWithLabel({
+ labelOn: "On",
+ labelOff: "Off"
+ })
+ );
+
+ // Verify that it's Off by default
+ var label = TestUtils.findRenderedDOMComponentWithTag(
+ checkbox, 'label');
+ expect(label.getDOMNode().textContent).toEqual('Off');
+
+ // Simulate a click and verify that it is now On
+ var input = TestUtils.findRenderedDOMComponentWithTag(
+ checkbox, 'input');
+ TestUtils.Simulate.change(input);
+ expect(label.getDOMNode().textContent).toEqual('On');
+ });
+});
+
+function testInstances() {
+ var mockFn = jest.genMockFunction();
+ var a = new mockFn();
+ var b = new mockFn();
+
+ mockFn.mock.instances[0] === a; // true
+ mockFn.mock.instances[1] === b; // true
+}
+
+function testMockImplementation() {
+ var mockFn = jest.genMockFunction().mockImplementation(function (scalar:number):number {
+ return 42 + scalar;
+ });
+
+ var a = mockFn(0);
+ var b = mockFn(1);
+
+ a === 42; // true
+ b === 43; // true
+
+ mockFn.mock.calls[0][0] === 0; // true
+ mockFn.mock.calls[1][0] === 1; // true
+}
\ No newline at end of file
diff --git a/jest/jest.d.ts b/jest/jest.d.ts
new file mode 100644
index 000000000..52d09f99e
--- /dev/null
+++ b/jest/jest.d.ts
@@ -0,0 +1,79 @@
+// Type definitions for Jest 0.1.18
+// Project: http://facebook.github.io/jest/
+// Definitions by: Asana
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+declare function afterEach(fn: jest.EmptyFunction): void;
+declare function beforeEach(fn: jest.EmptyFunction): void;
+declare function describe(name: string, fn: jest.EmptyFunction): void;
+declare var it: jest.It;
+declare function pit(name: string, fn: jest.EmptyFunction): void;
+declare var require: jest.Require;
+declare function xdescribe(name: string, fn: jest.EmptyFunction): void;
+declare function xit(name: string, fn: jest.EmptyFunction): void;
+
+declare function expect(actual: any): jest.Matchers;
+
+declare module jest {
+ function autoMockOff(): void;
+ function autoMockOn(): void;
+ function clearAllTimers(): void;
+ function dontMock(moduleName: string): void;
+ function genMockFromModule(moduleName: string): Mock;
+ function genMockFunction(): Mock;
+ function genMockFn(): Mock;
+ function mock(moduleName: string): void;
+ function runAllTicks(): void;
+ function runAllTimers(): void;
+ function runOnlyPendingTimers(): void;
+ function setMock(moduleName: string, moduleExports: T): void;
+
+ interface EmptyFunction {
+ (): void;
+ }
+
+ interface Matchers {
+ not: Matchers;
+ toThrow(expected?: any): boolean;
+ toBe(expected: any): boolean;
+ toEqual(expected: any): boolean;
+ toBeFalsy(): boolean;
+ toBeTruthy(): boolean;
+ toBeNull(): boolean;
+ toBeUndefined(): boolean;
+ toMatch(expected: RegExp): boolean;
+ toContain(expected: string): boolean;
+ toBeCloseTo(expected: number, delta: number): boolean;
+ toBeGreaterThen(expected: number): boolean;
+ toBeLessThen(expected: number): boolean;
+ toBeCalled(): boolean;
+ toBeCalledWith(...args: any[]): boolean;
+ lastCalledWith(...args: any[]): boolean;
+ }
+
+ interface It {
+ (name: string, fn: EmptyFunction): void;
+ only(name: string, fn: EmptyFunction): void;
+ }
+
+ interface Require {
+ (moduleName: string): any;
+ requireActual(moduleName: string): any;
+ }
+
+ interface Mock {
+ new(): T;
+ mock: MockContext;
+ mockClear(): void;
+ mockImplementation(fn: Function): Mock;
+ mockImpl(fn: Function): Mock;
+ mockReturnThis(): Mock;
+ mockReturnValue(value: any): Mock;
+ mockReturnValueOnce(value: any): Mock;
+ }
+
+ interface MockContext {
+ calls: any[][];
+ instances: T[];
+ }
+}
\ No newline at end of file