diff --git a/types/ember-mocha/ember-mocha-tests.ts b/types/ember-mocha/ember-mocha-tests.ts new file mode 100644 index 0000000000..a4c055c91b --- /dev/null +++ b/types/ember-mocha/ember-mocha-tests.ts @@ -0,0 +1,187 @@ +import { + describeComponent, describeModel, describeModule, + setResolver, setupAcceptanceTest, setupComponentTest, + setupModelTest, setupTest +} from 'ember-mocha'; +import { describe, it, beforeEach, afterEach, before, after } from 'mocha'; +import chai = require('chai'); +import Ember from "ember"; +import hbs from 'htmlbars-inline-precompile'; + +describeModule('name', function() { + beforeEach(function() { + }); + + it('test', function() { + }); +}); + +describeModule('name', 'description', function() { + it('test', function() { + }); +}); + +describeModule( + 'name', + 'description', + { + needs: ['service:notifications'] + }, + function() { + } +); + +describeModule('component:x-foo', 'TestModule callbacks', { + needs: [], + + beforeSetup() { + }, + setup() { + }, + teardown() { + }, + afterTeardown() { + } +}, function() { +}); + +describeComponent('x-foo', { + integration: true +}, function() { +}); + +describeComponent('x-foo', { + unit: true, + needs: ['helper:pluralize-string'] +}, function() { +}); + +describeComponent.skip( + 'block-slot', + 'Integration: BlockSlotComponent', + { + integration: true + }, + function() { + } +); + +describeModel('user', { + needs: ['model:child'] +}, function() { +}); + +describeModule('component:x-foo', 'TestModule callbacks', function() { + before(function() { + class I18n extends Ember.Object {} + + this.skip(); + this.timeout(1000); + this.registry.register('helper:i18n', I18n); + this.registry.register('helper:i18n', I18n, { singleton: true }); + this.register('service:i18n', {}); + this.inject.service('i18n'); + this.inject.service('i18n', { as: 'i18n' }); + this.factory('object:user').create(); + }); + + after(function() { + }); + + beforeEach(function() { + }); + + afterEach(function() { + }); +}); + +describe('setupTest', function() { + setupTest(); + + setupTest('service:ajax'); + + setupTest('service:ajax', { + unit: true + }); + + setupTest('controller:sidebar', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] + }); + + setupComponentTest('gravatar-image', { + // specify the other units that are required for this test + // needs: ['component:foo', 'helper:bar'] + }); + + setupModelTest('contact', { + // Specify the other units that are required for this test. + needs: [] + }); + + const Application = Ember.Application.extend(); + + setupAcceptanceTest({ Application }); + + it('test', function() { + }); +}); + +// if you don't have a custom resolver, do it like this: +setResolver(Ember.DefaultResolver.create()); + +it('renders', function() { + // setup the outer context + this.set('value', 'cat'); + this.on('action', function(result) { + chai.expect(result).to.equal('bar', 'The correct result was returned'); + chai.expect(this.get('value')).to.equal('cat'); + }); + + // render the component + this.render(hbs` + {{ x-foo value=value action="result" }} + `); + this.render('{{ x-foo value=value action="result" }}'); + this.render([ + '{{ x-foo value=value action="result" }}' + ]); + + chai.expect(this.$('div>.value').text()).to.equal('cat', 'The component shows the correct value'); + + this.$('button').click(); +}); + +it('renders', function() { + // creates the component instance + const subject = this.subject(); + + const subject2 = this.subject({ + item: 42 + }); + + const { inputFormat } = this.setProperties({ + inputFormat: 'M/D/YY', + outputFormat: 'MMMM D, YYYY', + date: '5/3/10' + }); + + const { inputFormat: if2, outputFormat } = this.getProperties('inputFormat', 'outputFormat'); + + const inputFormat2 = this.get('inputFormat'); + + // render the component on the page + this.render(); + chai.expect(this.$('.foo').text()).to.equal('bar'); +}); + +it('can calculate the result', function(assert) { + const subject = this.subject(); + + subject.set('value', 'foo'); + chai.assert.equal(subject.get('result'), 'bar'); +}); + +it.skip('disabled test'); + +it.skip('disabled test', function() { }); diff --git a/types/ember-mocha/index.d.ts b/types/ember-mocha/index.d.ts new file mode 100644 index 0000000000..d114b6620d --- /dev/null +++ b/types/ember-mocha/index.d.ts @@ -0,0 +1,95 @@ +// Type definitions for ember-mocha 0.12 +// Project: https://github.com/emberjs/ember-mocha#readme +// Definitions by: Derek Wickern +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.4 + +import { TestContext, ModuleCallbacks } from "ember-test-helpers"; +import Ember from 'ember'; +import { it as mochaIt, ISuiteCallbackContext } from 'mocha'; + +// these globals are re-exported as named exports by ember-mocha +type mochaBefore = typeof before; +type mochaAfter = typeof after; +type mochaBeforeEach = typeof beforeEach; +type mochaAfterEach = typeof afterEach; +type mochaSetup = typeof setup; +type mochaTeardown = typeof teardown; +type mochaSuiteSetup = typeof suiteSetup; +type mochaSuiteTeardown = typeof suiteTeardown; + +declare module 'ember-mocha' { + interface ContextDefinitionFunction { + (name: string, description: string, callbacks: ModuleCallbacks, tests: (this: ISuiteCallbackContext) => void): void; + (name: string, description: string, tests: (this: ISuiteCallbackContext) => void): void; + (name: string, callbacks: ModuleCallbacks, tests: (this: ISuiteCallbackContext) => void): void; + (name: string, tests: (this: ISuiteCallbackContext) => void): void; + } + + interface ContextDefinition extends ContextDefinitionFunction { + only: ContextDefinitionFunction; + skip: ContextDefinitionFunction; + } + + interface SetupTest { + (name?: string, callbacks?: ModuleCallbacks): void; + (callbacks: ModuleCallbacks): void; + } + + /** + * + * @param {string} fullName The full name of the unit, ie controller:application, route:index. + * @param {string} description The description of the module + * @param {ModuleCallbacks} callbacks + * @deprecated Use setupTest instead + */ + export const describeModule: ContextDefinition; + + /** + * + * @param {string} fullName the short name of the component that you'd use in a template, ie x-foo, ic-tabs, etc. + * @param {string} description The description of the module + * @param {ModuleCallbacks} callbacks + * @deprecated Use setupComponentTest instead + */ + export const describeComponent: ContextDefinition; + + /** + * + * @param {string} fullName the short name of the model you'd use in store operations ie user, assignmentGroup, etc. + * @param {string} description The description of the module + * @param {ModuleCallbacks} callbacks + * @deprecated Use setupModelTest instead + */ + export const describeModel: ContextDefinition; + + export const setupTest: SetupTest; + export const setupAcceptanceTest: SetupTest; + export const setupComponentTest: SetupTest; + export const setupModelTest: SetupTest; + + export const it: typeof mochaIt; + + /** + * Sets a Resolver globally which will be used to look up objects from each test's container. + */ + export function setResolver(resolver: Ember.Resolver): void; +} + +declare module 'mocha' { + // augment test callback context + interface ITestCallbackContext extends TestContext {} + interface IHookCallbackContext extends TestContext {} + + // re-export mocha globals as named exports + export const describe: Mocha.IContextDefinition; + export const it: Mocha.ITestDefinition; + export const setup: mochaSetup; + export const teardown: mochaTeardown; + export const suiteSetup: mochaSuiteSetup; + export const suiteTeardown: mochaSuiteTeardown; + export const before: mochaBefore; + export const after: mochaAfter; + export const beforeEach: mochaBeforeEach; + export const afterEach: mochaAfterEach; +} diff --git a/types/ember-mocha/tsconfig.json b/types/ember-mocha/tsconfig.json new file mode 100644 index 0000000000..e9fdedfe7f --- /dev/null +++ b/types/ember-mocha/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": false, + "baseUrl": "../", + "typeRoots": ["../"], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "ember-mocha-tests.ts" + ] +} diff --git a/types/ember-mocha/tslint.json b/types/ember-mocha/tslint.json new file mode 100644 index 0000000000..aed9a80a73 --- /dev/null +++ b/types/ember-mocha/tslint.json @@ -0,0 +1,18 @@ +{ + "extends": "dtslint/dt.json", + "rules": { + "only-arrow-functions": false, + "strict-export-declare-modifiers": false, + "no-duplicate-imports": false, + "unified-signatures": false, + "no-declare-current-package": false, + + // ERROR: An interface declaring no members is equivalent to its supertype. + // -- Not true when augmenting an interface + "no-empty-interface": false, + + // ERROR: interface name must not have an "I" prefix + // -- Augmenting @types/mocha which uses "I" prefix + "interface-name": false + } +} diff --git a/types/ember-qunit/ember-qunit-tests.ts b/types/ember-qunit/ember-qunit-tests.ts new file mode 100644 index 0000000000..de22ab3d94 --- /dev/null +++ b/types/ember-qunit/ember-qunit-tests.ts @@ -0,0 +1,107 @@ +import Ember from 'ember'; +import hbs from 'htmlbars-inline-precompile'; +import { test, skip, moduleFor, moduleForModel, moduleForComponent, setResolver } from 'ember-qunit'; + +moduleForComponent('x-foo', { + integration: true +}); + +moduleForComponent('x-foo', { + unit: true, + needs: ['helper:pluralize-string'] +}); + +moduleForModel('user', { + needs: ['model:child'] +}); + +moduleFor('controller:home'); + +moduleFor('component:x-foo', 'Some description'); + +moduleFor('component:x-foo', 'TestModule callbacks', { + beforeSetup() { + }, + + beforeEach(assert) { + this.registry.register('helper:i18n', {}); + this.register('service:i18n', {}); + this.inject.service('i18n'); + this.inject.service('i18n', { as: 'i18n' }); + this.factory('object:user').create(); + assert.ok(true); + }, + + afterEach(assert) { + assert.ok(true); + }, + + afterTeardown(assert) { + assert.ok(true); + } +}); + +// if you don't have a custom resolver, do it like this: +setResolver(Ember.DefaultResolver.create()); + +test('it renders', function(assert) { + assert.expect(2); + + // setup the outer context + this.set('value', 'cat'); + this.on('action', function(result) { + assert.equal(result, 'bar', 'The correct result was returned'); + assert.equal(this.get('value'), 'cat'); + }); + + // render the component + this.render(hbs` + {{ x-foo value=value action="result" }} + `); + this.render('{{ x-foo value=value action="result" }}'); + this.render([ + '{{ x-foo value=value action="result" }}' + ]); + + assert.equal(this.$('div>.value').text(), 'cat', 'The component shows the correct value'); + + this.$('button').click(); +}); + +test('it renders', function(assert) { + assert.expect(1); + + // creates the component instance + const subject = this.subject(); + + const subject2 = this.subject({ + item: 42 + }); + + const { inputFormat } = this.setProperties({ + inputFormat: 'M/D/YY', + outputFormat: 'MMMM D, YYYY', + date: '5/3/10' + }); + + const { inputFormat: if2, outputFormat } = this.getProperties('inputFormat', 'outputFormat'); + + const inputFormat2 = this.get('inputFormat'); + + // render the component on the page + this.render(); + assert.equal(this.$('.foo').text(), 'bar'); +}); + +test('It can calculate the result', function(assert) { + assert.expect(1); + + const subject = this.subject(); + + subject.set('value', 'foo'); + assert.equal(subject.get('result'), 'bar'); +}); + +skip('disabled test'); + +skip('disabled test', function(assert) { }); diff --git a/types/ember-qunit/index.d.ts b/types/ember-qunit/index.d.ts new file mode 100644 index 0000000000..ef75eeeb26 --- /dev/null +++ b/types/ember-qunit/index.d.ts @@ -0,0 +1,124 @@ +// Type definitions for ember-qunit 2.2 +// Project: https://github.com/emberjs/ember-qunit#readme +// Definitions by: Derek Wickern +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.4 + +/// + +declare module 'ember-qunit' { + import Ember from 'ember'; + import { ModuleCallbacks } from "ember-test-helpers"; + + interface QUnitModuleCallbacks extends ModuleCallbacks, Hooks { + beforeSetup?(assert: Assert): void; + setup?(assert: Assert): void; + teardown?(assert: Assert): void; + afterTeardown?(assert: Assert): void; + } + + /** + * + * @param {string} fullName The full name of the unit, ie controller:application, route:index. + * @param {string} description The description of the module + * @param {ModuleCallbacks} callbacks + */ + export function moduleFor(fullName: string, description: string, callbacks?: QUnitModuleCallbacks): void; + export function moduleFor(fullName: string, callbacks?: QUnitModuleCallbacks): void; + + /** + * + * @param {string} fullName the short name of the component that you'd use in a template, ie x-foo, ic-tabs, etc. + * @param {string} description The description of the module + * @param {ModuleCallbacks} callbacks + */ + export function moduleForComponent(fullName: string, description: string, callbacks?: QUnitModuleCallbacks): void; + export function moduleForComponent(fullName: string, callbacks?: QUnitModuleCallbacks): void; + + /** + * + * @param {string} fullName the short name of the model you'd use in store operations ie user, assignmentGroup, etc. + * @param {string} description The description of the module + * @param {ModuleCallbacks} callbacks + */ + export function moduleForModel(fullName: string, description: string, callbacks?: QUnitModuleCallbacks): void; + export function moduleForModel(fullName: string, callbacks?: QUnitModuleCallbacks): void; + + /** + * Sets a Resolver globally which will be used to look up objects from each test's container. + */ + export function setResolver(resolver: Ember.Resolver): void; + + export class QUnitAdapter extends Ember.Test.Adapter {} + + export { module, test, skip, only, todo } from 'qunit'; +} + +declare module 'qunit' { + import { TestContext } from "ember-test-helpers"; + + export const module: typeof QUnit.module; + + /** + * Add a test to run. + * + * Add a test to run using `QUnit.test()`. + * + * The `assert` argument to the callback contains all of QUnit's assertion + * methods. Use this argument to call your test assertions. + * + * `QUnit.test()` can automatically handle the asynchronous resolution of a + * Promise on your behalf if you return a thenable Promise as the result of + * your callback function. + * + * @param {string} name Title of unit being tested + * @param callback Function to close over assertions + */ + export function test(name: string, callback: (this: TestContext, assert: Assert) => void): void; + + /** + * Adds a test to exclusively run, preventing all other tests from running. + * + * Use this method to focus your test suite on a specific test. QUnit.only + * will cause any other tests in your suite to be ignored. + * + * Note, that if more than one QUnit.only is present only the first instance + * will run. + * + * This is an alternative to filtering tests to run in the HTML reporter. It + * is especially useful when you use a console reporter or in a codebase + * with a large set of long running tests. + * + * @param {string} name Title of unit being tested + * @param callback Function to close over assertions + */ + export function only(name: string, callback: (this: TestContext, assert: Assert) => void): void; + + /** + * Use this method to test a unit of code which is still under development (in a “todo” state). + * The test will pass as long as one failing assertion is present. + * + * If all assertions pass, then the test will fail signaling that `QUnit.todo` should + * be replaced by `QUnit.test`. + * + * @param {string} name Title of unit being tested + * @param callback Function to close over assertions + */ + export function todo(name: string, callback: (this: TestContext, assert: Assert) => void): void; + + /** + * Adds a test like object to be skipped. + * + * Use this method to replace QUnit.test() instead of commenting out entire + * tests. + * + * This test's prototype will be listed on the suite as a skipped test, + * ignoring the callback argument and the respective global and module's + * hooks. + * + * @param {string} Title of unit being tested + */ + export const skip: typeof QUnit.skip; + + export default QUnit; +} diff --git a/types/ember-qunit/tsconfig.json b/types/ember-qunit/tsconfig.json new file mode 100644 index 0000000000..845f5b1023 --- /dev/null +++ b/types/ember-qunit/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": false, + "baseUrl": "../", + "typeRoots": ["../"], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "ember-qunit-tests.ts" + ] +} diff --git a/types/ember-qunit/tslint.json b/types/ember-qunit/tslint.json new file mode 100644 index 0000000000..5070b08af9 --- /dev/null +++ b/types/ember-qunit/tslint.json @@ -0,0 +1,9 @@ +{ + "extends": "dtslint/dt.json", + "rules": { + "only-arrow-functions": false, + "strict-export-declare-modifiers": false, + "no-duplicate-imports": false, + "no-declare-current-package": false + } +} diff --git a/types/ember-test-helpers/ember-test-helpers-tests.ts b/types/ember-test-helpers/ember-test-helpers-tests.ts new file mode 100644 index 0000000000..fe9876803f --- /dev/null +++ b/types/ember-test-helpers/ember-test-helpers-tests.ts @@ -0,0 +1,25 @@ +/// +import { ModuleCallbacks, TestModule } from "ember-test-helpers"; +import wait from 'ember-test-helpers/wait'; +import hasEmberVersion from 'ember-test-helpers/has-ember-version'; + +function moduleFor(name: string, description: string, callbacks: ModuleCallbacks) { + let module = new TestModule(name, description, callbacks); + + QUnit.module(module.name, { + beforeEach() { + module.setup(); + }, + afterEach() { + module.teardown(); + } + }); +} + +async function testWait() { + await wait(); +} + +if (hasEmberVersion(2, 10)) { + // ... +} diff --git a/types/ember-test-helpers/index.d.ts b/types/ember-test-helpers/index.d.ts new file mode 100644 index 0000000000..26591d7d23 --- /dev/null +++ b/types/ember-test-helpers/index.d.ts @@ -0,0 +1,95 @@ +// Type definitions for ember-test-helpers 0.6 +// Project: https://github.com/emberjs/ember-test-helpers#readme +// Definitions by: Derek Wickern +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.4 + +/// + +declare module 'ember-test-helpers' { + import Ember from 'ember'; + import DS from 'ember-data'; + import { TemplateFactory } from 'htmlbars-inline-precompile'; + import RSVP from "rsvp"; + + interface ModuleCallbacks { + integration?: boolean; + unit?: boolean; + needs?: string[]; + + beforeSetup?(assert?: any): void; + setup?(assert?: any): void; + teardown?(assert?: any): void; + afterTeardown?(assert?: any): void; + + [key: string]: any; + } + + interface TestContext { + get(key: string): any; + getProperties(...keys: K[]): Pick; + set(key: string, value: V): V; + setProperties

(hash: P): P; + on(actionName: string, handler: (this: TestContext, ...args: any[]) => any): void; + send(actionName: string): void; + $: JQueryStatic; + subject(options?: {}): any; + render(template?: string | string[] | TemplateFactory): void; + clearRender(): void; + registry: Ember.Registry; + container: Ember.Container; + dispatcher: Ember.EventDispatcher; + application: Ember.Application; + store: DS.Store; + register(fullName: string, factory: any): void; + factory(fullName: string): any; + inject: { + controller(name: string, options?: { as: string }): any; + service(name: string, options?: { as: string }): any; + }; + } + + class TestModule { + constructor(name: string, callbacks?: ModuleCallbacks); + constructor(name: string, description?: string, callbacks?: ModuleCallbacks); + + name: string; + subjectName: string; + description: string; + isIntegration: boolean; + callbacks: ModuleCallbacks; + context: TestContext; + resolver: Ember.Resolver; + + setup(assert?: any): RSVP.Promise; + teardown(assert?: any): RSVP.Promise; + getContext(): TestContext; + setContext(context: TestContext): void; + } + + class TestModuleForAcceptance extends TestModule {} + class TestModuleForIntegration extends TestModule {} + class TestModuleForComponent extends TestModule {} + class TestModuleForModel extends TestModule {} + + function getContext(): TestContext | undefined; + function setContext(context: TestContext): void; + function unsetContext(): void; + function setResolver(resolver: Ember.Resolver): void; +} + +declare module 'ember-test-helpers/wait' { + import RSVP from "rsvp"; + + interface WaitOptions { + waitForTimers?: boolean; + waitForAJAX?: boolean; + waitForWaiters?: boolean; + } + + export default function wait(options?: WaitOptions): RSVP.Promise; +} + +declare module 'ember-test-helpers/has-ember-version' { + export default function hasEmberVersion(major: number, minor: number): boolean; +} diff --git a/types/ember-test-helpers/tsconfig.json b/types/ember-test-helpers/tsconfig.json new file mode 100644 index 0000000000..dc9c583d1c --- /dev/null +++ b/types/ember-test-helpers/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6", + "dom" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": false, + "baseUrl": "../", + "typeRoots": ["../"], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "ember-test-helpers-tests.ts" + ] +}