diff --git a/circle.yml b/circle.yml index 599249d254..3316522162 100644 --- a/circle.yml +++ b/circle.yml @@ -17,7 +17,7 @@ dependencies: test: override: - - echo "No tests are written at the moment. But we will attempt to build the library with the latest changes." + - npm test - npm run build deployment: diff --git a/karma.conf.ts b/karma.conf.ts new file mode 100644 index 0000000000..da215d038e --- /dev/null +++ b/karma.conf.ts @@ -0,0 +1,60 @@ +const WATCH = process.argv.indexOf('--watch') > -1; + +module.exports = config => { + config.set({ + + // base path that will be used to resolve all patterns (eg. files, exclude) + basePath: './', + + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ['jasmine', 'browserify'], + + // list of files / patterns to load in the browser + files: [ + 'test/**/*.spec.ts' + ], + + // preprocess matching files before serving them to the browser + // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor + preprocessors: { + 'test/**/*.spec.ts': ['browserify'] + }, + + browserify: { + plugin: [ 'tsify' ], + extensions: ['.js', '.ts'] + }, + + phantomjsLauncher: { + // Have phantomjs exit if a ResourceError is encountered (useful if karma exits without killing phantom) + exitOnResourceError: true + }, + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + reporters: ['dots'], + + // web server port + port: 9876, + + // enable / disable colors in the output (reporters and logs) + colors: true, + + // level of logging + // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG + logLevel: config.LOG_INFO, + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: WATCH, + + // start these browsers + // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher + browsers: ['PhantomJS'], + + // Continuous Integration mode + // if true, Karma captures browsers, runs the tests and exits + singleRun: !WATCH + }); +}; diff --git a/package.json b/package.json index b0c46e4422..feac394595 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "decamelize": "^1.2.0", "dgeni": "^0.4.2", "dgeni-packages": "^0.10.18", + "es6-shim": "~0.35.1", "glob": "^6.0.4", "gulp": "^3.9.1", "gulp-rename": "^1.2.2", @@ -26,18 +27,27 @@ "gulp-tslint": "^5.0.0", "gulp-uglify": "^1.5.4", "ionic-gulp-tslint": "^1.0.0", + "jasmine-core": "~2.5.0", + "karma": "~1.2.0", + "karma-browserify": "~5.1.0", + "karma-jasmine": "~1.0.2", + "karma-phantomjs-launcher": "~1.0.2", "lodash": "3.10.1", "minimist": "^1.1.3", "mkdirp": "^0.5.1", "node-html-encoder": "0.0.2", "q": "1.4.1", "semver": "^5.0.1", + "tsify": "~1.0.4", "tslint": "^3.8.1", "tslint-ionic-rules": "0.0.5", - "typescript": "^1.8.10" + "typescript": "^1.8.10", + "watchify": "~3.7.0" }, "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", + "test": "karma start", + "test:watch": "npm test -- --watch", + "start": "npm run test:watch", "lint": "./node_modules/.bin/gulp lint", "watch": "./node_modules/.bin/tsc -w", "build": "npm run lint && npm run build:js && npm run build:bundle && npm run build:minify", diff --git a/src/ng1.ts b/src/ng1.ts index 384bd02f8f..615b3f6aec 100644 --- a/src/ng1.ts +++ b/src/ng1.ts @@ -7,14 +7,15 @@ declare var window; */ export function initAngular1(plugins) { if (window.angular) { - window.angular.module('ionic.native', []); + + const ngModule = window.angular.module('ionic.native', []); for (var name in plugins) { let serviceName = '$cordova' + name; let cls = plugins[name]; (function(serviceName, cls, name) { - window.angular.module('ionic.native').service(serviceName, [function() { + ngModule.service(serviceName, [function() { var funcs = window.angular.copy(cls); funcs.prototype['name'] = name; return funcs; diff --git a/src/plugins/plugin.ts b/src/plugins/plugin.ts index e0eaa1587e..810c9fcc20 100644 --- a/src/plugins/plugin.ts +++ b/src/plugins/plugin.ts @@ -3,8 +3,6 @@ import { Observable } from 'rxjs/Observable'; declare var window; declare var Promise; -declare var $q; - /** * @private diff --git a/test/plugin.spec.ts b/test/plugin.spec.ts new file mode 100644 index 0000000000..3fd61f1597 --- /dev/null +++ b/test/plugin.spec.ts @@ -0,0 +1,141 @@ +/// + +import 'es6-shim'; +import {Plugin, Cordova} from './../src/plugins/plugin'; + +declare const window: any; +window.plugins = { + test: {} +}; + +const testPluginMeta = { + plugin: 'cordova-plugin-test', + pluginRef: 'plugins.test', + repo: 'https://github.com/apache/cordova-plugin-test', + platforms: ['Android', 'iOS'] +}; + +describe('plugin', () => { + + it('sync method', () => { + + window.plugins.test.syncMethod = () => { + return 'syncResult'; + }; + + @Plugin(testPluginMeta) + class Test { + + @Cordova({ + sync: true + }) + static syncMethod(arg: any): boolean { return; }; + + } + + const spy = spyOn(window.plugins.test, 'syncMethod').and.callThrough(); + const result = Test.syncMethod('foo'); + expect(result).toEqual('syncResult'); + expect(spy).toHaveBeenCalledWith('foo', undefined, undefined); + + }); + + it('normal order callback', done => { + + window.plugins.test.normalOrderCallback = (args, success, error) => { + success('normalOrderCallback'); + }; + + @Plugin(testPluginMeta) + class Test { + @Cordova() + static normalOrderCallback(args: any): Promise { return; } + } + + const spy = spyOn(window.plugins.test, 'normalOrderCallback').and.callThrough(); + Test.normalOrderCallback('foo').then(result => { + expect(result).toEqual('normalOrderCallback'); + done(); + }); + expect(spy.calls.mostRecent().args[0]).toEqual('foo'); + + }); + + it('reverse order callback', done => { + + window.plugins.test.reverseOrderCallback = (success, error, args) => { + success('reverseOrderCallback'); + }; + + @Plugin(testPluginMeta) + class Test { + + @Cordova({ + callbackOrder: 'reverse' + }) + static reverseOrderCallback(args: any): Promise { return; } + + } + + const spy = spyOn(window.plugins.test, 'reverseOrderCallback').and.callThrough(); + Test.reverseOrderCallback('foo').then(result => { + expect(result).toEqual('reverseOrderCallback'); + done(); + }); + expect(spy.calls.mostRecent().args[2]).toEqual('foo'); + + }); + + it('node style callback', done => { + + window.plugins.test.nodeStyleCallback = (args, done) => { + done(null, 'nodeStyleCallback'); + }; + + @Plugin(testPluginMeta) + class Test { + + @Cordova({ + callbackStyle: 'node' + }) + static nodeStyleCallback(args: any): Promise { return; } + + } + + const spy = spyOn(window.plugins.test, 'nodeStyleCallback').and.callThrough(); + Test.nodeStyleCallback('foo').then(result => { + expect(result).toEqual('nodeStyleCallback'); + done(); + }); + expect(spy.calls.mostRecent().args[0]).toEqual('foo'); + + }); + + it('object style callback', done => { + + window.plugins.test.objectStyleCallback = (args, {success}) => { + success('objectStyleCallback'); + }; + + @Plugin(testPluginMeta) + class Test { + + @Cordova({ + callbackStyle: 'object', + successName: 'success', + errorName: 'error' + }) + static objectStyleCallback(args: any): Promise { return; } + + } + + const spy = spyOn(window.plugins.test, 'objectStyleCallback').and.callThrough(); + Test.objectStyleCallback('foo').then(result => { + expect(result).toEqual('objectStyleCallback'); + done(); + }); + expect(spy.calls.mostRecent().args[0]).toEqual('foo'); + + }); + +}); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index fc1c522253..be48d5b1bc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,8 @@ "sourceMap": true, "declaration": true, "experimentalDecorators": true, - "outDir": "dist" + "outDir": "dist", + "moduleResolution": "node" }, "files": [ "typings/es6-shim/es6-shim.d.ts", diff --git a/typings.json b/typings.json new file mode 100644 index 0000000000..dbbc9d62fd --- /dev/null +++ b/typings.json @@ -0,0 +1,5 @@ +{ + "globalDevDependencies": { + "jasmine": "registry:dt/jasmine#2.2.0+20160621224255" + } +} diff --git a/typings/globals/jasmine/index.d.ts b/typings/globals/jasmine/index.d.ts new file mode 100644 index 0000000000..e81f5ace5d --- /dev/null +++ b/typings/globals/jasmine/index.d.ts @@ -0,0 +1,502 @@ +// Generated by typings +// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/c49913aa9ea419ea46c1c684e488cf2a10303b1a/jasmine/jasmine.d.ts +declare function describe(description: string, specDefinitions: () => void): void; +declare function fdescribe(description: string, specDefinitions: () => void): void; +declare function xdescribe(description: string, specDefinitions: () => void): void; + +declare function it(expectation: string, assertion?: () => void, timeout?: number): void; +declare function it(expectation: string, assertion?: (done: DoneFn) => void, timeout?: number): void; +declare function fit(expectation: string, assertion?: () => void, timeout?: number): void; +declare function fit(expectation: string, assertion?: (done: DoneFn) => void, timeout?: number): void; +declare function xit(expectation: string, assertion?: () => void, timeout?: number): void; +declare function xit(expectation: string, assertion?: (done: DoneFn) => void, timeout?: number): void; + +/** If you call the function pending anywhere in the spec body, no matter the expectations, the spec will be marked pending. */ +declare function pending(reason?: string): void; + +declare function beforeEach(action: () => void, timeout?: number): void; +declare function beforeEach(action: (done: DoneFn) => void, timeout?: number): void; +declare function afterEach(action: () => void, timeout?: number): void; +declare function afterEach(action: (done: DoneFn) => void, timeout?: number): void; + +declare function beforeAll(action: () => void, timeout?: number): void; +declare function beforeAll(action: (done: DoneFn) => void, timeout?: number): void; +declare function afterAll(action: () => void, timeout?: number): void; +declare function afterAll(action: (done: DoneFn) => void, timeout?: number): void; + +declare function expect(spy: Function): jasmine.Matchers; +declare function expect(actual: any): jasmine.Matchers; + +declare function fail(e?: any): void; +/** Action method that should be called when the async work is complete */ +interface DoneFn extends Function { + (): void; + + /** fails the spec and indicates that it has completed. If the message is an Error, Error.message is used */ + fail: (message?: Error|string) => void; +} + +declare function spyOn(object: any, method: string): jasmine.Spy; + +declare function runs(asyncMethod: Function): void; +declare function waitsFor(latchMethod: () => boolean, failureMessage?: string, timeout?: number): void; +declare function waits(timeout?: number): void; + +declare namespace jasmine { + + var clock: () => Clock; + + function any(aclass: any): Any; + function anything(): Any; + function arrayContaining(sample: any[]): ArrayContaining; + function objectContaining(sample: any): ObjectContaining; + function createSpy(name: string, originalFn?: Function): Spy; + function createSpyObj(baseName: string, methodNames: any[]): any; + function createSpyObj(baseName: string, methodNames: any[]): T; + function pp(value: any): string; + function getEnv(): Env; + function addCustomEqualityTester(equalityTester: CustomEqualityTester): void; + function addMatchers(matchers: CustomMatcherFactories): void; + function stringMatching(str: string): Any; + function stringMatching(str: RegExp): Any; + + interface Any { + + new (expectedClass: any): any; + + jasmineMatches(other: any): boolean; + jasmineToString(): string; + } + + // taken from TypeScript lib.core.es6.d.ts, applicable to CustomMatchers.contains() + interface ArrayLike { + length: number; + [n: number]: T; + } + + interface ArrayContaining { + new (sample: any[]): any; + + asymmetricMatch(other: any): boolean; + jasmineToString(): string; + } + + interface ObjectContaining { + new (sample: any): any; + + jasmineMatches(other: any, mismatchKeys: any[], mismatchValues: any[]): boolean; + jasmineToString(): string; + } + + interface Block { + + new (env: Env, func: SpecFunction, spec: Spec): any; + + execute(onComplete: () => void): void; + } + + interface WaitsBlock extends Block { + new (env: Env, timeout: number, spec: Spec): any; + } + + interface WaitsForBlock extends Block { + new (env: Env, timeout: number, latchFunction: SpecFunction, message: string, spec: Spec): any; + } + + interface Clock { + install(): void; + uninstall(): void; + /** Calls to any registered callback are triggered when the clock is ticked forward via the jasmine.clock().tick function, which takes a number of milliseconds. */ + tick(ms: number): void; + mockDate(date?: Date): void; + } + + interface CustomEqualityTester { + (first: any, second: any): boolean; + } + + interface CustomMatcher { + compare(actual: T, expected: T): CustomMatcherResult; + compare(actual: any, expected: any): CustomMatcherResult; + } + + interface CustomMatcherFactory { + (util: MatchersUtil, customEqualityTesters: Array): CustomMatcher; + } + + interface CustomMatcherFactories { + [index: string]: CustomMatcherFactory; + } + + interface CustomMatcherResult { + pass: boolean; + message?: string; + } + + interface MatchersUtil { + equals(a: any, b: any, customTesters?: Array): boolean; + contains(haystack: ArrayLike | string, needle: any, customTesters?: Array): boolean; + buildFailureMessage(matcherName: string, isNot: boolean, actual: any, ...expected: Array): string; + } + + interface Env { + setTimeout: any; + clearTimeout: void; + setInterval: any; + clearInterval: void; + updateInterval: number; + + currentSpec: Spec; + + matchersClass: Matchers; + + version(): any; + versionString(): string; + nextSpecId(): number; + addReporter(reporter: Reporter): void; + execute(): void; + describe(description: string, specDefinitions: () => void): Suite; + // ddescribe(description: string, specDefinitions: () => void): Suite; Not a part of jasmine. Angular team adds these + beforeEach(beforeEachFunction: () => void): void; + beforeAll(beforeAllFunction: () => void): void; + currentRunner(): Runner; + afterEach(afterEachFunction: () => void): void; + afterAll(afterAllFunction: () => void): void; + xdescribe(desc: string, specDefinitions: () => void): XSuite; + it(description: string, func: () => void): Spec; + // iit(description: string, func: () => void): Spec; Not a part of jasmine. Angular team adds these + xit(desc: string, func: () => void): XSpec; + compareRegExps_(a: RegExp, b: RegExp, mismatchKeys: string[], mismatchValues: string[]): boolean; + compareObjects_(a: any, b: any, mismatchKeys: string[], mismatchValues: string[]): boolean; + equals_(a: any, b: any, mismatchKeys: string[], mismatchValues: string[]): boolean; + contains_(haystack: any, needle: any): boolean; + addCustomEqualityTester(equalityTester: CustomEqualityTester): void; + addMatchers(matchers: CustomMatcherFactories): void; + specFilter(spec: Spec): boolean; + throwOnExpectationFailure(value: boolean): void; + } + + interface FakeTimer { + + new (): any; + + reset(): void; + tick(millis: number): void; + runFunctionsWithinRange(oldMillis: number, nowMillis: number): void; + scheduleFunction(timeoutKey: any, funcToCall: () => void, millis: number, recurring: boolean): void; + } + + interface HtmlReporter { + new (): any; + } + + interface HtmlSpecFilter { + new (): any; + } + + interface Result { + type: string; + } + + interface NestedResults extends Result { + description: string; + + totalCount: number; + passedCount: number; + failedCount: number; + + skipped: boolean; + + rollupCounts(result: NestedResults): void; + log(values: any): void; + getItems(): Result[]; + addResult(result: Result): void; + passed(): boolean; + } + + interface MessageResult extends Result { + values: any; + trace: Trace; + } + + interface ExpectationResult extends Result { + matcherName: string; + passed(): boolean; + expected: any; + actual: any; + message: string; + trace: Trace; + } + + interface Trace { + name: string; + message: string; + stack: any; + } + + interface PrettyPrinter { + + new (): any; + + format(value: any): void; + iterateObject(obj: any, fn: (property: string, isGetter: boolean) => void): void; + emitScalar(value: any): void; + emitString(value: string): void; + emitArray(array: any[]): void; + emitObject(obj: any): void; + append(value: any): void; + } + + interface StringPrettyPrinter extends PrettyPrinter { + } + + interface Queue { + + new (env: any): any; + + env: Env; + ensured: boolean[]; + blocks: Block[]; + running: boolean; + index: number; + offset: number; + abort: boolean; + + addBefore(block: Block, ensure?: boolean): void; + add(block: any, ensure?: boolean): void; + insertNext(block: any, ensure?: boolean): void; + start(onComplete?: () => void): void; + isRunning(): boolean; + next_(): void; + results(): NestedResults; + } + + interface Matchers { + + new (env: Env, actual: any, spec: Env, isNot?: boolean): any; + + env: Env; + actual: any; + spec: Env; + isNot?: boolean; + message(): any; + + toBe(expected: any, expectationFailOutput?: any): boolean; + toEqual(expected: any, expectationFailOutput?: any): boolean; + toMatch(expected: string | RegExp, expectationFailOutput?: any): boolean; + toBeDefined(expectationFailOutput?: any): boolean; + toBeUndefined(expectationFailOutput?: any): boolean; + toBeNull(expectationFailOutput?: any): boolean; + toBeNaN(): boolean; + toBeTruthy(expectationFailOutput?: any): boolean; + toBeFalsy(expectationFailOutput?: any): boolean; + toHaveBeenCalled(): boolean; + toHaveBeenCalledWith(...params: any[]): boolean; + toHaveBeenCalledTimes(expected: number): boolean; + toContain(expected: any, expectationFailOutput?: any): boolean; + toBeLessThan(expected: number, expectationFailOutput?: any): boolean; + toBeGreaterThan(expected: number, expectationFailOutput?: any): boolean; + toBeCloseTo(expected: number, precision?: any, expectationFailOutput?: any): boolean; + toThrow(expected?: any): boolean; + toThrowError(message?: string | RegExp): boolean; + toThrowError(expected?: new (...args: any[]) => Error, message?: string | RegExp): boolean; + not: Matchers; + + Any: Any; + } + + interface Reporter { + reportRunnerStarting(runner: Runner): void; + reportRunnerResults(runner: Runner): void; + reportSuiteResults(suite: Suite): void; + reportSpecStarting(spec: Spec): void; + reportSpecResults(spec: Spec): void; + log(str: string): void; + } + + interface MultiReporter extends Reporter { + addReporter(reporter: Reporter): void; + } + + interface Runner { + + new (env: Env): any; + + execute(): void; + beforeEach(beforeEachFunction: SpecFunction): void; + afterEach(afterEachFunction: SpecFunction): void; + beforeAll(beforeAllFunction: SpecFunction): void; + afterAll(afterAllFunction: SpecFunction): void; + finishCallback(): void; + addSuite(suite: Suite): void; + add(block: Block): void; + specs(): Spec[]; + suites(): Suite[]; + topLevelSuites(): Suite[]; + results(): NestedResults; + } + + interface SpecFunction { + (spec?: Spec): void; + } + + interface SuiteOrSpec { + id: number; + env: Env; + description: string; + queue: Queue; + } + + interface Spec extends SuiteOrSpec { + + new (env: Env, suite: Suite, description: string): any; + + suite: Suite; + + afterCallbacks: SpecFunction[]; + spies_: Spy[]; + + results_: NestedResults; + matchersClass: Matchers; + + getFullName(): string; + results(): NestedResults; + log(arguments: any): any; + runs(func: SpecFunction): Spec; + addToQueue(block: Block): void; + addMatcherResult(result: Result): void; + expect(actual: any): any; + waits(timeout: number): Spec; + waitsFor(latchFunction: SpecFunction, timeoutMessage?: string, timeout?: number): Spec; + fail(e?: any): void; + getMatchersClass_(): Matchers; + addMatchers(matchersPrototype: CustomMatcherFactories): void; + finishCallback(): void; + finish(onComplete?: () => void): void; + after(doAfter: SpecFunction): void; + execute(onComplete?: () => void): any; + addBeforesAndAftersToQueue(): void; + explodes(): void; + spyOn(obj: any, methodName: string, ignoreMethodDoesntExist: boolean): Spy; + removeAllSpies(): void; + } + + interface XSpec { + id: number; + runs(): void; + } + + interface Suite extends SuiteOrSpec { + + new (env: Env, description: string, specDefinitions: () => void, parentSuite: Suite): any; + + parentSuite: Suite; + + getFullName(): string; + finish(onComplete?: () => void): void; + beforeEach(beforeEachFunction: SpecFunction): void; + afterEach(afterEachFunction: SpecFunction): void; + beforeAll(beforeAllFunction: SpecFunction): void; + afterAll(afterAllFunction: SpecFunction): void; + results(): NestedResults; + add(suiteOrSpec: SuiteOrSpec): void; + specs(): Spec[]; + suites(): Suite[]; + children(): any[]; + execute(onComplete?: () => void): void; + } + + interface XSuite { + execute(): void; + } + + interface Spy { + (...params: any[]): any; + + identity: string; + and: SpyAnd; + calls: Calls; + mostRecentCall: { args: any[]; }; + argsForCall: any[]; + wasCalled: boolean; + } + + interface SpyAnd { + /** By chaining the spy with and.callThrough, the spy will still track all calls to it but in addition it will delegate to the actual implementation. */ + callThrough(): Spy; + /** By chaining the spy with and.returnValue, all calls to the function will return a specific value. */ + returnValue(val: any): Spy; + /** By chaining the spy with and.returnValues, all calls to the function will return specific values in order until it reaches the end of the return values list. */ + returnValues(...values: any[]): Spy; + /** By chaining the spy with and.callFake, all calls to the spy will delegate to the supplied function. */ + callFake(fn: Function): Spy; + /** By chaining the spy with and.throwError, all calls to the spy will throw the specified value. */ + throwError(msg: string): Spy; + /** When a calling strategy is used for a spy, the original stubbing behavior can be returned at any time with and.stub. */ + stub(): Spy; + } + + interface Calls { + /** By chaining the spy with calls.any(), will return false if the spy has not been called at all, and then true once at least one call happens. **/ + any(): boolean; + /** By chaining the spy with calls.count(), will return the number of times the spy was called **/ + count(): number; + /** By chaining the spy with calls.argsFor(), will return the arguments passed to call number index **/ + argsFor(index: number): any[]; + /** By chaining the spy with calls.allArgs(), will return the arguments to all calls **/ + allArgs(): any[]; + /** By chaining the spy with calls.all(), will return the context (the this) and arguments passed all calls **/ + all(): CallInfo[]; + /** By chaining the spy with calls.mostRecent(), will return the context (the this) and arguments for the most recent call **/ + mostRecent(): CallInfo; + /** By chaining the spy with calls.first(), will return the context (the this) and arguments for the first call **/ + first(): CallInfo; + /** By chaining the spy with calls.reset(), will clears all tracking for a spy **/ + reset(): void; + } + + interface CallInfo { + /** The context (the this) for the call */ + object: any; + /** All arguments passed to the call */ + args: any[]; + /** The return value of the call */ + returnValue: any; + } + + interface Util { + inherit(childClass: Function, parentClass: Function): any; + formatException(e: any): any; + htmlEscape(str: string): string; + argsToArray(args: any): any; + extend(destination: any, source: any): any; + } + + interface JsApiReporter extends Reporter { + + started: boolean; + finished: boolean; + result: any; + messages: any; + + new (): any; + + suites(): Suite[]; + summarize_(suiteOrSpec: SuiteOrSpec): any; + results(): any; + resultsForSpec(specId: any): any; + log(str: any): any; + resultsForSpecs(specIds: any): any; + summarizeResult_(result: any): any; + } + + interface Jasmine { + Spec: Spec; + clock: Clock; + util: Util; + } + + export var HtmlReporter: HtmlReporter; + export var HtmlSpecFilter: HtmlSpecFilter; + export var DEFAULT_TIMEOUT_INTERVAL: number; +} \ No newline at end of file diff --git a/typings/globals/jasmine/typings.json b/typings/globals/jasmine/typings.json new file mode 100644 index 0000000000..3fb336cf1c --- /dev/null +++ b/typings/globals/jasmine/typings.json @@ -0,0 +1,8 @@ +{ + "resolution": "main", + "tree": { + "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/c49913aa9ea419ea46c1c684e488cf2a10303b1a/jasmine/jasmine.d.ts", + "raw": "registry:dt/jasmine#2.2.0+20160621224255", + "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/c49913aa9ea419ea46c1c684e488cf2a10303b1a/jasmine/jasmine.d.ts" + } +} diff --git a/typings/index.d.ts b/typings/index.d.ts new file mode 100644 index 0000000000..7cf8a3f75b --- /dev/null +++ b/typings/index.d.ts @@ -0,0 +1 @@ +///