diff --git a/gulp-debug/gulp-debug-tests.ts b/gulp-debug/gulp-debug-tests.ts
new file mode 100644
index 000000000..e6485d8da
--- /dev/null
+++ b/gulp-debug/gulp-debug-tests.ts
@@ -0,0 +1,14 @@
+///
+///
+
+import gulp = require('gulp');
+import debug = require('gulp-debug');
+
+gulp.task('default', () =>
+ gulp.src('foo.js')
+ .pipe(debug({title: 'unicorn:'}))
+ .pipe(gulp.dest('dist'))
+);
+
+
+debug();
diff --git a/gulp-debug/gulp-debug.d.ts b/gulp-debug/gulp-debug.d.ts
new file mode 100644
index 000000000..743f5f5eb
--- /dev/null
+++ b/gulp-debug/gulp-debug.d.ts
@@ -0,0 +1,17 @@
+// Type definitions for gulp-debug v2.0.1
+// Project: https://github.com/sindresorhus/gulp-debug
+// Definitions by: Tanguy Krotoff
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+///
+
+declare module 'gulp-debug' {
+ interface IOptions {
+ title?: string;
+ minimal?: boolean;
+ }
+
+ function debug(options?: IOptions): NodeJS.ReadWriteStream;
+
+ export = debug;
+}
diff --git a/gulp-jasmine-browser/gulp-jasmine-browser-tests.ts b/gulp-jasmine-browser/gulp-jasmine-browser-tests.ts
new file mode 100644
index 000000000..c28b312f4
--- /dev/null
+++ b/gulp-jasmine-browser/gulp-jasmine-browser-tests.ts
@@ -0,0 +1,32 @@
+///
+///
+
+import gulp = require('gulp');
+import jasmineBrowser = require('gulp-jasmine-browser');
+
+gulp.task('jasmine', () =>
+ gulp.src(['src/**/*.js', 'spec/**/*_spec.js'])
+ .pipe(jasmineBrowser.specRunner())
+ .pipe(jasmineBrowser.server({port: 8888}))
+);
+
+
+gulp.task('jasmine-phantom', () =>
+ gulp.src(['src/**/*.js', 'spec/**/*_spec.js'])
+ .pipe(jasmineBrowser.specRunner({console: true}))
+ .pipe(jasmineBrowser.headless())
+);
+
+
+gulp.task('jasmine-slimerjs', () =>
+ gulp.src(['src/**/*.js', 'spec/**/*_spec.js'])
+ .pipe(jasmineBrowser.specRunner({console: true}))
+ .pipe(jasmineBrowser.headless({driver: 'slimerjs'}))
+);
+
+
+gulp.task('jasmine', () =>
+ gulp.src('spec/**/*_spec.js')
+ .pipe(jasmineBrowser.specRunner())
+ .pipe(jasmineBrowser.server())
+);
diff --git a/gulp-jasmine-browser/gulp-jasmine-browser.d.ts b/gulp-jasmine-browser/gulp-jasmine-browser.d.ts
new file mode 100644
index 000000000..e2e717969
--- /dev/null
+++ b/gulp-jasmine-browser/gulp-jasmine-browser.d.ts
@@ -0,0 +1,17 @@
+// Type definitions for gulp-jasmine-browser v0.1.4
+// Project: https://github.com/jasmine/gulp-jasmine-browser
+// Definitions by: Tanguy Krotoff
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+///
+
+declare module 'gulp-jasmine-browser' {
+ interface IJasmineBrowser {
+ specRunner(options?: any): NodeJS.ReadWriteStream;
+ server(options?: any): NodeJS.ReadWriteStream;
+ headless(options?: any): NodeJS.ReadWriteStream;
+ }
+
+ var jasmineBrowser: IJasmineBrowser;
+ export = jasmineBrowser;
+}
diff --git a/gulp-protractor/gulp-protractor-tests.ts b/gulp-protractor/gulp-protractor-tests.ts
new file mode 100644
index 000000000..4224084d8
--- /dev/null
+++ b/gulp-protractor/gulp-protractor-tests.ts
@@ -0,0 +1,20 @@
+///
+///
+
+import gulp = require('gulp');
+import protractor = require('gulp-protractor');
+
+gulp.src(["./src/tests/*.js"])
+ .pipe(protractor.protractor({
+ configFile: "test/protractor.config.js",
+ args: ['--baseUrl', 'http://127.0.0.1:8000']
+ }))
+
+
+gulp.task('webdriver_standalone', protractor.webdriver_standalone);
+
+
+gulp.task('webdriver-update', protractor.webdriver_update);
+
+
+console.log(protractor.getProtractorDir());
diff --git a/gulp-protractor/gulp-protractor.d.ts b/gulp-protractor/gulp-protractor.d.ts
new file mode 100644
index 000000000..d0317e2e2
--- /dev/null
+++ b/gulp-protractor/gulp-protractor.d.ts
@@ -0,0 +1,25 @@
+// Type definitions for gulp-protractor v1.0.0
+// Project: https://github.com/mllrsohn/gulp-protractor
+// Definitions by: Tanguy Krotoff
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+///
+///
+
+declare module 'gulp-protractor' {
+ interface IOptions {
+ configFile?: string;
+ args?: Array;
+ debug?: boolean;
+ }
+
+ interface IGulpProtractor {
+ getProtractorDir(): string;
+ protractor(options?: IOptions): NodeJS.ReadWriteStream;
+ webdriver_standalone: gulp.ITaskCallback;
+ webdriver_update: gulp.ITaskCallback;
+ }
+
+ var protractor: IGulpProtractor;
+ export = protractor;
+}
diff --git a/gulp-rev-replace/gulp-rev-replace-tests.ts b/gulp-rev-replace/gulp-rev-replace-tests.ts
new file mode 100644
index 000000000..57515c9ac
--- /dev/null
+++ b/gulp-rev-replace/gulp-rev-replace-tests.ts
@@ -0,0 +1,63 @@
+///
+///
+///
+///
+
+import gulp = require('gulp');
+import revReplace = require('gulp-rev-replace');
+import rev = require('gulp-rev');
+import useref = require('gulp-useref');
+
+gulp.task("index", () => {
+ var userefAssets = useref.assets();
+
+ return gulp.src("src/index.html")
+ .pipe(userefAssets) // Concatenate with gulp-useref
+ .pipe(rev()) // Rename the concatenated files
+ .pipe(userefAssets.restore())
+ .pipe(useref())
+ .pipe(revReplace()) // Substitute in new filenames
+ .pipe(gulp.dest('public'));
+});
+
+
+var opt = {
+ srcFolder: 'src',
+ distFolder: 'dist'
+}
+
+gulp.task("revision", ["dist:css", "dist:js"], () =>
+ gulp.src(["dist/**/*.css", "dist/**/*.js"])
+ .pipe(rev())
+ .pipe(gulp.dest(opt.distFolder))
+ .pipe(rev.manifest())
+ .pipe(gulp.dest(opt.distFolder))
+);
+
+gulp.task("revreplace", ["revision"], () => {
+ var manifest = gulp.src("./" + opt.distFolder + "/rev-manifest.json");
+
+ return gulp.src(opt.srcFolder + "/index.html")
+ .pipe(revReplace({manifest: manifest}))
+ .pipe(gulp.dest(opt.distFolder));
+});
+
+
+function replaceJsIfMap(filename: string): string {
+ if (filename.indexOf('.map') > -1) {
+ return filename.replace('js/', '');
+ }
+ return filename;
+}
+
+gulp.task("revreplace", ["revision"], () => {
+ var manifest = gulp.src("./" + opt.distFolder + "/rev-manifest.json");
+
+ return gulp.src(opt.distFolder + '**/*.js')
+ .pipe(revReplace({
+ manifest: manifest,
+ modifyUnreved: replaceJsIfMap,
+ modifyReved: replaceJsIfMap
+ }))
+ .pipe(gulp.dest(opt.distFolder));
+});
diff --git a/gulp-rev-replace/gulp-rev-replace.d.ts b/gulp-rev-replace/gulp-rev-replace.d.ts
new file mode 100644
index 000000000..3e683d183
--- /dev/null
+++ b/gulp-rev-replace/gulp-rev-replace.d.ts
@@ -0,0 +1,21 @@
+// Type definitions for gulp-rev-replace v0.2.1
+// Project: https://github.com/jamesknelson/gulp-rev-replace
+// Definitions by: Tanguy Krotoff
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+///
+
+declare module 'gulp-rev-replace' {
+ interface IOptions {
+ canonicalUris?: boolean;
+ replaceInExtensions?: Array;
+ prefix?: string;
+ manifest?: NodeJS.ReadWriteStream;
+ modifyUnreved?: Function;
+ modifyReved?: Function;
+ }
+
+ function revReplace(options?: IOptions): NodeJS.ReadWriteStream;
+
+ export = revReplace;
+}
diff --git a/gulp-rev/gulp-rev-tests.ts b/gulp-rev/gulp-rev-tests.ts
new file mode 100644
index 000000000..37661424f
--- /dev/null
+++ b/gulp-rev/gulp-rev-tests.ts
@@ -0,0 +1,36 @@
+///
+///
+
+import gulp = require('gulp');
+import rev = require('gulp-rev');
+
+gulp.task('default', () =>
+ gulp.src('src/*.css')
+ .pipe(rev())
+ .pipe(gulp.dest('dist'))
+);
+
+gulp.task('default', () =>
+ // by default, gulp would pick `assets/css` as the base,
+ // so we need to set it explicitly:
+ gulp.src(['assets/css/*.css', 'assets/js/*.js'], {base: 'assets'})
+ .pipe(gulp.dest('build/assets')) // copy original assets to build dir
+ .pipe(rev())
+ .pipe(gulp.dest('build/assets')) // write rev'd assets to build dir
+ .pipe(rev.manifest())
+ .pipe(gulp.dest('build/assets')) // write manifest to build dir
+);
+
+gulp.task('default', () =>
+ // by default, gulp would pick `assets/css` as the base,
+ // so we need to set it explicitly:
+ gulp.src(['assets/css/*.css', 'assets/js/*.js'], {base: 'assets'})
+ .pipe(gulp.dest('build/assets'))
+ .pipe(rev())
+ .pipe(gulp.dest('build/assets'))
+ .pipe(rev.manifest({
+ base: 'build/assets',
+ merge: true // merge with the existing manifest (if one exists)
+ }))
+ .pipe(gulp.dest('build/assets'))
+);
diff --git a/gulp-rev/gulp-rev.d.ts b/gulp-rev/gulp-rev.d.ts
new file mode 100644
index 000000000..6cd432b0d
--- /dev/null
+++ b/gulp-rev/gulp-rev.d.ts
@@ -0,0 +1,26 @@
+// Type definitions for gulp-csso v5.0.1
+// Project: https://github.com/sindresorhus/gulp-rev
+// Definitions by: Tanguy Krotoff
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+///
+
+declare module 'gulp-rev' {
+ interface IOptions {
+ base?: string;
+ cwd?: string;
+ merge?: boolean;
+ }
+
+ interface IRev {
+ (): NodeJS.ReadWriteStream;
+
+ manifest(): NodeJS.ReadWriteStream;
+ manifest(path?: string): NodeJS.ReadWriteStream;
+ manifest(options?: IOptions): NodeJS.ReadWriteStream;
+ manifest(path?: string, options?: IOptions): NodeJS.ReadWriteStream;
+ }
+
+ var rev: IRev;
+ export = rev;
+}
diff --git a/gulp-size/gulp-size-tests.ts b/gulp-size/gulp-size-tests.ts
new file mode 100644
index 000000000..bfa2c6a04
--- /dev/null
+++ b/gulp-size/gulp-size-tests.ts
@@ -0,0 +1,27 @@
+///
+///
+///
+
+import gulp = require('gulp');
+import size = require('gulp-size');
+import debug = require('gulp-debug');
+
+gulp.task('default', () =>
+ gulp.src('fixture.js')
+ .pipe(size())
+ .pipe(gulp.dest('dist'))
+);
+
+
+gulp.task('default', () => {
+ var s = size();
+
+ return gulp.src('fixture.js')
+ .pipe(s)
+ .pipe(gulp.dest('dist'))
+ .pipe(debug({title: 'Total size ' + s.prettySize}));
+});
+
+
+size();
+size({showFiles: true, gzip: true});
diff --git a/gulp-size/gulp-size.d.ts b/gulp-size/gulp-size.d.ts
new file mode 100644
index 000000000..d25f6ed94
--- /dev/null
+++ b/gulp-size/gulp-size.d.ts
@@ -0,0 +1,23 @@
+// Type definitions for gulp-size v1.2.3
+// Project: https://github.com/sindresorhus/gulp-size
+// Definitions by: Tanguy Krotoff
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+///
+
+declare module 'gulp-size' {
+ interface IOptions {
+ showFiles?: boolean;
+ gzip?: boolean;
+ title?: string;
+ }
+
+ interface ISizeStream extends NodeJS.ReadWriteStream {
+ size: number;
+ prettySize: string;
+ }
+
+ function size(options?: IOptions): ISizeStream;
+
+ export = size;
+}
diff --git a/gulp-useref/gulp-useref-tests.ts b/gulp-useref/gulp-useref-tests.ts
new file mode 100644
index 000000000..95c35662d
--- /dev/null
+++ b/gulp-useref/gulp-useref-tests.ts
@@ -0,0 +1,15 @@
+///
+///
+
+import gulp = require('gulp');
+import useref = require('gulp-useref');
+
+gulp.task('default', () => {
+ var assets = useref.assets();
+
+ return gulp.src('app/*.html')
+ .pipe(assets)
+ .pipe(assets.restore())
+ .pipe(useref())
+ .pipe(gulp.dest('dist'));
+});
diff --git a/gulp-useref/gulp-useref.d.ts b/gulp-useref/gulp-useref.d.ts
new file mode 100644
index 000000000..b1628aa5f
--- /dev/null
+++ b/gulp-useref/gulp-useref.d.ts
@@ -0,0 +1,25 @@
+// Type definitions for gulp-useref v1.2.0
+// Project: https://github.com/jonkemp/gulp-useref
+// Definitions by: Tanguy Krotoff
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+///
+
+declare module 'gulp-useref' {
+ interface IAssetsOptions {
+ searchPath?: string | string[];
+ noconcat?: boolean;
+ }
+
+ interface IAssetsStream extends NodeJS.ReadWriteStream {
+ restore(): NodeJS.ReadWriteStream;
+ }
+
+ interface IUseref {
+ (options?: any): NodeJS.ReadWriteStream;
+ assets(options?: IAssetsOptions): IAssetsStream;
+ }
+
+ var useref: IUseref;
+ export = useref;
+}
diff --git a/gulp-watch/gulp-watch-tests.ts b/gulp-watch/gulp-watch-tests.ts
new file mode 100644
index 000000000..9d9303ac2
--- /dev/null
+++ b/gulp-watch/gulp-watch-tests.ts
@@ -0,0 +1,30 @@
+///
+///
+
+import gulp = require('gulp');
+import watch = require('gulp-watch');
+
+gulp.task('stream', () =>
+ gulp.src('css/**/*.css')
+ .pipe(watch('css/**/*.css'))
+ .pipe(gulp.dest('build'))
+);
+
+gulp.task('callback', (cb) =>
+ watch('css/**/*.css', () =>
+ gulp.src('css/**/*.css')
+ .pipe(watch('css/**/*.css'))
+ .on('end', cb)
+ )
+);
+
+gulp.task('build', () => {
+ var files = [
+ 'app/**/*.ts',
+ 'lib/**/*.ts',
+ 'components/**/*.ts',
+ ];
+
+ gulp.src(files, { base: '..' })
+ .pipe(watch(files, { base: '..' }));
+});
diff --git a/gulp-watch/gulp-watch.d.ts b/gulp-watch/gulp-watch.d.ts
new file mode 100644
index 000000000..35fb7de95
--- /dev/null
+++ b/gulp-watch/gulp-watch.d.ts
@@ -0,0 +1,27 @@
+// Type definitions for gulp-watch v4.1.1
+// Project: https://github.com/floatdrop/gulp-watch
+// Definitions by: Tanguy Krotoff
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+///
+
+declare module 'gulp-watch' {
+ interface IOptions {
+ ignoreInitial?: boolean;
+ events?: Array;
+ base?: string;
+ name?: string;
+ verbose?: boolean;
+ readDelay?: number;
+ }
+
+ interface IWatchStream extends NodeJS.ReadWriteStream {
+ add(path: string | Array): NodeJS.ReadWriteStream;
+ unwatch(path: string | Array): NodeJS.ReadWriteStream;
+ close(): NodeJS.ReadWriteStream;
+ }
+
+ function watch(glob: string | Array, options?: IOptions, callback?: Function): IWatchStream;
+
+ export = watch;
+}
diff --git a/karma/karma-tests.ts b/karma/karma-tests.ts
new file mode 100644
index 000000000..b70e7273b
--- /dev/null
+++ b/karma/karma-tests.ts
@@ -0,0 +1,26 @@
+///
+///
+
+import gulp = require('gulp');
+import karma = require('karma');
+
+function runKarma(singleRun: boolean): void {
+ karma.server.start({
+ configFile: __dirname + '/karma.conf.js',
+ singleRun: singleRun
+ });
+}
+
+gulp.task('test:unit:karma', ['build:test:unit'], () => runKarma(true));
+
+
+karma.server.start({port: 9876}, (exitCode) => {
+ console.log('Karma has exited with ' + exitCode);
+ process.exit(exitCode);
+});
+
+
+karma.runner.run({port: 9876}, (exitCode) => {
+ console.log('Karma has exited with ' + exitCode);
+ process.exit(exitCode);
+});
diff --git a/karma/karma.d.ts b/karma/karma.d.ts
new file mode 100644
index 000000000..c66e6fe06
--- /dev/null
+++ b/karma/karma.d.ts
@@ -0,0 +1,24 @@
+// Type definitions for karma v0.12.37
+// Project: https://github.com/karma-runner/karma
+// Definitions by: Tanguy Krotoff
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+declare module 'karma' {
+ // See Karma public API https://karma-runner.github.io/0.12/dev/public-api.html
+
+ interface IKarmaServer {
+ start(options?: any, callback?: (exitCode: number) => void): void;
+ }
+
+ interface IKarmaRunner {
+ run(options?: any, callback?: (exitCode: number) => void): void;
+ }
+
+ interface IKarma {
+ server: IKarmaServer;
+ runner: IKarmaRunner;
+ }
+
+ var karma: IKarma;
+ export = karma;
+}
diff --git a/merge2/merge2-tests.ts b/merge2/merge2-tests.ts
new file mode 100644
index 000000000..bba0dd0a3
--- /dev/null
+++ b/merge2/merge2-tests.ts
@@ -0,0 +1,64 @@
+///
+///
+
+import gulp = require('gulp');
+import merge2 = require('merge2');
+
+gulp.task('app-js', () =>
+ merge2(
+ gulp.src('static/src/tpl/*.html'),
+ gulp.src([
+ 'static/src/js/app.js',
+ 'static/src/js/locale_zh-cn.js',
+ 'static/src/js/router.js',
+ 'static/src/js/tools.js',
+ 'static/src/js/services.js',
+ 'static/src/js/filters.js',
+ 'static/src/js/directives.js',
+ 'static/src/js/controllers.js'
+ ])
+ )
+ .pipe(gulp.dest('static/dist/js/'))
+);
+
+
+var stream1 = gulp.src('*.html');
+var stream2 = gulp.src('*.html');
+var stream3 = gulp.src('*.html');
+var stream4 = gulp.src('*.html');
+var stream5 = gulp.src('*.html');
+var stream6 = gulp.src('*.html');
+var stream7 = gulp.src('*.html');
+
+
+var stream = merge2([stream1, stream2], stream3, {end: false})
+//...
+stream.add(stream4, stream5);
+//..
+stream.end();
+
+
+// equal to merge2([stream1, stream2], stream3)
+var stream = merge2();
+stream.add([stream1, stream2]);
+stream.add(stream3);
+
+
+// merge order:
+// 1. merge `stream1`;
+// 2. merge `stream2` and `stream3` in parallel after `stream1` merged;
+// 3. merge 'stream4' after `stream2` and `stream3` merged;
+var stream = merge2(stream1, [stream2, stream3], stream4);
+
+// merge order:
+// 1. merge `stream5` and `stream6` in parallel after `stream4` merged;
+// 2. merge 'stream7' after `stream5` and `stream6` merged;
+stream.add([stream5, stream6], stream7);
+
+
+// nest merge
+// equal to merge2(stream1, stream2, stream6, stream3, [stream4, stream5]);
+var streamA = merge2(stream1, stream2);
+var streamB = merge2(stream3, [stream4, stream5]);
+var stream = merge2(streamA, streamB);
+streamA.add(stream6);
diff --git a/merge2/merge2.d.ts b/merge2/merge2.d.ts
new file mode 100644
index 000000000..ebf1df758
--- /dev/null
+++ b/merge2/merge2.d.ts
@@ -0,0 +1,21 @@
+// Type definitions for merge2 v0.3.6
+// Project: https://github.com/teambition/merge2
+// Definitions by: Tanguy Krotoff
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+///
+
+declare module 'merge2' {
+ interface IOptions {
+ end?: boolean;
+ objectMode?: boolean;
+ }
+
+ interface IMerge2Stream extends NodeJS.ReadWriteStream {
+ add(...args: Array>): IMerge2Stream;
+ }
+
+ function merge2(...args: Array | IOptions>): IMerge2Stream;
+
+ export = merge2;
+}