diff --git a/bardjs/bardjs-tests.ts b/bardjs/bardjs-tests.ts new file mode 100644 index 0000000000..b033ffe3c7 --- /dev/null +++ b/bardjs/bardjs-tests.ts @@ -0,0 +1,282 @@ +/// +/// +/// +/// +/// + +module bardTests { + var expect = chai.expect, + assert = chai.assert; + + class MyService { + constructor(private $q: angular.IQService) {} + + remoteCall(): angular.IPromise { + return new this.$q((resolve, reject) => { + resolve(['Hello', 'World']); + }); + } + } + + myService.$inject = ['$q']; + function myService($q: angular.IQService) { + return new MyService($q); + } + + class MyController { + myProperty: string; + } + + angular + .module('myModule') + .service('myService', myService) + .controller('MyController', MyController); + + /* + * bard.$httpBackend + */ + function test_$httpBackend() { + var myService: MyService; + var $rootScope: angular.IRootScopeService; + + beforeEach(module(bard.$httpBackend, 'myModule')); + + beforeEach(inject(function(_myService_: MyService, _$rootScope_: angular.IRootScopeService) { + myService = _myService_; + $rootScope = _$rootScope_; + })); + + it('should return valid data', function(done) { + myService.remoteCall() + .then(function(data) { + expect(data).to.exist; + }) + .then(done, done); + + $rootScope.$apply; // Because not using bard.$q, must flush the $http and $q queues + }); + } + + /* + * bard.$q + */ + function test_$q() { + var myService: MyService; + + beforeEach(module(bard.$q, bard.$httpBackend, 'myModule')); + + beforeEach(inject(function(_myService_: MyService) { + myService = _myService_; + })); + + it('should return valid data', (done) => { + myService.remoteCall() + .then((data) => { + expect(data).to.exist; + }) + .then(done, done); + + // No need to flush + }); + } + + /* + * bard.addGlobals + */ + function test_addGlobals() { + describe('someting', function() { + var ctx = this; + + it('should work', function() { + var bar = 'bar'; + bard.addGlobals(this, 'foo'); // where `this` is the spec context + bard.addGlobals(this, 'foo', bar); + bard.addGlobals.bind(this)('foo', 'bar'); + bard.addGlobals(ctx, ['foo', 'bar']) // where ctx is the spec context + }); + }) + } + + /* + * bard.appModule + */ + function test_appModule() { + beforeEach(bard.appModule('myModule')); + //// + beforeEach(bard.appModule('myModule', function() {}, {})); + } + + /* + * bard.assertFail + */ + function test_assertFail() { + bard.assertFail('FAIL!'); + } + + /* + * bard.asyncModule + */ + function test_asyncModule() { + beforeEach(bard.asyncModule('myModule')); + //// + beforeEach(bard.asyncModule('myModule', function() {}, {})); + } + + /* + * bard.debugging + */ + function test_debugging() { + console.log( + bard.debugging(true), // should return true + bard.debugging(false), // should return false + bard.debugging(42), // should return true + bard.debugging(''), // should return false + bard.debugging() // should return false + ); + } + + /* + * bard.fakeLogger + */ + function test_fakeLogger() { + beforeEach(module('myModule', bard.fakeLogger)); + //// + beforeEach(bard.appModule('myModule', bard.fakeLogger)); + //// + beforeEach(bard.asyncModule('myModule', bard.fakeLogger)); + } + + /* + * bard.fakeRouteHelperProvider + */ + function test_fakeRouteHelperProvider() { + beforeEach(module('myModule', bard.fakeRouteHelperProvider)); + //// + beforeEach(bard.appModule('myModule', bard.fakeRouteHelperProvider)); + //// + beforeEach(bard.asyncModule('myModule', bard.fakeRouteHelperProvider)); + } + + /* + * bard.fakeRouteProvider + */ + function test_fakeRouteProvider() { + beforeEach(module('myModule', bard.fakeRouteProvider)); + //// + beforeEach(bard.appModule('myModule', bard.fakeRouteProvider)); + //// + beforeEach(bard.asyncModule('myModule', bard.fakeRouteProvider)); + } + + /* + * bard.fakeStateProvider + */ + function test_fakeStateProvider() { + beforeEach(module('myModule', bard.fakeStateProvider)); + //// + beforeEach(bard.appModule('myModule', bard.fakeStateProvider)); + //// + beforeEach(bard.asyncModule('myModule', bard.fakeStateProvider)); + } + + /* + * bard.fakeToastr + */ + function test_fakeToastr() { + beforeEach(module('myModule', bard.fakeToastr)); + //// + beforeEach(bard.appModule('myModule', bard.fakeToastr)); + //// + beforeEach(bard.asyncModule('myModule', bard.fakeToastr)); + } + + /* + * bard.inject + */ + function test_inject() { + beforeEach(() => bard.inject(this, '$controller', '$log', '$q', '$rootScope', 'myService')); + } + + /* + * bard.log + */ + function test_log() { + bard.log('We got the goods'); + } + + /* + * bard.mochaRunnerListener + */ + function test_mochaRunnerListener() { + var runner = mocha.run(); + bard.mochaRunnerListener(runner); + } + + /* + * bard.mockService + */ + function test_mockService() { + var controller: MyController, + myArray = ['This', 'is', 'some', 'mocked', 'data']; + var $controller: angular.IControllerService, + $q: angular.IQService, + $rootScope: angular.IRootScopeService, + myService: MyService; + + beforeEach(function() { + bard.appModule('myModule'); + bard.inject(this, '$controller', '$q', '$rootScope', 'myService'); + + bard.mockService(myService, { + remoteCall: $q.when(myArray), + _default: $q.when([]) + }); + + controller = $controller('MyController'); + $rootScope.$apply(); + }); + } + + /* + * bard.replaceAccentChars + */ + function test_replaceAccentChars() { + console.log(bard.replaceAccentChars('àáâãäåèéêëìíîïòóôõöùúûüýÿ') === 'aaaaaaeeeeeeeeooooouuuuyy'); + } + + /* + * bard.verifyNoOutstandingHttpRequests + */ + function test_verifyNoOutstandingHttpRequests() { + var controller: MyController, + myArray = ['This', 'is', 'some', 'mocked', 'data']; + var $controller: angular.IControllerService, + $q: angular.IQService, + $rootScope: angular.IRootScopeService, + myService: MyService; + + beforeEach(function() { + bard.appModule('myModule'); + bard.inject(this, '$controller', '$q', '$rootScope', 'myService'); + + bard.mockService(myService, { + remoteCall: $q.when(myArray), + _default: $q.when([]) + }); + + controller = $controller('MyController'); + $rootScope.$apply(); + }); + + bard.verifyNoOutstandingHttpRequests(); + } + + /* + * bard.wrapWithDone + */ + function test_wrapWithDone() { + function callback() { console.log('Doing something...'); } + function done() { console.log('...Done'); } + bard.wrapWithDone(callback, done); + } +} diff --git a/bardjs/bardjs.d.ts b/bardjs/bardjs.d.ts new file mode 100644 index 0000000000..3d3ad5f228 --- /dev/null +++ b/bardjs/bardjs.d.ts @@ -0,0 +1,174 @@ +// Type definitions for bardjs 0.1.4 +// Project: https://github.com/wardbell/bardjs +// Definitions by: Andrew Archibald +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/// +/// +/// + +/** + * Module for bardjs functions + */ +declare module bard { + /** + * Replaces the ngMock'ed $httpBackend with the real one from ng thus + * restoring the ability to issue AJAX calls to the backend with $http. + * + * Note that $q remains ngMocked so you must flush $http calls ($rootScope.$digest). + * Use $rootScope.$apply() for this purpose. + * + * Could restore $q with $qReal in which case don't need to flush. + */ + function $httpBackend($provide: angular.auto.IProvideService): any; + + /** + * Replaces the ngMock'ed $q with the real one from ng thus + * obviating the need to flush $http and $q queues + * at the expense of ability to control $q timing. + */ + function $q($provide: angular.auto.IProvideService): any; + + /** + * Add names of globals to list of OK globals for this mocha spec + * NB: Call this method ONLY if you're using mocha! + * NB: Turn off browser-sync else mocha detects the browser-sync globals + * like ` ___browserSync___` + */ + function addGlobals(...globals: any[]): void; + + /** + * Prepare ngMocked application feature module + * along with faked toastr, routehelper, + * and faked router services. + * Especially useful for controller testing + * Use it as you would the ngMocks#module method + * + * DO NOT USE IF YOU NEED THE REAL ROUTER SERVICES! + * Fall back to `angular.mock.module(...)` or just `module(...)` + */ + function appModule(...fns: (string | Function | Object)[]): () => void; + + /** + * Assert a failure in mocha, without condition + */ + function assertFail(message: string): Chai.AssertionError; + + /** + * Prepare ngMocked module definition that makes real $http and $q calls + * Also adds fakeLogger to the end of the definition + * Use it as you would the ngMocks#module method + */ + function asyncModule(...fns: (string | Function | Object)[]): () => void; + + /** + * Get or set bard debugging flag + */ + function debugging(newFlag?: any): boolean; + + /** + * Registers a fake logger service that you can spy on + */ + function fakeLogger($provide: angular.auto.IProvideService): void; + + /** + * Registers a fake route helper provider service that you can spy on + */ + function fakeRouteHelperProvider($provide: angular.auto.IProvideService): void; + + /** + * Stub out the $routeProvider so we avoid + * all routing calls, including the default route + * which runs on every test otherwise. + * Make sure this goes before the inject in the spec. + */ + function fakeRouteProvider($provide: angular.auto.IProvideService): void; + + /** + * Stub out the $stateProvider so we avoid + * all routing calls, including the default state + * which runs on every test otherwise. + * Make sure this goes before the inject in the spec. + */ + function fakeStateProvider($provide: angular.auto.IProvideService): void; + + /** + * Registers a fake toastr service that you can spy on + */ + function fakeToastr($provide: angular.auto.IProvideService): void; + + /** + * Inject selected services into the windows object during test + * then remove them when test ends with an `afterEach`. + * + * spares us the repetition of creating common service vars and injecting them + * + * Option: the first argument may be the mocha spec context object (`this`) + * It MUST be `this` if you what to check for mocha global leaks. + * Do NOT supply `this` as the first arg if you're not running mocha specs. + * + * remaining inject arguments may take one of 3 forms : + * + * function - This fn will be passed to ngMocks.inject. + * Annotations extracted after inject does its thing. + * [strings] - same string array you'd use to set fn.$inject + * (...string) - string arguments turned into a string array + */ + function inject(context?: Function, ...args: string[]): void; + + /** + * Write to console if bard debugging flag is on + */ + function log(message: any): void; + + /** + * Listen to mocha test runner events + * Usage in browser: + * var runner = mocha.run(); + * bard.mochaRunnerListener(runner); + */ + function mochaRunnerListener(runner: Mocha.IRunner): void; + + /** + * Mocks out a service with sinon stubbed functions + * that return the values specified in the config + * + * If the config value is `undefined`, + * stub the service method with a dummy that doesn't return a value + * + * If the config value is a function, set service property with it + * + * If a service member is a property, not a function, + * set it with the config value + * If a service member name is not a key in config, + * follow the same logic as above to set its members + * using the config._default value (which is `undefined` if omitted) + * + * If there is a config entry that is NOT a member of the service + * add mocked function to the service using the config value + */ + function mockService(service: any, config: any): any; + + /** + * Replaces the accented characters of many European languages w/ unaccented chars + * Use it in JavaScript string sorts where such characters may be encountered + * Matches the default string comparers of most databases. + * Ex: replaceAccentChars(a.Name) < replaceAccentChars(b.Name) + * instead of: a.Name < b.Name + */ + function replaceAccentChars(text: string): string; + + /** + * Assert that there are no outstanding HTTP requests after test is complete + * For use with ngMocks; doesn't work for async server integration tests + */ + function verifyNoOutstandingHttpRequests(): void; + + /** + * Returns a function that execute a callback function + * (typically a fn making asserts) within a try/catch + * The try/catch then calls the ambient "done" function + * in the appropriate way for both success and failure + */ + function wrapWithDone(callback: Function, done: Function): Function; +}