diff --git a/.vscode/settings.json b/.vscode/settings.json index 1884ba9a0255..40ac686b302b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -15,8 +15,8 @@ "typescript.tsdk": "./node_modules/typescript/lib", // we want to use the TS server from our node_modules folder to control its version "tslint.enable": true, "python.linting.enabled": false, - "python.formatting.formatOnSave": false, "python.unitTest.promptToConfigure": false, "python.workspaceSymbols.enabled": false, - "python.formatting.provider": "yapf" + "python.formatting.provider": "none", + "files.insertFinalNewline": true } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 8a17b7da905f..e9a646b57d1c 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -47,6 +47,26 @@ "isDefault": true } }, + { + // Task that will replace 'Compile' and 'Hygiene', after being battle-tested. + "label": "Watch", + "type": "gulp", + "task": "watch", + "isBackground": true, + "presentation": { + "echo": true, + "reveal": "always", + "focus": false, + "panel": "shared" + }, + "problemMatcher": [ + "$tsc-watch", + { + "base": "$tslint5", + "fileLocation": "relative" + } + ] + }, { "label": "Hygiene (staged)", "type": "gulp", diff --git a/CODING_STANDARDS.md b/CODING_STANDARDS.md index 5b4749340248..1badbfbcca34 100644 --- a/CODING_STANDARDS.md +++ b/CODING_STANDARDS.md @@ -23,7 +23,8 @@ Use undefined. Do not use null. ### Comments -Use JSDoc style comments for functions, interfaces, enums, and classes. +* Comments must end with a period. +* Use JSDoc style comments for functions, interfaces, enums, and classes. ### Strings @@ -42,5 +43,4 @@ Use single quotes for strings. * `else` goes on a the same line from the closing curly brace. * Use 4 spaces per indentation. - - +* All files must end with an empty line. diff --git a/gulpfile.js b/gulpfile.js index ecf4dd1d5bca..61c47b6ae155 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,7 +1,7 @@ /*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ +* Copyright (c) Microsoft Corporation. All rights reserved. +* Licensed under the MIT License. See License.txt in the project root for license information. +*--------------------------------------------------------------------------------------------*/ 'use strict'; @@ -12,446 +12,300 @@ const tsfmt = require('typescript-formatter'); const tslint = require('tslint'); const relative = require('relative'); const ts = require('gulp-typescript'); -const watch = require('gulp-debounced-watch'); const cp = require('child_process'); const colors = require('colors/safe'); +const gitmodified = require('gulp-gitmodified'); +const path = require('path'); +const debounce = require('debounce'); /** - * Hygiene works by creating cascading subsets of all our files and - * passing them through a sequence of checks. Here are the current subsets, - * named according to the checks performed on them. Each subset contains - * the following one, as described in mathematical notation: - * - * all ⊃ eol ⊇ indentation ⊃ typescript - */ +* Hygiene works by creating cascading subsets of all our files and +* passing them through a sequence of checks. Here are the current subsets, +* named according to the checks performed on them. Each subset contains +* the following one, as described in mathematical notation: +* +* all ⊃ indentation ⊃ typescript +*/ const all = [ - 'src/**/*', - 'src/client/**/*', -]; - -const eolFilter = [ - '**', - '!.editorconfig', - '!.eslintrc', - '!.gitignore', - '!.gitmodules', - '!.jshintignore', - '!.jshintrc', - '!.npmrc', - '!.vscodeignore', - '!LICENSE', - '!**/node_modules/**', - '!**/*.{svg,exe,png,bmp,scpt,bat,cmd,cur,ttf,woff,eot,txt,md,json,yml,pyc}', - '!out/**/*', - '!images/**/*', - '!.vscode/**/*', - '!pythonFiles/**/*', - '!resources/**/*', - '!snippets/**/*', - '!syntaxes/**/*', - '!**/typings/**/*', + 'src/**/*', + 'src/client/**/*', ]; const indentationFilter = [ - 'src/**/*.ts', - '!**/typings/**/*', + 'src/**/*.ts', + '!**/typings/**/*', ]; const tslintFilter = [ - 'src/**/*.ts', - 'test/**/*.ts', - '!**/node_modules/**', - '!out/**/*', - '!images/**/*', - '!.vscode/**/*', - '!pythonFiles/**/*', - '!resources/**/*', - '!snippets/**/*', - '!syntaxes/**/*', - '!**/typings/**/*', + 'src/**/*.ts', + 'test/**/*.ts', + '!**/node_modules/**', + '!out/**/*', + '!images/**/*', + '!.vscode/**/*', + '!pythonFiles/**/*', + '!resources/**/*', + '!snippets/**/*', + '!syntaxes/**/*', + '!**/typings/**/*', ]; -function reportFailures(failures) { - failures.forEach(failure => { - const name = failure.name || failure.fileName; - const position = failure.startPosition; - const line = position.lineAndCharacter ? position.lineAndCharacter.line : position.line; - const character = position.lineAndCharacter ? position.lineAndCharacter.character : position.character; - - // Output in format similar to tslint for the linter to pickup. - console.error(`ERROR: (${failure.ruleName}) ${relative(__dirname, name)}[${line + 1}, ${character + 1}]: ${failure.failure}`); - }); -} +gulp.task('hygiene', () => run({ mode: 'all', skipFormatCheck: true, skipIndentationCheck: true })); +gulp.task('compile', () => run({ mode: 'compile', skipFormatCheck: true, skipIndentationCheck: true, skipLinter: true })); -/** - * @typedef {Object} hygieneOptions - creates a new type named 'SpecialType' - * @property {boolean=} skipEOL - skipEOL check. - * @property {boolean=} skipIndentationCheck - Skip indentation checks. - * @property {boolean=} skipFormatCheck - Skip format checks. - */ +gulp.task('watch', ['hygiene-modified', 'hygiene-watch']); -/** - * - * @param {string[]} some - * @param {hygieneOptions} options - * @returns {NodeJS.EventEmitter} - */ -const hygiene = (some, options) => { - options = options || {}; - let errorCount = 0; - const eol = es.through(function (file) { - if (/\r\n?/g.test(file.contents.toString('utf8'))) { - console.error(file.relative + ': Bad EOL found'); - errorCount++; - } - - this.emit('data', file); - }); - - const indentation = es.through(function (file) { - file.contents - .toString('utf8') - .split(/\r\n|\r|\n/) - .forEach((line, i) => { - if (/^\s*$/.test(line) || /^\S+.*$/.test(line)) { - // Empty or whitespace lines are OK. - } else if (/^(\s\s\s\s)+.*/.test(line)) { - // Good indent. - } else if (/^[\t]+.*/.test(line)) { - console.error(file.relative + '(' + (i + 1) + ',1): Bad whitespace indentation (use 4 spaces instead of tabs or other)'); - errorCount++; - } - }); - - this.emit('data', file); - }); - - const formatting = es.map(function (file, cb) { - tsfmt.processString(file.path, file.contents.toString('utf8'), { - verify: true, - tsconfig: true, - tslint: true, - editorconfig: true, - tsfmt: true - }).then(result => { - if (result.error) { - console.error(result.message.trim()); - errorCount++; - } - cb(null, file); - - }, err => { - cb(err); - }); - }); - - const program = require('tslint').Linter.createProgram("./tsconfig.json"); - const linter = new tslint.Linter(options, program); - const tsl = es.through(function (file) { - const configuration = tslint.Configuration.findConfiguration(null, '.'); - const options = { - formatter: 'json' - }; - const contents = file.contents.toString('utf8'); - linter.lint(file.relative, contents, configuration.results); - const result = linter.getResult(); - if (result.failureCount > 0 || result.errorCount > 0) { - reportFailures(result.failures); - if (result.failureCount) { - errorCount += result.failureCount; - } - if (result.errorCount) { - errorCount += result.errorCount; - } - } - - this.emit('data', file); - }); - - const tsFiles = []; - const tscFilesTracker = es.through(function (file) { - tsFiles.push(file.path.replace(/\\/g, '/')); - tsFiles.push(file.path); - this.emit('data', file); - }); - - const tsc = function () { - function customReporter() { - return { - error: function (error) { - const fullFilename = error.fullFilename || ''; - const relativeFilename = error.relativeFilename || ''; - if (tsFiles.findIndex(file => fullFilename === file || relativeFilename === file) === -1) { - return; - } - errorCount += 1; - console.error(error.message); - }, - finish: function () { - // forget the summary. - } - }; - } - const tsProject = ts.createProject('tsconfig.json', { strict: true, noImplicitAny: false, noImplicitThis: false }); - const reporter = customReporter(); - return tsProject(reporter); - } - - // Misc file checks. - let result = gulp.src(some || all, { - base: '.' - }) - .pipe(filter(f => !f.stat.isDirectory())) - .pipe(filter(eolFilter)) - .pipe(options.skipEOL ? es.through() : eol) - .pipe(filter(indentationFilter)) - .pipe(indentation); - - // Type script checks. - let typescript = result - .pipe(filter(tslintFilter)) - .pipe(formatting); - - typescript = typescript - .pipe(tsl) - .pipe(tscFilesTracker) - .pipe(tsc()); - - return typescript - .pipe(es.through(null, function () { - if (errorCount > 0) { - this.emit('error', 'Hygiene failed with ' + errorCount + ' errors 👎. Check \'gulpfile.js\'.'); - } else { - this.emit('end'); - } - })); -}; +gulp.task('hygiene-watch', () => gulp.watch(all, debounce(() => run({ mode: 'changes' }), 1000))); -exports.hygiene = hygiene; +gulp.task('hygiene-modified', ['compile'], () => run({ mode: 'changes' })); -gulp.task('hygiene', () => run({ mode: 'all', skipFormatCheck: true, skipIndentationCheck: true })); +function reportFailures(failures) { + failures.forEach(failure => { + const name = failure.name || failure.fileName; + const position = failure.startPosition; + const line = position.lineAndCharacter ? position.lineAndCharacter.line : position.line; + const character = position.lineAndCharacter ? position.lineAndCharacter.character : position.character; + + // Output in format similar to tslint for the linter to pickup. + console.error(`ERROR: (${failure.ruleName}) ${relative(__dirname, name)}[${line + 1}, ${character + 1}]: ${failure.failure}`); + }); +} -gulp.task('hygiene-staged', () => run({ mode: 'changes' })); - -gulp.task('hygiene-watch', ['hygiene-staged', 'hygiene-watch-runner']); - -gulp.task('hygiene-watch-runner', function () { - /** - * @type {Deferred} - */ - let runPromise; - - return watch(all, { events: ['add', 'change'] }, function (event) { - // Damn bounce does not work, do our own checks. - const start = new Date(); - if (runPromise && !runPromise.completed) { - console.log(`[${start.toLocaleTimeString()}] Already running`); - return; - } - console.log(`[${start.toLocaleTimeString()}] Starting '${colors.cyan('hygiene-watch-runner')}'...`); - - runPromise = new Deferred(); - // Skip indentation and formatting checks to speed up linting. - run({ mode: 'watch', skipFormatCheck: true, skipIndentationCheck: true }) - .then(() => { - const end = new Date(); - const time = (end.getTime() - start.getTime()) / 1000; - console.log(`[${end.toLocaleTimeString()}] Finished '${colors.cyan('hygiene-watch-runner')}' after ${time} seconds`); - runPromise.resolve(); - }) - .catch(runPromise.reject.bind); - - return runPromise.promise; - }); -}); +/** +* @typedef {Object} hygieneOptions - creates a new type named 'SpecialType' +* @property {'changes'|'staged'|'all'|'compile'} [mode=] - Mode. +* @property {boolean=} skipIndentationCheck - Skip indentation checks. +* @property {boolean=} skipFormatCheck - Skip format checks. +* @property {boolean=} skipLinter - Skip linter. +*/ /** - * @typedef {Object} runOptions - * @property {boolean=} exitOnError - Exit on error. - * @property {'watch'|'changes'|'staged'|'all'} [mode=] - Mode. - * @property {string[]=} files - Optional list of files to be modified. - * @property {boolean=} skipIndentationCheck - Skip indentation checks. - * @property {boolean=} skipFormatCheck - Skip format checks. + * + * @param {hygieneOptions} options + * @returns {NodeJS.ReadWriteStream} */ +const hygiene = (options) => { + options = options || {}; + let errorCount = 0; + + const indentation = es.through(function (file) { + file.contents + .toString('utf8') + .split(/\r\n|\r|\n/) + .forEach((line, i) => { + if (/^\s*$/.test(line) || /^\S+.*$/.test(line)) { + // Empty or whitespace lines are OK. + } else if (/^(\s\s\s\s)+.*/.test(line)) { + // Good indent. + } else if (/^[\t]+.*/.test(line)) { + console.error(file.relative + '(' + (i + 1) + ',1): Bad whitespace indentation (use 4 spaces instead of tabs or other)'); + errorCount++; + } + }); + + this.emit('data', file); + }); + + const formatOptions = { verify: true, tsconfig: true, tslint: true, editorconfig: true, tsfmt: true }; + const formatting = es.map(function (file, cb) { + tsfmt.processString(file.path, file.contents.toString('utf8'), formatOptions) + .then(result => { + if (result.error) { + let message = result.message.trim(); + let formattedMessage = ''; + if (message.startsWith(__dirname)) { + message = message.substr(__dirname.length); + message = message.startsWith(path.sep) ? message.substr(1) : message; + const index = message.indexOf('.ts '); + if (index === -1) { + formattedMessage = colors.red(message); + } else { + const file = message.substr(0, index + 3); + const errorMessage = message.substr(index + 4).trim(); + formattedMessage = `${colors.red(file)} ${errorMessage}`; + } + } else { + formattedMessage = colors.red(message); + } + console.error(formattedMessage); + errorCount++; + } + cb(null, file); + }) + .catch(cb); + }); + + const configuration = tslint.Configuration.findConfiguration(null, '.'); + const program = tslint.Linter.createProgram('./tsconfig.json'); + const linter = new tslint.Linter({ formatter: 'json' }, program); + const tsl = es.through(function (file) { + const contents = file.contents.toString('utf8'); + // Don't print anything to the console, we'll do that. + // Yes this is a hack, but tslinter doesn't provide an option to prevent this. + const oldWarn = console.warn; + console.warn = () => { }; + linter.lint(file.relative, contents, configuration.results); + console.warn = oldWarn; + const result = linter.getResult(); + if (result.failureCount > 0 || result.errorCount > 0) { + reportFailures(result.failures); + if (result.failureCount) { + errorCount += result.failureCount; + } + if (result.errorCount) { + errorCount += result.errorCount; + } + } + this.emit('data', file); + }); + + const tsFiles = []; + const tscFilesTracker = es.through(function (file) { + tsFiles.push(file.path.replace(/\\/g, '/')); + tsFiles.push(file.path); + this.emit('data', file); + }); + + const tsOptions = options.mode === 'compile' ? undefined : { strict: true, noImplicitAny: false, noImplicitThis: false }; + const tsProject = ts.createProject('tsconfig.json', tsOptions); + + const tsc = function () { + function customReporter() { + return { + error: function (error) { + const fullFilename = error.fullFilename || ''; + const relativeFilename = error.relativeFilename || ''; + if (tsFiles.findIndex(file => fullFilename === file || relativeFilename === file) === -1) { + return; + } + errorCount += 1; + console.error(error.message); + }, + finish: function () { + // forget the summary. + } + }; + } + const reporter = customReporter(); + return tsProject(reporter); + } + + const files = options.mode === 'compile' ? tsProject.src() : getFilesToProcess(options); + const dest = options.mode === 'compile' ? './out' : '.'; + let result = files + .pipe(filter(f => !f.stat.isDirectory())); + + if (!options.skipIndentationCheck) { + result = result.pipe(filter(indentationFilter)) + .pipe(indentation); + } + + result = result + .pipe(filter(tslintFilter)); + + if (!options.skipFormatCheck) { + result = result + .pipe(formatting); + } + + if (!options.skipLinter) { + result = result + .pipe(tsl); + } + + result = result + .pipe(tscFilesTracker) + .pipe(tsc()) + .js.pipe(gulp.dest(dest)) + .pipe(es.through(null, function () { + if (errorCount > 0) { + const errorMessage = `Hygiene failed with ${colors.yellow(errorCount)} errors 👎 . Check 'gulpfile.js'.`; + console.error(colors.red(errorMessage)); + exitHandler(options); + } else { + console.log(colors.green('Hygiene passed with 0 errors 👍.')); + } + // Reset error counter. + errorCount = 0; + this.emit('end'); + })) + .on('error', exitHandler.bind(this, options)); +}; /** - * Run the linters. - * @param {runOptions} options - * @param {Error} ex - */ +* @typedef {Object} runOptions +* @property {boolean=} exitOnError - Exit on error. +* @property {'changes'|'staged'|'all'} [mode=] - Mode. +* @property {string[]=} files - Optional list of files to be modified. +* @property {boolean=} skipIndentationCheck - Skip indentation checks. +* @property {boolean=} skipFormatCheck - Skip format checks. +* @property {boolean=} skipLinter - Skip linter. + * @property {boolean=} watch - Watch mode. +*/ + +/** +* Run the linters. +* @param {runOptions} options +* @param {Error} ex +*/ function exitHandler(options, ex) { - console.error(); - if (ex) { - console.error(ex); - console.error(colors.red(ex)); - } - if (options.exitOnError) { - process.exit(1); - } - if (options.mode === 'watch') { - console.log('Watching for changes...'); - } + console.error(); + if (ex) { + console.error(ex); + console.error(colors.red(ex)); + } + if (options.exitOnError) { + console.log('exit'); + process.exit(1); + } } /** - * Run the linters. - * @param {runOptions} options - * @return {Promise} - */ +* Run the linters. +* @param {runOptions} options +*/ function run(options) { - options = options ? options : {}; - process.once('unhandledRejection', (reason, p) => { - console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); - exitHandler(options); - }); - - return getGitSkipEOL() - .then(skipEOL => { - if (typeof options.mode !== 'string' && process.argv.length > 2) { - return new Promise((resolve, reject) => { - return hygiene(process.argv.slice(2), { - skipEOL: skipEOL - }) - .once('error', reject) - .once('end', resolve); - }); - } - - return getFilesToProcess(options) - .then(files => { - return new Promise((resolve, reject) => { - hygiene(files, { - skipEOL: skipEOL, - skipFormatCheck: options.skipFormatCheck, - skipIndentationCheck: options.skipIndentationCheck - }) - .once('end', () => { - if (options.mode === 'watch') { - console.log(colors.green('Hygiene passed with 0 errors 👍.')); - console.log('Watching for changes...'); - } - resolve(); - }) - .once('error', reject); - }); - }); - }) - .catch(exitHandler.bind(options)); + options = options ? options : {}; + process.once('unhandledRejection', (reason, p) => { + console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); + exitHandler(options); + }); + + return hygiene(options); } -function getGitSkipEOL() { - return new Promise(resolve => { - cp.exec('git config core.autocrlf', (err, out) => { - const skipEOL = out.trim() === 'true'; - resolve(skipEOL); - }); - }); +function getStagedFilesSync() { + const out = cp.execSync('git diff --cached --name-only', { encoding: 'utf8' }); + const some = out + .split(/\r?\n/) + .filter(l => !!l); + return some; } + /** - * Gets a list of files to be processed. - * @param {runOptions} options - * @return {Promise} - */ +* @param {hygieneOptions} options +*/ function getFilesToProcess(options) { - switch (options.mode) { - case 'all': { - return Promise.resolve(all); - } - case 'watch': - case 'changes': { - return Promise.all([getCachedFiles(), getModifiedFiles()]) - .then(filesList => mergeFiles(filesList[0], filesList[1])); - } - default: { - return getCachedFiles(); - } - } -} -/** - * Merges a list of files. - * @param {string[]} files1 - * @param {string[]} files2 - */ -function mergeFiles(files1, files2) { - const files = files2.slice(); - files.forEach(file => { - if (files.indexOf(file) === -1) { - files.push(file); - } - }); - return files; -} -function getCachedFiles() { - return new Promise(resolve => { - cp.exec('git diff --cached --name-only', { - maxBuffer: 2000 * 1024 - }, (err, out) => { - if (err) { - return reject(err); - } - const some = out - .split(/\r?\n/) - .filter(l => !!l); - resolve(some); - }); - }); -} -function getModifiedFiles() { - return new Promise(resolve => { - cp.exec('git diff --name-only', { - maxBuffer: 2000 * 1024 - }, (err, out) => { - if (err) { - return reject(err); - } - const some = out - .split(/\r?\n/) - .filter(l => !!l); - resolve(some); - }); - }); + const mode = options ? options.mode : 'all'; + const gulpSrcOptions = { base: '.' }; + + // If we need only modified files, then filter the glob. + if (options && options.mode === 'changes') { + return gulp.src(all, gulpSrcOptions) + .pipe(gitmodified('M', 'A', 'D', 'R', 'C', 'U', '??')); + } + + if (options && options.mode === 'staged') { + return gulp.src(getStagedFilesSync(), gulpSrcOptions); + } + + return gulp.src(all, gulpSrcOptions); } +exports.hygiene = hygiene; + // this allows us to run hygiene as a git pre-commit hook. if (require.main === module) { - run({ exitOnError: true, mode: 'staged' }); -} - -class Deferred { - constructor(scope) { - this.scope = scope; - this._resolved = false; - this._rejected = false; - - this._promise = new Promise((resolve, reject) => { - this._resolve = resolve; - this._reject = reject; - }); - } - resolve(value) { - this._resolve.apply(this.scope ? this.scope : this, arguments); - this._resolved = true; - } - /** - * Rejects the promise - * @param {any} reason - * @memberof Deferred - */ - reject(reason) { - this._reject.apply(this.scope ? this.scope : this, arguments); - this._rejected = true; - } - get promise() { - return this._promise; - } - get resolved() { - return this._resolved === true; - } - get rejected() { - return this._rejected === true; - } - get completed() { - return this._rejected || this._resolved; - } + run({ exitOnError: true, mode: 'staged' }); } diff --git a/package-lock.json b/package-lock.json index 10e608b1634d..a2b337eed25e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5955 +1,6675 @@ { - "name": "python", - "version": "0.8.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/chai": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.0.6.tgz", - "integrity": "sha512-IzRWv/7IpaMm41KLLJcaaD/UKit/MrHu4rWs61oWiVjuk4aKWe2eopx3XyhAHhSnMyB5EeCMRr2AsJtuQ8COWA==", - "dev": true - }, - "@types/chai-as-promised": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.0.tgz", - "integrity": "sha512-MFiW54UOSt+f2bRw8J7LgQeIvE/9b4oGvwU7XW30S9QGAiHGnU/fmiOprsyMkdmH2rl8xSPc0/yrQw8juXU6bQ==", - "dev": true, - "requires": { - "@types/chai": "4.0.6" - } - }, - "@types/commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@types/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-G4+ewSX5/TPqpUjltkuyJ4QhX8oTy94WEyJMvC+R8cg/qKGjq+/n+b/TRVe/+/278jV9Iot5dS186r7NCcUrtg==", - "dev": true, - "requires": { - "@types/node": "6.0.92" - } - }, - "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", - "dev": true, - "requires": { - "@types/node": "6.0.92" - } - }, - "@types/get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@types/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha512-TiNg8R1kjDde5Pub9F9vCwZA/BNW9HeXP5b9j7Qucqncy/McfPZ6xze/EyBdXS5FhMIGN6Fx3vg75l5KHy3V1Q==", - "dev": true - }, - "@types/iconv-lite": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@types/iconv-lite/-/iconv-lite-0.0.1.tgz", - "integrity": "sha1-qjuL2ivlErGuCgV7lC6GnDcKVWk=", - "dev": true, - "requires": { - "@types/node": "6.0.92" - } - }, - "@types/lodash": { - "version": "4.14.86", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.86.tgz", - "integrity": "sha512-DIiC7xZkI+iqwb6A28+JDfrioxcFRHAUXl+AEZ9lULQppiArWRfex4ugVUAJKZHxcgqZJ1w2de2DTahVyrEp4Q==", - "dev": true - }, - "@types/mocha": { - "version": "2.2.44", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.44.tgz", - "integrity": "sha512-k2tWTQU8G4+iSMvqKi0Q9IIsWAp/n8xzdZS4Q4YVIltApoMA00wFBFdlJnmoaK1/z7B0Cy0yPe6GgXteSmdUNw==", - "dev": true - }, - "@types/node": { - "version": "6.0.92", - "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.92.tgz", - "integrity": "sha512-awEYSSTn7dauwVCYSx2CJaPTu0Z1Ht2oR1b2AD3CYao6ZRb+opb6EL43fzmD7eMFgMHzTBWSUzlWSD+S8xN0Nw==", - "dev": true - }, - "@types/semver": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.4.0.tgz", - "integrity": "sha512-PBHCvO98hNec9A491vBbh0ZNDOVxccwKL1u2pm6fs9oDgm7SEnw0lEHqHfjsYryDxnE3zaf7LvERWEXjOp1hig==", - "dev": true - }, - "@types/sinon": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-2.3.7.tgz", - "integrity": "sha512-w+LjztaZbgZWgt/y/VMP5BUAWLtSyoIJhXyW279hehLPyubDoBNwvhcj3WaSptcekuKYeTCVxrq60rdLc6ImJA==", - "dev": true - }, - "@types/uuid": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.3.tgz", - "integrity": "sha512-5fRLCYhLtDb3hMWqQyH10qtF+Ud2JnNCXTCZ+9ktNdCcgslcuXkDTkFcJNk++MT29yDntDnlF1+jD+uVGumsbw==", - "dev": true, - "requires": { - "@types/node": "6.0.92" - } - }, - "@types/winreg": { - "version": "1.2.30", - "resolved": "https://registry.npmjs.org/@types/winreg/-/winreg-1.2.30.tgz", - "integrity": "sha1-kdZxDlNtNFucmwF8V0z2qNpkxRg=", - "dev": true - }, - "@types/xml2js": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.2.tgz", - "integrity": "sha512-8aKUBSj3oGcnuiBmDLm3BIk09RYg01mz9HlQ2u4aS17oJ25DxjQrEUVGFSBVNOfM45pQW4OjcBPplq6r/exJdA==", - "dev": true, - "requires": { - "@types/node": "6.0.92" - } - }, - "ajv": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.0.tgz", - "integrity": "sha1-6yhAdG6dxIvV4GOjbj/UAMXqtak=", - "dev": true, - "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.0.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "2.3.11", - "normalize-path": "2.1.1" - } - }, - "applicationinsights": { - "version": "0.15.6", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-0.15.6.tgz", - "integrity": "sha1-IBoGgsBwT+S92aktCyy+NNKuWXI=" - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "1.1.0" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "array-differ": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", - "dev": true - }, - "array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", - "dev": true - }, - "array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "1.0.3" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", - "dev": true - }, - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", - "dev": true - }, - "assertion-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", - "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", - "dev": true - }, - "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", - "dev": true - }, - "aws4": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", - "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", - "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", - "dev": true, - "optional": true, - "requires": { - "tweetnacl": "0.14.5" - } - }, - "beeper": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", - "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", - "dev": true - }, - "binary-extensions": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", - "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", - "dev": true - }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "dev": true, - "requires": { - "inherits": "2.0.3" - } - }, - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" - } - }, - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "caseless": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", - "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", - "dev": true - }, - "chai": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", - "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", - "dev": true, - "requires": { - "assertion-error": "1.0.2", - "check-error": "1.0.2", - "deep-eql": "3.0.1", - "get-func-name": "2.0.0", - "pathval": "1.1.0", - "type-detect": "4.0.5" - } - }, - "chai-as-promised": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", - "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", - "dev": true, - "requires": { - "check-error": "1.0.2" - } - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "1.3.2", - "async-each": "1.0.1", - "fsevents": "1.1.3", - "glob-parent": "2.0.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "2.0.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.1.0" - } - }, - "ci-info": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.2.tgz", - "integrity": "sha512-uTGIPNx/nSpBdsF6xnseRXLLtfr9VLqkz8ZqHXr3Y7b6SftyRxBGjwMtJj1OhNbmlc1wZzLNAlAcvyIiE8a6ZA==", - "dev": true - }, - "clone": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz", - "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=", - "dev": true - }, - "clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", - "dev": true - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", - "dev": true - }, - "cloneable-readable": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.0.0.tgz", - "integrity": "sha1-pikNQT8hemEjL5XkWP84QYz7ARc=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "process-nextick-args": "1.0.7", - "through2": "2.0.3" - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "color-convert": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", - "dev": true - }, - "combined-stream": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", - "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", - "dev": true, - "requires": { - "delayed-stream": "1.0.0" - } - }, - "commander": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", - "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=", - "dev": true - }, - "commandpost": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/commandpost/-/commandpost-1.2.1.tgz", - "integrity": "sha512-V1wzc+DTFsO96te2W/U+fKNRSOWtOwXhkkZH2WRLLbucrY+YrDNsRr4vtfSf83MUZVF3E6B4nwT30fqaTpzipQ==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "convert-source-map": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", - "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", - "dev": true, - "requires": { - "boom": "2.10.1" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "dateformat": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", - "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=", - "dev": true - }, - "debounce-hashed": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/debounce-hashed/-/debounce-hashed-0.1.2.tgz", - "integrity": "sha1-oN/jB8Gn2zD2kRyM+8DvhB831K8=", - "dev": true - }, - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "deep-assign": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/deep-assign/-/deep-assign-1.0.0.tgz", - "integrity": "sha1-sJJ0O+hCfcYh6gBnzex+cN0Z83s=", - "dev": true, - "requires": { - "is-obj": "1.0.1" - } - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "4.0.5" - } - }, - "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "dev": true, - "requires": { - "clone": "1.0.3" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "deprecated": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz", - "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=", - "dev": true - }, - "detect-file": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz", - "integrity": "sha1-STXe39lIhkjgBrASlWbpOGcR6mM=", - "dev": true, - "requires": { - "fs-exists-sync": "0.1.0" - } - }, - "diff": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", - "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", - "dev": true - }, - "diff-match-patch": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.0.tgz", - "integrity": "sha1-HMPIOkkNZ/ldkeOfatHy4Ia2MEg=" - }, - "doctrine": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz", - "integrity": "sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM=", - "dev": true, - "requires": { - "esutils": "1.1.6", - "isarray": "0.0.1" - }, - "dependencies": { - "esutils": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz", - "integrity": "sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U=", - "dev": true - } - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", - "dev": true - }, - "duplexer2": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", - "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", - "dev": true, - "requires": { - "readable-stream": "1.1.14" - } - }, - "duplexify": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.1.tgz", - "integrity": "sha512-j5goxHTwVED1Fpe5hh3q9R93Kip0Bg2KVAt4f8CEYM3UEwYcPSvWbXaUQOzdX/HtiNomipv+gU7ASQPDbV7pGQ==", - "dev": true, - "requires": { - "end-of-stream": "1.4.0", - "inherits": "2.0.3", - "readable-stream": "2.3.3", - "stream-shift": "1.0.0" - }, - "dependencies": { - "end-of-stream": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", - "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", - "dev": true, - "requires": { - "once": "1.4.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", - "dev": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "editorconfig": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.0.tgz", - "integrity": "sha512-j7JBoj/bpNzvoTQylfRZSc85MlLNKWQiq5y6gwKhmqD2h1eZ+tH4AXbkhEJD468gjDna/XMx2YtSkCxBRX9OGg==", - "dev": true, - "requires": { - "@types/commander": "2.11.0", - "@types/semver": "5.4.0", - "commander": "2.12.2", - "lru-cache": "4.1.1", - "semver": "5.4.1", - "sigmund": "1.0.1" - }, - "dependencies": { - "commander": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz", - "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==", - "dev": true - }, - "lru-cache": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", - "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", - "dev": true, - "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" - } - } - } - }, - "end-of-stream": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", - "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=", - "dev": true, - "requires": { - "once": "1.3.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "event-stream": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", - "dev": true, - "requires": { - "duplexer": "0.1.1", - "from": "0.1.7", - "map-stream": "0.1.0", - "pause-stream": "0.0.11", - "split": "0.3.3", - "stream-combiner": "0.0.4", - "through": "2.3.8" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "0.1.1" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "2.2.3" - } - }, - "expand-tilde": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", - "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", - "dev": true, - "requires": { - "os-homedir": "1.0.2" - } - }, - "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", - "dev": true - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fancy-log": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", - "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "time-stamp": "1.1.0" - } - }, - "fast-deep-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", - "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true - }, - "fd-slicer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", - "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", - "dev": true, - "requires": { - "pend": "1.2.0" - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", - "dev": true, - "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "1.1.7", - "repeat-element": "1.1.2", - "repeat-string": "1.6.1" - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "findup-sync": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.3.tgz", - "integrity": "sha1-QAQ5Kee8YK3wt/SCfExudaDeyhI=", - "dev": true, - "requires": { - "detect-file": "0.1.0", - "is-glob": "2.0.1", - "micromatch": "2.3.11", - "resolve-dir": "0.1.1" - } - }, - "fined": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.0.tgz", - "integrity": "sha1-s33IRLdqL15wgeiE98CuNE8VNHY=", - "dev": true, - "requires": { - "expand-tilde": "2.0.2", - "is-plain-object": "2.0.4", - "object.defaults": "1.1.0", - "object.pick": "1.3.0", - "parse-filepath": "1.0.1" - }, - "dependencies": { - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "1.0.1" - } - } - } - }, - "first-chunk-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", - "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=", - "dev": true - }, - "flagged-respawn": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.2.tgz", - "integrity": "sha1-/xke3c1wiKZ1smEP/8l2vpuAdLU=", - "dev": true - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "1.0.2" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", - "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", - "dev": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" - } - }, - "formatio": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", - "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", - "dev": true, - "requires": { - "samsam": "1.3.0" - } - }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", - "dev": true - }, - "fs-exists-sync": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", - "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=", - "dev": true - }, - "fs-extra": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.2.tgz", - "integrity": "sha1-+RcExT0bRh+JNFKwwwfZmXZHq2s=", - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "4.0.0", - "universalify": "0.1.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz", - "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", - "dev": true, - "optional": true, - "requires": { - "nan": "2.8.0", - "node-pre-gyp": "0.6.39" - }, - "dependencies": { - "abbrev": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "ajv": { - "version": "4.11.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" - } - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "aproba": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "1.0.0", - "readable-stream": "2.2.9" - } - }, - "asn1": { - "version": "0.2.3", - "bundled": true, - "dev": true, - "optional": true - }, - "assert-plus": { - "version": "0.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "asynckit": { - "version": "0.4.0", - "bundled": true, - "dev": true, - "optional": true - }, - "aws-sign2": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "aws4": { - "version": "1.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "balanced-match": { - "version": "0.4.2", - "bundled": true, - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "tweetnacl": "0.14.5" - } - }, - "block-stream": { - "version": "0.0.9", - "bundled": true, - "dev": true, - "requires": { - "inherits": "2.0.3" - } - }, - "boom": { - "version": "2.10.1", - "bundled": true, - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "brace-expansion": { - "version": "1.1.7", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "0.4.2", - "concat-map": "0.0.1" - } - }, - "buffer-shims": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "caseless": { - "version": "0.12.0", - "bundled": true, - "dev": true, - "optional": true - }, - "co": { - "version": "4.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "combined-stream": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "requires": { - "delayed-stream": "1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "cryptiles": { - "version": "2.0.5", - "bundled": true, - "dev": true, - "requires": { - "boom": "2.10.1" - } - }, - "dashdash": { - "version": "1.14.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "debug": { - "version": "2.6.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.4.2", - "bundled": true, - "dev": true, - "optional": true - }, - "delayed-stream": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "ecc-jsbn": { - "version": "0.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "extend": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "extsprintf": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "bundled": true, - "dev": true, - "optional": true - }, - "form-data": { - "version": "2.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.15" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "fstream": { - "version": "1.0.11", - "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.1" - } - }, - "fstream-ignore": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fstream": "1.0.11", - "inherits": "2.0.3", - "minimatch": "3.0.4" - } - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "1.1.1", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" - } - }, - "getpass": { - "version": "0.1.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "graceful-fs": { - "version": "4.1.11", - "bundled": true, - "dev": true - }, - "har-schema": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "optional": true - }, - "har-validator": { - "version": "4.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "hawk": { - "version": "3.1.3", - "bundled": true, - "dev": true, - "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" - } - }, - "hoek": { - "version": "2.16.3", - "bundled": true, - "dev": true - }, - "http-signature": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.0", - "sshpk": "1.13.0" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "ini": { - "version": "1.3.4", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "isstream": { - "version": "0.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "jodid25519": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "jsbn": { - "version": "0.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "json-schema": { - "version": "0.2.3", - "bundled": true, - "dev": true, - "optional": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "jsonify": "0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "jsonify": { - "version": "0.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "jsprim": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.0.2", - "json-schema": "0.2.3", - "verror": "1.3.6" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "mime-db": { - "version": "1.27.0", - "bundled": true, - "dev": true - }, - "mime-types": { - "version": "2.1.15", - "bundled": true, - "dev": true, - "requires": { - "mime-db": "1.27.0" - } - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "node-pre-gyp": { - "version": "0.6.39", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "1.0.2", - "hawk": "3.1.3", - "mkdirp": "0.5.1", - "nopt": "4.0.1", - "npmlog": "4.1.0", - "rc": "1.2.1", - "request": "2.81.0", - "rimraf": "2.6.1", - "semver": "5.3.0", - "tar": "2.2.1", - "tar-pack": "3.4.0" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1.1.0", - "osenv": "0.1.4" - } - }, - "npmlog": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "oauth-sign": { - "version": "0.8.2", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "performance-now": { - "version": "0.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "1.0.7", - "bundled": true, - "dev": true - }, - "punycode": { - "version": "1.4.1", - "bundled": true, - "dev": true, - "optional": true - }, - "qs": { - "version": "6.4.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.2.9", - "bundled": true, - "dev": true, - "requires": { - "buffer-shims": "1.0.0", - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "1.0.1", - "util-deprecate": "1.0.2" - } - }, - "request": { - "version": "2.81.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.15", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.0.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.2", - "tunnel-agent": "0.6.0", - "uuid": "3.0.1" - } - }, - "rimraf": { - "version": "2.6.1", - "bundled": true, - "dev": true, - "requires": { - "glob": "7.1.2" - } - }, - "safe-buffer": { - "version": "5.0.1", - "bundled": true, - "dev": true - }, - "semver": { - "version": "5.3.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sntp": { - "version": "1.0.9", - "bundled": true, - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "sshpk": { - "version": "1.13.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jodid25519": "1.0.2", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "string_decoder": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "5.0.1" - } - }, - "stringstream": { - "version": "0.0.5", - "bundled": true, - "dev": true, - "optional": true - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "2.2.1", - "bundled": true, - "dev": true, - "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" - } - }, - "tar-pack": { - "version": "3.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "2.6.8", - "fstream": "1.0.11", - "fstream-ignore": "1.0.5", - "once": "1.4.0", - "readable-stream": "2.2.9", - "rimraf": "2.6.1", - "tar": "2.2.1", - "uid-number": "0.0.6" - } - }, - "tough-cookie": { - "version": "2.3.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "punycode": "1.4.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "bundled": true, - "dev": true, - "optional": true - }, - "uid-number": { - "version": "0.0.6", - "bundled": true, - "dev": true, - "optional": true - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "uuid": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "verror": { - "version": "1.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "extsprintf": "1.0.2" - } - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - } - } - }, - "fstream": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", - "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.2" - } - }, - "fuzzy": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/fuzzy/-/fuzzy-0.1.3.tgz", - "integrity": "sha1-THbsL/CsGjap3M+aAN+GIweNTtg=" - }, - "gaze": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", - "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=", - "dev": true, - "requires": { - "globule": "0.1.0" - } - }, - "generate-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", - "dev": true - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true, - "requires": { - "is-property": "1.0.2" - } - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=" - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "glob": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", - "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", - "dev": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "2.0.10", - "once": "1.3.3" - }, - "dependencies": { - "minimatch": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", - "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", - "dev": true, - "requires": { - "brace-expansion": "1.1.8" - } - } - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "2.0.0", - "is-glob": "2.0.1" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "2.0.1" - } - }, - "glob-stream": { - "version": "3.1.18", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", - "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", - "dev": true, - "requires": { - "glob": "4.5.3", - "glob2base": "0.0.12", - "minimatch": "2.0.10", - "ordered-read-streams": "0.1.0", - "through2": "0.6.5", - "unique-stream": "1.0.0" - }, - "dependencies": { - "minimatch": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", - "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", - "dev": true, - "requires": { - "brace-expansion": "1.1.8" - } - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - } - } - }, - "glob-watcher": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz", - "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=", - "dev": true, - "requires": { - "gaze": "0.5.2" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "0.1.1" - } - }, - "global-modules": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", - "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", - "dev": true, - "requires": { - "global-prefix": "0.1.5", - "is-windows": "0.2.0" - } - }, - "global-prefix": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", - "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", - "dev": true, - "requires": { - "homedir-polyfill": "1.0.1", - "ini": "1.3.5", - "is-windows": "0.2.0", - "which": "1.3.0" - } - }, - "globule": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", - "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", - "dev": true, - "requires": { - "glob": "3.1.21", - "lodash": "1.0.2", - "minimatch": "0.2.14" - }, - "dependencies": { - "glob": { - "version": "3.1.21", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", - "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", - "dev": true, - "requires": { - "graceful-fs": "1.2.3", - "inherits": "1.0.2", - "minimatch": "0.2.14" - } - }, - "graceful-fs": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", - "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=", - "dev": true - }, - "inherits": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", - "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=", - "dev": true - }, - "lodash": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", - "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=", - "dev": true - }, - "minimatch": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", - "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", - "dev": true, - "requires": { - "lru-cache": "2.7.3", - "sigmund": "1.0.1" - } - } - } - }, - "glogg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", - "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", - "dev": true, - "requires": { - "sparkles": "1.0.0" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" - }, - "growl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", - "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", - "dev": true - }, - "gulp": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz", - "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=", - "dev": true, - "requires": { - "archy": "1.0.0", - "chalk": "1.1.3", - "deprecated": "0.0.1", - "gulp-util": "3.0.8", - "interpret": "1.1.0", - "liftoff": "2.3.0", - "minimist": "1.2.0", - "orchestrator": "0.3.8", - "pretty-hrtime": "1.0.3", - "semver": "4.3.6", - "tildify": "1.2.0", - "v8flags": "2.1.1", - "vinyl-fs": "0.3.14" - }, - "dependencies": { - "semver": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", - "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", - "dev": true - } - } - }, - "gulp-chmod": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/gulp-chmod/-/gulp-chmod-2.0.0.tgz", - "integrity": "sha1-AMOQuSigeZslGsz2MaoJ4BzGKZw=", - "dev": true, - "requires": { - "deep-assign": "1.0.0", - "stat-mode": "0.2.2", - "through2": "2.0.3" - } - }, - "gulp-debounced-watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/gulp-debounced-watch/-/gulp-debounced-watch-1.0.4.tgz", - "integrity": "sha1-WkfU4kzkY2XOguysMqKjA+QysSo=", - "dev": true, - "requires": { - "debounce-hashed": "0.1.2", - "gulp-watch": "4.3.11", - "object-assign": "3.0.0" - } - }, - "gulp-filter": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/gulp-filter/-/gulp-filter-5.0.1.tgz", - "integrity": "sha512-5olRzAhFdXB2klCu1lnazP65aO9YdA/5WfC9VdInIc8PrUeDIoZfaA3Edb0yUBGhVdHv4eHKL9Fg5tUoEJ9z5A==", - "dev": true, - "requires": { - "gulp-util": "3.0.8", - "multimatch": "2.1.0", - "streamfilter": "1.0.5" - } - }, - "gulp-gunzip": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulp-gunzip/-/gulp-gunzip-1.0.0.tgz", - "integrity": "sha1-FbdBFF6Dqcb1CIYkG1fMWHHxUak=", - "dev": true, - "requires": { - "through2": "0.6.5", - "vinyl": "0.4.6" - }, - "dependencies": { - "clone": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", - "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - }, - "vinyl": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", - "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", - "dev": true, - "requires": { - "clone": "0.2.0", - "clone-stats": "0.0.1" - } - } - } - }, - "gulp-remote-src": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/gulp-remote-src/-/gulp-remote-src-0.4.3.tgz", - "integrity": "sha1-VyjP1kNDPdSEXd7wlp8PlxoqtKE=", - "dev": true, - "requires": { - "event-stream": "3.3.4", - "node.extend": "1.1.6", - "request": "2.79.0", - "through2": "2.0.3", - "vinyl": "2.0.2" - }, - "dependencies": { - "clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", - "dev": true - }, - "replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", - "dev": true - }, - "request": { - "version": "2.79.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz", - "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=", - "dev": true, - "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.11.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "2.0.6", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "oauth-sign": "0.8.2", - "qs": "6.3.2", - "stringstream": "0.0.5", - "tough-cookie": "2.3.3", - "tunnel-agent": "0.4.3", - "uuid": "3.1.0" - } - }, - "vinyl": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.0.2.tgz", - "integrity": "sha1-CjcT2NTpIhxY8QyhbAEWyeJe2nw=", - "dev": true, - "requires": { - "clone": "1.0.3", - "clone-buffer": "1.0.0", - "clone-stats": "1.0.0", - "cloneable-readable": "1.0.0", - "is-stream": "1.1.0", - "remove-trailing-separator": "1.1.0", - "replace-ext": "1.0.0" - } - } - } - }, - "gulp-sourcemaps": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz", - "integrity": "sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw=", - "dev": true, - "requires": { - "convert-source-map": "1.5.1", - "graceful-fs": "4.1.11", - "strip-bom": "2.0.0", - "through2": "2.0.3", - "vinyl": "1.2.0" - }, - "dependencies": { - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "0.2.1" - } - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.3", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - } - } - }, - "gulp-symdest": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/gulp-symdest/-/gulp-symdest-1.1.0.tgz", - "integrity": "sha1-wWUyBzLRks5W/ZQnH/oSMjS/KuA=", - "dev": true, - "requires": { - "event-stream": "3.3.4", - "mkdirp": "0.5.1", - "queue": "3.1.0", - "vinyl-fs": "2.4.4" - }, - "dependencies": { - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.3.3", - "path-is-absolute": "1.0.1" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" - } - }, - "glob-stream": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", - "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", - "dev": true, - "requires": { - "extend": "3.0.1", - "glob": "5.0.15", - "glob-parent": "3.1.0", - "micromatch": "2.3.11", - "ordered-read-streams": "0.3.0", - "through2": "0.6.5", - "to-absolute-glob": "0.1.1", - "unique-stream": "2.2.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - } - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "ordered-read-streams": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", - "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", - "dev": true, - "requires": { - "is-stream": "1.1.0", - "readable-stream": "2.3.3" - } - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "0.2.1" - } - }, - "strip-bom-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz", - "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=", - "dev": true, - "requires": { - "first-chunk-stream": "1.0.0", - "strip-bom": "2.0.0" - } - }, - "unique-stream": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", - "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", - "dev": true, - "requires": { - "json-stable-stringify": "1.0.1", - "through2-filter": "2.0.0" - } - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.3", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - }, - "vinyl-fs": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", - "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", - "dev": true, - "requires": { - "duplexify": "3.5.1", - "glob-stream": "5.3.5", - "graceful-fs": "4.1.11", - "gulp-sourcemaps": "1.6.0", - "is-valid-glob": "0.3.0", - "lazystream": "1.0.0", - "lodash.isequal": "4.5.0", - "merge-stream": "1.0.1", - "mkdirp": "0.5.1", - "object-assign": "4.1.1", - "readable-stream": "2.3.3", - "strip-bom": "2.0.0", - "strip-bom-stream": "1.0.0", - "through2": "2.0.3", - "through2-filter": "2.0.0", - "vali-date": "1.0.0", - "vinyl": "1.2.0" - } - } - } - }, - "gulp-typescript": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-3.2.3.tgz", - "integrity": "sha512-Np2sJXgtDUwIAoMtlJ9uXsVmpu1FWXlKZw164hLuo56uJa7qo5W2KZ0yAYiYH/HUsaz5L0O2toMOcLIokpFCPg==", - "dev": true, - "requires": { - "gulp-util": "3.0.8", - "source-map": "0.5.7", - "through2": "2.0.3", - "vinyl-fs": "2.4.4" - }, - "dependencies": { - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.3.3", - "path-is-absolute": "1.0.1" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" - } - }, - "glob-stream": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", - "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", - "dev": true, - "requires": { - "extend": "3.0.1", - "glob": "5.0.15", - "glob-parent": "3.1.0", - "micromatch": "2.3.11", - "ordered-read-streams": "0.3.0", - "through2": "0.6.5", - "to-absolute-glob": "0.1.1", - "unique-stream": "2.2.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - } - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "ordered-read-streams": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", - "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", - "dev": true, - "requires": { - "is-stream": "1.1.0", - "readable-stream": "2.3.3" - } - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "0.2.1" - } - }, - "strip-bom-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz", - "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=", - "dev": true, - "requires": { - "first-chunk-stream": "1.0.0", - "strip-bom": "2.0.0" - } - }, - "unique-stream": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", - "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", - "dev": true, - "requires": { - "json-stable-stringify": "1.0.1", - "through2-filter": "2.0.0" - } - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.3", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - }, - "vinyl-fs": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", - "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", - "dev": true, - "requires": { - "duplexify": "3.5.1", - "glob-stream": "5.3.5", - "graceful-fs": "4.1.11", - "gulp-sourcemaps": "1.6.0", - "is-valid-glob": "0.3.0", - "lazystream": "1.0.0", - "lodash.isequal": "4.5.0", - "merge-stream": "1.0.1", - "mkdirp": "0.5.1", - "object-assign": "4.1.1", - "readable-stream": "2.3.3", - "strip-bom": "2.0.0", - "strip-bom-stream": "1.0.0", - "through2": "2.0.3", - "through2-filter": "2.0.0", - "vali-date": "1.0.0", - "vinyl": "1.2.0" - } - } - } - }, - "gulp-untar": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/gulp-untar/-/gulp-untar-0.0.6.tgz", - "integrity": "sha1-1r3v3n6ajgVMnxYjhaB4LEvnQAA=", - "dev": true, - "requires": { - "event-stream": "3.3.4", - "gulp-util": "3.0.8", - "streamifier": "0.1.1", - "tar": "2.2.1", - "through2": "2.0.3" - } - }, - "gulp-util": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", - "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", - "dev": true, - "requires": { - "array-differ": "1.0.0", - "array-uniq": "1.0.3", - "beeper": "1.1.1", - "chalk": "1.1.3", - "dateformat": "2.2.0", - "fancy-log": "1.3.0", - "gulplog": "1.0.0", - "has-gulplog": "0.1.0", - "lodash._reescape": "3.0.0", - "lodash._reevaluate": "3.0.0", - "lodash._reinterpolate": "3.0.0", - "lodash.template": "3.6.2", - "minimist": "1.2.0", - "multipipe": "0.1.2", - "object-assign": "3.0.0", - "replace-ext": "0.0.1", - "through2": "2.0.3", - "vinyl": "0.5.3" - } - }, - "gulp-vinyl-zip": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/gulp-vinyl-zip/-/gulp-vinyl-zip-2.1.0.tgz", - "integrity": "sha1-JOQGhdwFtxSZlSRQmeBZAmO+ja0=", - "dev": true, - "requires": { - "event-stream": "3.3.4", - "queue": "4.4.2", - "through2": "2.0.3", - "vinyl": "2.1.0", - "vinyl-fs": "2.4.4", - "yauzl": "2.9.1", - "yazl": "2.4.3" - }, - "dependencies": { - "clone": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", - "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", - "dev": true - }, - "clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", - "dev": true - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.3.3", - "path-is-absolute": "1.0.1" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" - } - }, - "glob-stream": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", - "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", - "dev": true, - "requires": { - "extend": "3.0.1", - "glob": "5.0.15", - "glob-parent": "3.1.0", - "micromatch": "2.3.11", - "ordered-read-streams": "0.3.0", - "through2": "0.6.5", - "to-absolute-glob": "0.1.1", - "unique-stream": "2.2.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - } - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "ordered-read-streams": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", - "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", - "dev": true, - "requires": { - "is-stream": "1.1.0", - "readable-stream": "2.3.3" - } - }, - "queue": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/queue/-/queue-4.4.2.tgz", - "integrity": "sha512-fSMRXbwhMwipcDZ08enW2vl+YDmAmhcNcr43sCJL8DIg+CFOsoRLG23ctxA+fwNk1w55SePSiS7oqQQSgQoVJQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - } - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", - "dev": true - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "0.2.1" - } - }, - "strip-bom-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz", - "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=", - "dev": true, - "requires": { - "first-chunk-stream": "1.0.0", - "strip-bom": "2.0.0" - } - }, - "unique-stream": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", - "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", - "dev": true, - "requires": { - "json-stable-stringify": "1.0.1", - "through2-filter": "2.0.0" - } - }, - "vinyl": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz", - "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=", - "dev": true, - "requires": { - "clone": "2.1.1", - "clone-buffer": "1.0.0", - "clone-stats": "1.0.0", - "cloneable-readable": "1.0.0", - "remove-trailing-separator": "1.1.0", - "replace-ext": "1.0.0" - } - }, - "vinyl-fs": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", - "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", - "dev": true, - "requires": { - "duplexify": "3.5.1", - "glob-stream": "5.3.5", - "graceful-fs": "4.1.11", - "gulp-sourcemaps": "1.6.0", - "is-valid-glob": "0.3.0", - "lazystream": "1.0.0", - "lodash.isequal": "4.5.0", - "merge-stream": "1.0.1", - "mkdirp": "0.5.1", - "object-assign": "4.1.1", - "readable-stream": "2.3.3", - "strip-bom": "2.0.0", - "strip-bom-stream": "1.0.0", - "through2": "2.0.3", - "through2-filter": "2.0.0", - "vali-date": "1.0.0", - "vinyl": "1.2.0" - }, - "dependencies": { - "clone": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz", - "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=", - "dev": true - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", - "dev": true - }, - "replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", - "dev": true - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.3", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - } - } - } - } - }, - "gulp-watch": { - "version": "4.3.11", - "resolved": "https://registry.npmjs.org/gulp-watch/-/gulp-watch-4.3.11.tgz", - "integrity": "sha1-Fi/FY96fx3DpH5p845VVE6mhGMA=", - "dev": true, - "requires": { - "anymatch": "1.3.2", - "chokidar": "1.7.0", - "glob-parent": "3.1.0", - "gulp-util": "3.0.8", - "object-assign": "4.1.1", - "path-is-absolute": "1.0.1", - "readable-stream": "2.3.3", - "slash": "1.0.0", - "vinyl": "1.2.0", - "vinyl-file": "2.0.0" - }, - "dependencies": { - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.3", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - } - } - }, - "gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", - "dev": true, - "requires": { - "glogg": "1.0.0" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", - "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "commander": "2.12.2", - "is-my-json-valid": "2.16.1", - "pinkie-promise": "2.0.1" - }, - "dependencies": { - "commander": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz", - "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==", - "dev": true - } - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "has-gulplog": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", - "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", - "dev": true, - "requires": { - "sparkles": "1.0.0" - } - }, - "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", - "dev": true, - "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" - } - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", - "dev": true - }, - "homedir-polyfill": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", - "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", - "dev": true, - "requires": { - "parse-passwd": "1.0.0" - } - }, - "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", - "dev": true, - "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" - } - }, - "husky": { - "version": "0.14.3", - "resolved": "https://registry.npmjs.org/husky/-/husky-0.14.3.tgz", - "integrity": "sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA==", - "dev": true, - "requires": { - "is-ci": "1.0.10", - "normalize-path": "1.0.0", - "strip-indent": "2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz", - "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=", - "dev": true - } - } - }, - "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "1.3.3", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true - }, - "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", - "dev": true - }, - "inversify": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/inversify/-/inversify-4.5.2.tgz", - "integrity": "sha512-nyXPqxMVdJDCbeq+eWSq5wEYvm6jlBNkBS+rMAXdxlEibAIXuzXXNgvETsP0MVcsWc4bAwUMhqr6X/5sUzNrFw==" - }, - "is": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is/-/is-3.2.1.tgz", - "integrity": "sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU=", - "dev": true - }, - "is-absolute": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz", - "integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=", - "dev": true, - "requires": { - "is-relative": "0.2.1", - "is-windows": "0.2.0" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "1.11.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-ci": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", - "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", - "dev": true, - "requires": { - "ci-info": "1.1.2" - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - }, - "is-my-json-valid": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz", - "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==", - "dev": true, - "requires": { - "generate-function": "2.0.0", - "generate-object-property": "1.2.0", - "jsonpointer": "4.0.1", - "xtend": "4.0.1" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - } - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", - "dev": true - }, - "is-relative": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz", - "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=", - "dev": true, - "requires": { - "is-unc-path": "0.1.2" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-unc-path": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz", - "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=", - "dev": true, - "requires": { - "unc-path-regex": "0.1.2" - } - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "is-valid-glob": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-0.3.0.tgz", - "integrity": "sha1-1LVcafUYhvm2XHDWwmItN+KfSP4=", - "dev": true - }, - "is-windows": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", - "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "jade": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", - "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=", - "dev": true, - "requires": { - "commander": "0.6.1", - "mkdirp": "0.3.0" - }, - "dependencies": { - "commander": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", - "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=", - "dev": true - }, - "mkdirp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", - "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=", - "dev": true - } - } - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, - "optional": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, - "requires": { - "jsonify": "0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "4.1.11" - } - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "jsonpointer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "liftoff": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.3.0.tgz", - "integrity": "sha1-qY8v9nGD2Lp8+soQVIvX/wVQs4U=", - "dev": true, - "requires": { - "extend": "3.0.1", - "findup-sync": "0.4.3", - "fined": "1.1.0", - "flagged-respawn": "0.3.2", - "lodash.isplainobject": "4.0.6", - "lodash.isstring": "4.0.1", - "lodash.mapvalues": "4.6.0", - "rechoir": "0.6.2", - "resolve": "1.5.0" - } - }, - "line-by-line": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/line-by-line/-/line-by-line-0.1.5.tgz", - "integrity": "sha1-GcRbWfCoBjLDC1xDpkf+Faq5BcI=" - }, - "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" - }, - "lodash._basecopy": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", - "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", - "dev": true - }, - "lodash._basetostring": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", - "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", - "dev": true - }, - "lodash._basevalues": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", - "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", - "dev": true - }, - "lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", - "dev": true - }, - "lodash._isiterateecall": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", - "dev": true - }, - "lodash._reescape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", - "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", - "dev": true - }, - "lodash._reevaluate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", - "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", - "dev": true - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, - "lodash._root": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", - "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", - "dev": true - }, - "lodash.escape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", - "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", - "dev": true, - "requires": { - "lodash._root": "3.0.1" - } - }, - "lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", - "dev": true - }, - "lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", - "dev": true - }, - "lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", - "dev": true - }, - "lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "dev": true, - "requires": { - "lodash._getnative": "3.9.1", - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4" - } - }, - "lodash.mapvalues": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", - "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=", - "dev": true - }, - "lodash.restparam": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", - "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", - "dev": true - }, - "lodash.template": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", - "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", - "dev": true, - "requires": { - "lodash._basecopy": "3.0.1", - "lodash._basetostring": "3.0.1", - "lodash._basevalues": "3.0.0", - "lodash._isiterateecall": "3.0.9", - "lodash._reinterpolate": "3.0.0", - "lodash.escape": "3.2.0", - "lodash.keys": "3.1.2", - "lodash.restparam": "3.6.1", - "lodash.templatesettings": "3.1.1" - } - }, - "lodash.templatesettings": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", - "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", - "dev": true, - "requires": { - "lodash._reinterpolate": "3.0.0", - "lodash.escape": "3.2.0" - } - }, - "lolex": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz", - "integrity": "sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY=", - "dev": true - }, - "lru-cache": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", - "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", - "dev": true - }, - "merge-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", - "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" - } - }, - "mime-db": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", - "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=", - "dev": true - }, - "mime-types": { - "version": "2.1.17", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", - "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", - "dev": true, - "requires": { - "mime-db": "1.30.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "1.1.8" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-2.5.3.tgz", - "integrity": "sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg=", - "dev": true, - "requires": { - "commander": "2.3.0", - "debug": "2.2.0", - "diff": "1.4.0", - "escape-string-regexp": "1.0.2", - "glob": "3.2.11", - "growl": "1.9.2", - "jade": "0.26.3", - "mkdirp": "0.5.1", - "supports-color": "1.2.0", - "to-iso-string": "0.0.2" - }, - "dependencies": { - "escape-string-regexp": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz", - "integrity": "sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE=", - "dev": true - }, - "glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", - "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "minimatch": "0.3.0" - } - }, - "minimatch": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", - "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", - "dev": true, - "requires": { - "lru-cache": "2.7.3", - "sigmund": "1.0.1" - } - }, - "supports-color": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz", - "integrity": "sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4=", - "dev": true - } - } - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - }, - "multimatch": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", - "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", - "dev": true, - "requires": { - "array-differ": "1.0.0", - "array-union": "1.0.2", - "arrify": "1.0.1", - "minimatch": "3.0.4" - } - }, - "multipipe": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", - "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", - "dev": true, - "requires": { - "duplexer2": "0.0.2" - } - }, - "named-js-regexp": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/named-js-regexp/-/named-js-regexp-1.3.3.tgz", - "integrity": "sha512-zIUAXzGQOp16VR0Ct89SDstU62hzAPBluNUrUrsdD7MNSRbm/vyqGhEnp+4hnsMjmX3C2wh1cbIEP0joKMFLxw==" - }, - "nan": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz", - "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=", - "dev": true, - "optional": true - }, - "native-promise-only": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", - "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", - "dev": true - }, - "natives": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.0.tgz", - "integrity": "sha1-6f+EFBimsux6SV6TmYT3jxY+bjE=", - "dev": true - }, - "node.extend": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-1.1.6.tgz", - "integrity": "sha1-p7iCyC1sk6SGOlUEvV3o7IYli5Y=", - "dev": true, - "requires": { - "is": "3.2.1" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "1.1.0" - } - }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true - }, - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", - "dev": true - }, - "object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", - "dev": true, - "requires": { - "array-each": "1.0.1", - "array-slice": "1.1.0", - "for-own": "1.0.0", - "isobject": "3.0.1" - }, - "dependencies": { - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "1.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "0.1.5", - "is-extendable": "0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "once": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", - "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "orchestrator": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz", - "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=", - "dev": true, - "requires": { - "end-of-stream": "0.1.5", - "sequencify": "0.0.7", - "stream-consume": "0.1.0" - } - }, - "ordered-read-streams": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz", - "integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=", - "dev": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "parse-filepath": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.1.tgz", - "integrity": "sha1-FZ1hVdQ5BNFsEO9piRHaHpGWm3M=", - "dev": true, - "requires": { - "is-absolute": "0.2.6", - "map-cache": "0.2.2", - "path-root": "0.1.1" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "0.3.0", - "is-dotfile": "1.0.3", - "is-extglob": "1.0.0", - "is-glob": "2.0.1" - } - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", - "dev": true - }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", - "dev": true, - "requires": { - "path-root-regex": "0.1.2" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", - "dev": true - }, - "path-to-regexp": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", - "dev": true, - "requires": { - "isarray": "0.0.1" - } - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", - "dev": true, - "requires": { - "through": "2.3.8" - } - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "2.0.4" - } - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", - "dev": true - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "qs": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", - "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=", - "dev": true - }, - "querystringify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-1.0.0.tgz", - "integrity": "sha1-YoYkIRLFtxL6ZU5SZlK/ahP/Bcs=", - "dev": true - }, - "queue": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/queue/-/queue-3.1.0.tgz", - "integrity": "sha1-bEnQHwCeIlZ4h4nyv/rGuLmZBYU=", - "dev": true, - "requires": { - "inherits": "2.0.3" - } - }, - "randomatic": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", - "dev": true, - "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "readdirp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", - "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "minimatch": "3.0.4", - "readable-stream": "2.3.3", - "set-immediate-shim": "1.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "1.5.0" - } - }, - "reflect-metadata": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.10.tgz", - "integrity": "sha1-tPg3BEFqytiZiMmxVjXUfgO5NEo=" - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "0.1.3" - } - }, - "relative": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/relative/-/relative-3.0.2.tgz", - "integrity": "sha1-Dc2OxUpdNaPBXhBFA9ZTdbWlNn8=", - "dev": true, - "requires": { - "isobject": "2.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", - "dev": true - }, - "request": { - "version": "2.83.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", - "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", - "dev": true, - "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.3.1", - "har-validator": "5.0.3", - "hawk": "6.0.2", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "oauth-sign": "0.8.2", - "performance-now": "2.1.0", - "qs": "6.5.1", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.3", - "tunnel-agent": "0.6.0", - "uuid": "3.1.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "boom": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", - "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", - "dev": true, - "requires": { - "hoek": "4.2.0" - } - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "cryptiles": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", - "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", - "dev": true, - "requires": { - "boom": "5.2.0" - }, - "dependencies": { - "boom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", - "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", - "dev": true, - "requires": { - "hoek": "4.2.0" - } - } - } - }, - "form-data": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", - "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", - "dev": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" - } - }, - "har-validator": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", - "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", - "dev": true, - "requires": { - "ajv": "5.5.0", - "har-schema": "2.0.0" - } - }, - "hawk": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", - "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", - "dev": true, - "requires": { - "boom": "4.3.1", - "cryptiles": "3.1.2", - "hoek": "4.2.0", - "sntp": "2.1.0" - } - }, - "hoek": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", - "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==", - "dev": true - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" - } - }, - "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", - "dev": true - }, - "sntp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", - "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", - "dev": true, - "requires": { - "hoek": "4.2.0" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", - "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", - "dev": true, - "requires": { - "path-parse": "1.0.5" - } - }, - "resolve-dir": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", - "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", - "dev": true, - "requires": { - "expand-tilde": "1.2.2", - "global-modules": "0.2.3" - } - }, - "retyped-diff-match-patch-tsd-ambient": { - "version": "1.0.0-1", - "resolved": "https://registry.npmjs.org/retyped-diff-match-patch-tsd-ambient/-/retyped-diff-match-patch-tsd-ambient-1.0.0-1.tgz", - "integrity": "sha1-Jkgr9JFcftn4MAu1y+xI/U/1vGI=", - "dev": true - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "7.1.2" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.3.3", - "path-is-absolute": "1.0.1" - } - } - } - }, - "rxjs": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.2.tgz", - "integrity": "sha512-oRYoIKWBU3Ic37fLA5VJu31VqQO4bWubRntcHSJ+cwaDQBwdnZ9x4zmhJfm/nFQ2E82/I4loSioHnACamrKGgA==", - "requires": { - "symbol-observable": "1.1.0" - } - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true - }, - "samsam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", - "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", - "dev": true - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" - }, - "sequencify": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz", - "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=", - "dev": true - }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true - }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true - }, - "sinon": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-2.4.1.tgz", - "integrity": "sha512-vFTrO9Wt0ECffDYIPSP/E5bBugt0UjcBQOfQUMh66xzkyPEnhl/vM2LRZi2ajuTdkH07sA6DzrM6KvdvGIH8xw==", - "dev": true, - "requires": { - "diff": "3.4.0", - "formatio": "1.2.0", - "lolex": "1.6.0", - "native-promise-only": "0.8.1", - "path-to-regexp": "1.7.0", - "samsam": "1.3.0", - "text-encoding": "0.6.4", - "type-detect": "4.0.5" - }, - "dependencies": { - "diff": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz", - "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==", - "dev": true - } - } - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - }, - "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-support": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.0.tgz", - "integrity": "sha512-vUoN3I7fHQe0R/SJLKRdKYuEdRGogsviXFkHHo17AWaTGv17VLnxw+CFXvqy+y4ORZ3doWLQcxRYfwKrsd/H7Q==", - "dev": true, - "requires": { - "source-map": "0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "sparkles": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", - "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", - "dev": true - }, - "split": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", - "dev": true, - "requires": { - "through": "2.3.8" - } - }, - "sshpk": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", - "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", - "dev": true, - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "stat-mode": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-0.2.2.tgz", - "integrity": "sha1-5sgLYjEj19gM8TLOU480YokHJQI=", - "dev": true - }, - "stream-combiner": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", - "dev": true, - "requires": { - "duplexer": "0.1.1" - } - }, - "stream-consume": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz", - "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=", - "dev": true - }, - "stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", - "dev": true - }, - "streamfilter": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/streamfilter/-/streamfilter-1.0.5.tgz", - "integrity": "sha1-h1BxEb644phFFxe1Ec/tjwAqv1M=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "streamifier": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/streamifier/-/streamifier-0.1.1.tgz", - "integrity": "sha1-l+mNj6TRBdYqJpHR3AfoINuN/E8=", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "stringstream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "strip-bom": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz", - "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=", - "dev": true, - "requires": { - "first-chunk-stream": "1.0.0", - "is-utf8": "0.2.1" - } - }, - "strip-bom-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz", - "integrity": "sha1-+H217yYT9paKpUWr/h7HKLaoKco=", - "dev": true, - "requires": { - "first-chunk-stream": "2.0.0", - "strip-bom": "2.0.0" - }, - "dependencies": { - "first-chunk-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz", - "integrity": "sha1-G97NuOCDwGZLkZRVgVd6Q6nzHXA=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "0.2.1" - } - } - } - }, - "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "symbol-observable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.1.0.tgz", - "integrity": "sha512-dQoid9tqQ+uotGhuTKEY11X4xhyYePVnqGSoSm3OGKh2E8LZ6RPULp1uXTctk33IeERlrRJYoVSBglsL05F5Uw==" - }, - "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", - "dev": true, - "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" - } - }, - "text-encoding": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", - "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "through2": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", - "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", - "dev": true, - "requires": { - "readable-stream": "2.3.3", - "xtend": "4.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "through2-filter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz", - "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=", - "dev": true, - "requires": { - "through2": "2.0.3", - "xtend": "4.0.1" - } - }, - "tildify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", - "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", - "dev": true, - "requires": { - "os-homedir": "1.0.2" - } - }, - "time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", - "dev": true - }, - "tmp": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.29.tgz", - "integrity": "sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA=", - "requires": { - "os-tmpdir": "1.0.2" - } - }, - "to-absolute-glob": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz", - "integrity": "sha1-HN+kcqnvUMI57maZm2YsoOs5k38=", - "dev": true, - "requires": { - "extend-shallow": "2.0.1" - } - }, - "to-iso-string": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/to-iso-string/-/to-iso-string-0.0.2.tgz", - "integrity": "sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE=", - "dev": true - }, - "tough-cookie": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", - "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", - "dev": true, - "requires": { - "punycode": "1.4.1" - } - }, - "tree-kill": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.0.tgz", - "integrity": "sha512-DlX6dR0lOIRDFxI0mjL9IYg6OTncLm/Zt+JiBhE5OlFcAR8yc9S7FFXU9so0oda47frdM/JFsk7UjNt9vscKcg==" - }, - "tslib": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.8.0.tgz", - "integrity": "sha512-ymKWWZJST0/CkgduC2qkzjMOWr4bouhuURNXCn/inEX0L57BnRG6FhX76o7FOnsjHazCjfU2LKeSrlS2sIKQJg==", - "dev": true - }, - "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", - "dev": true, - "requires": { - "babel-code-frame": "6.26.0", - "builtin-modules": "1.1.1", - "chalk": "2.3.0", - "commander": "2.12.2", - "diff": "3.4.0", - "glob": "7.1.2", - "minimatch": "3.0.4", - "resolve": "1.5.0", - "semver": "5.4.1", - "tslib": "1.8.0", - "tsutils": "2.13.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "1.9.1" - } - }, - "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" - } - }, - "commander": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz", - "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==", - "dev": true - }, - "diff": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz", - "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==", - "dev": true - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.3.3", - "path-is-absolute": "1.0.1" - } - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "dev": true, - "requires": { - "has-flag": "2.0.0" - } - } - } - }, - "tslint-eslint-rules": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/tslint-eslint-rules/-/tslint-eslint-rules-4.1.1.tgz", - "integrity": "sha1-fDDniC8mvCdr/5HSOEl1xp2viLo=", - "dev": true, - "requires": { - "doctrine": "0.7.2", - "tslib": "1.8.0", - "tsutils": "1.9.1" - }, - "dependencies": { - "tsutils": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-1.9.1.tgz", - "integrity": "sha1-ufmrROVa+WgYMdXyjQrur1x1DLA=", - "dev": true - } - } - }, - "tslint-microsoft-contrib": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-5.0.1.tgz", - "integrity": "sha1-Mo7pwo0HzfeTKTIEyW4v+rkiGZQ=", - "dev": true, - "requires": { - "tsutils": "1.9.1" - }, - "dependencies": { - "tsutils": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-1.9.1.tgz", - "integrity": "sha1-ufmrROVa+WgYMdXyjQrur1x1DLA=", - "dev": true - } - } - }, - "tsutils": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.13.0.tgz", - "integrity": "sha512-FuWzNJbMsp3gcZMbI3b5DomhW4Ia41vMxjN63nKWI0t7f+I3UmHfRl0TrXJTwI2LUduDG+eR1Mksp3pvtlyCFQ==", - "dev": true, - "requires": { - "tslib": "1.8.0" - } - }, - "tunnel-agent": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", - "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", - "dev": true - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, - "optional": true - }, - "type-detect": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.5.tgz", - "integrity": "sha512-N9IvkQslUGYGC24RkJk1ba99foK6TkwC2FHAEBlQFBP0RxQZS8ZpJuAZcwiY/w9ZJHFQb1aOXBI60OdxhTrwEQ==", - "dev": true - }, - "typescript": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz", - "integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=", - "dev": true - }, - "typescript-formatter": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/typescript-formatter/-/typescript-formatter-6.1.0.tgz", - "integrity": "sha512-o2TJSBDSdua8yl8gXNJonM4jr4f7ZuLhsbG7zMG80iJluhE8MWI0R/mPzA3in3omwAJwkcbkc5Xxm74io/J7WA==", - "dev": true, - "requires": { - "commandpost": "1.2.1", - "editorconfig": "0.15.0" - } - }, - "uint64be": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uint64be/-/uint64be-1.0.1.tgz", - "integrity": "sha1-H3FUIC8qG4rzU4cd2mUb80zpPpU=" - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", - "dev": true - }, - "unique-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", - "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=", - "dev": true - }, - "universalify": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", - "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=" - }, - "untildify": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-3.0.2.tgz", - "integrity": "sha1-fx8wIFWz/qDz6B3HjrNnZstl4/E=" - }, - "url-parse": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.2.0.tgz", - "integrity": "sha512-DT1XbYAfmQP65M/mE6OALxmXzZ/z1+e5zk2TcSKe/KiYbNGZxgtttzC0mR/sjopbpOXcbniq7eIKmocJnUWlEw==", - "dev": true, - "requires": { - "querystringify": "1.0.0", - "requires-port": "1.0.0" - } - }, - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "uuid": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", - "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", - "dev": true - }, - "v8flags": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", - "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", - "dev": true, - "requires": { - "user-home": "1.1.1" - } - }, - "vali-date": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz", - "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "1.3.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "vinyl": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", - "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", - "dev": true, - "requires": { - "clone": "1.0.3", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - }, - "vinyl-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/vinyl-file/-/vinyl-file-2.0.0.tgz", - "integrity": "sha1-p+v1/779obfRjRQPyweyI++2dRo=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0", - "strip-bom-stream": "2.0.0", - "vinyl": "1.2.0" - }, - "dependencies": { - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "0.2.1" - } - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.3", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - } - } - }, - "vinyl-fs": { - "version": "0.3.14", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz", - "integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=", - "dev": true, - "requires": { - "defaults": "1.0.3", - "glob-stream": "3.1.18", - "glob-watcher": "0.0.6", - "graceful-fs": "3.0.11", - "mkdirp": "0.5.1", - "strip-bom": "1.0.0", - "through2": "0.6.5", - "vinyl": "0.4.6" - }, - "dependencies": { - "clone": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", - "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", - "dev": true - }, - "graceful-fs": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz", - "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", - "dev": true, - "requires": { - "natives": "1.1.0" - } - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - }, - "vinyl": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", - "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", - "dev": true, - "requires": { - "clone": "0.2.0", - "clone-stats": "0.0.1" - } - } - } - }, - "vinyl-source-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-source-stream/-/vinyl-source-stream-1.1.0.tgz", - "integrity": "sha1-RMvlEIIFJ53rDFZTwJSiiHk4sas=", - "dev": true, - "requires": { - "through2": "0.6.5", - "vinyl": "0.4.6" - }, - "dependencies": { - "clone": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", - "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - }, - "vinyl": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", - "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", - "dev": true, - "requires": { - "clone": "0.2.0", - "clone-stats": "0.0.1" - } - } - } - }, - "vscode": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.9.tgz", - "integrity": "sha512-xhSh410NntYViiBYIPimAwF0U6NZgORtqQenlpTI/qKBGwHMtZSCJcL3/JIhfCw43HBXqPg59kA947OT3UvZKQ==", - "dev": true, - "requires": { - "glob": "7.1.2", - "gulp-chmod": "2.0.0", - "gulp-filter": "5.0.1", - "gulp-gunzip": "1.0.0", - "gulp-remote-src": "0.4.3", - "gulp-symdest": "1.1.0", - "gulp-untar": "0.0.6", - "gulp-vinyl-zip": "2.1.0", - "mocha": "4.0.1", - "request": "2.83.0", - "semver": "5.4.1", - "source-map-support": "0.5.0", - "url-parse": "1.2.0", - "vinyl-source-stream": "1.1.0" - }, - "dependencies": { - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.3.3", - "path-is-absolute": "1.0.1" - } - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "mocha": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.0.1.tgz", - "integrity": "sha512-evDmhkoA+cBNiQQQdSKZa2b9+W2mpLoj50367lhy+Klnx9OV8XlCIhigUnn1gaTFLQCa0kdNhEGDr0hCXOQFDw==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "2.0.0" - } - } - } - }, - "vscode-debugadapter": { - "version": "1.24.0", - "resolved": "https://registry.npmjs.org/vscode-debugadapter/-/vscode-debugadapter-1.24.0.tgz", - "integrity": "sha1-KAY7AcyorB5fehPRGOMgem6If/0=", - "requires": { - "vscode-debugprotocol": "1.24.0" - } - }, - "vscode-debugprotocol": { - "version": "1.24.0", - "resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.24.0.tgz", - "integrity": "sha1-28EOjX2VsQJyehmvPw/O9+JSsI4=" - }, - "vscode-extension-telemetry": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.5.tgz", - "integrity": "sha1-IeKrtMvOMybkad27MiEjs3AvP4U=", - "requires": { - "applicationinsights": "0.15.6", - "winreg": "0.0.13" - }, - "dependencies": { - "winreg": { - "version": "0.0.13", - "resolved": "https://registry.npmjs.org/winreg/-/winreg-0.0.13.tgz", - "integrity": "sha1-dr/gLh3QycgnX7n98XqfNoRuNIM=" - } - } - }, - "vscode-jsonrpc": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.5.0.tgz", - "integrity": "sha1-hyOdnhZrLXNSJFuKgTWXgEwdY6o=" - }, - "vscode-languageclient": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-3.5.0.tgz", - "integrity": "sha1-NtAswYaoNlpEZ3GaKQ+yAKmuSQo=", - "requires": { - "vscode-languageserver-protocol": "3.5.0" - } - }, - "vscode-languageserver": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-3.5.0.tgz", - "integrity": "sha1-0oCZvG3dqMHdFrcH5FThsd2uDbo=", - "requires": { - "vscode-languageserver-protocol": "3.5.0", - "vscode-uri": "1.0.1" - } - }, - "vscode-languageserver-protocol": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.5.0.tgz", - "integrity": "sha1-Bnxcvidwl5U5jRGWksl+u6FFIgk=", - "requires": { - "vscode-jsonrpc": "3.5.0", - "vscode-languageserver-types": "3.5.0" - } - }, - "vscode-languageserver-types": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.5.0.tgz", - "integrity": "sha1-5I15li8LjgLelV4/UkkI4rGcA3Q=" - }, - "vscode-uri": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.1.tgz", - "integrity": "sha1-Eahr7+rDxKo+wIYjZRo8gabQu8g=" - }, - "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", - "dev": true, - "requires": { - "isexe": "2.0.0" - } - }, - "winreg": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.4.tgz", - "integrity": "sha1-ugZWKbepJRMOFXeRCM9UCZDpjRs=" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xml2js": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", - "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", - "requires": { - "sax": "1.2.4", - "xmlbuilder": "9.0.4" - } - }, - "xmlbuilder": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.4.tgz", - "integrity": "sha1-UZy0ymhtAFqEINNJbz8MruzKWA8=" - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, - "yauzl": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz", - "integrity": "sha1-qBmB6nCleUYTOIPwKcWCGok1mn8=", - "dev": true, - "requires": { - "buffer-crc32": "0.2.13", - "fd-slicer": "1.0.1" - } - }, - "yazl": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.4.3.tgz", - "integrity": "sha1-7CblzIfVYBud+EMtvdPNLlFzoHE=", - "dev": true, - "requires": { - "buffer-crc32": "0.2.13" - } - } - } + "name": "python", + "version": "0.8.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/chai": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.0.6.tgz", + "integrity": "sha512-IzRWv/7IpaMm41KLLJcaaD/UKit/MrHu4rWs61oWiVjuk4aKWe2eopx3XyhAHhSnMyB5EeCMRr2AsJtuQ8COWA==", + "dev": true + }, + "@types/chai-as-promised": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.0.tgz", + "integrity": "sha512-MFiW54UOSt+f2bRw8J7LgQeIvE/9b4oGvwU7XW30S9QGAiHGnU/fmiOprsyMkdmH2rl8xSPc0/yrQw8juXU6bQ==", + "dev": true, + "requires": { + "@types/chai": "4.0.6" + } + }, + "@types/commander": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/@types/commander/-/commander-2.12.2.tgz", + "integrity": "sha512-0QEFiR8ljcHp9bAbWxecjVRuAMr16ivPiGOw6KFQBVrVd0RQIcM3xKdRisH2EDWgVWujiYtHwhSkSUoAAGzH7Q==", + "dev": true, + "requires": { + "commander": "2.3.0" + } + }, + "@types/fs-extra": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", + "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", + "dev": true, + "requires": { + "@types/node": "6.0.92" + } + }, + "@types/get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@types/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha512-TiNg8R1kjDde5Pub9F9vCwZA/BNW9HeXP5b9j7Qucqncy/McfPZ6xze/EyBdXS5FhMIGN6Fx3vg75l5KHy3V1Q==", + "dev": true + }, + "@types/iconv-lite": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@types/iconv-lite/-/iconv-lite-0.0.1.tgz", + "integrity": "sha1-qjuL2ivlErGuCgV7lC6GnDcKVWk=", + "dev": true, + "requires": { + "@types/node": "6.0.92" + } + }, + "@types/lodash": { + "version": "4.14.87", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.87.tgz", + "integrity": "sha512-AqRC+aEF4N0LuNHtcjKtvF9OTfqZI0iaBoe3dA6m/W+/YZJBZjBmW/QIZ8fBeXC6cnytSY9tBoFBqZ9uSCeVsw==", + "dev": true + }, + "@types/mocha": { + "version": "2.2.44", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.44.tgz", + "integrity": "sha512-k2tWTQU8G4+iSMvqKi0Q9IIsWAp/n8xzdZS4Q4YVIltApoMA00wFBFdlJnmoaK1/z7B0Cy0yPe6GgXteSmdUNw==", + "dev": true + }, + "@types/node": { + "version": "6.0.92", + "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.92.tgz", + "integrity": "sha512-awEYSSTn7dauwVCYSx2CJaPTu0Z1Ht2oR1b2AD3CYao6ZRb+opb6EL43fzmD7eMFgMHzTBWSUzlWSD+S8xN0Nw==", + "dev": true + }, + "@types/semver": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.4.0.tgz", + "integrity": "sha512-PBHCvO98hNec9A491vBbh0ZNDOVxccwKL1u2pm6fs9oDgm7SEnw0lEHqHfjsYryDxnE3zaf7LvERWEXjOp1hig==", + "dev": true + }, + "@types/sinon": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-2.3.7.tgz", + "integrity": "sha512-w+LjztaZbgZWgt/y/VMP5BUAWLtSyoIJhXyW279hehLPyubDoBNwvhcj3WaSptcekuKYeTCVxrq60rdLc6ImJA==", + "dev": true + }, + "@types/uuid": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.3.tgz", + "integrity": "sha512-5fRLCYhLtDb3hMWqQyH10qtF+Ud2JnNCXTCZ+9ktNdCcgslcuXkDTkFcJNk++MT29yDntDnlF1+jD+uVGumsbw==", + "dev": true, + "requires": { + "@types/node": "6.0.92" + } + }, + "@types/winreg": { + "version": "1.2.30", + "resolved": "https://registry.npmjs.org/@types/winreg/-/winreg-1.2.30.tgz", + "integrity": "sha1-kdZxDlNtNFucmwF8V0z2qNpkxRg=", + "dev": true + }, + "@types/xml2js": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.2.tgz", + "integrity": "sha512-8aKUBSj3oGcnuiBmDLm3BIk09RYg01mz9HlQ2u4aS17oJ25DxjQrEUVGFSBVNOfM45pQW4OjcBPplq6r/exJdA==", + "dev": true, + "requires": { + "@types/node": "6.0.92" + } + }, + "ajv": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.1.tgz", + "integrity": "sha1-s4u4h22ehr7plJVqBOch6IskjrI=", + "dev": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.0.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "requires": { + "micromatch": "2.3.11", + "normalize-path": "2.1.1" + } + }, + "applicationinsights": { + "version": "0.15.6", + "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-0.15.6.tgz", + "integrity": "sha1-IBoGgsBwT+S92aktCyy+NNKuWXI=" + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", + "dev": true + }, + "array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", + "dev": true + }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "dev": true + }, + "assertion-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", + "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", + "dev": true + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "dev": true + }, + "aws4": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "beeper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", + "dev": true + }, + "binary-extensions": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "dev": true + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "2.1.1", + "map-obj": "1.0.1" + } + }, + "caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", + "dev": true + }, + "chai": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", + "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", + "dev": true, + "requires": { + "assertion-error": "1.0.2", + "check-error": "1.0.2", + "deep-eql": "3.0.1", + "get-func-name": "2.0.0", + "pathval": "1.1.0", + "type-detect": "4.0.5" + } + }, + "chai-as-promised": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", + "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", + "dev": true, + "requires": { + "check-error": "1.0.2" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true, + "requires": { + "anymatch": "1.3.2", + "async-each": "1.0.1", + "fsevents": "1.1.3", + "glob-parent": "2.0.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "2.0.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0" + } + }, + "ci-info": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.2.tgz", + "integrity": "sha512-uTGIPNx/nSpBdsF6xnseRXLLtfr9VLqkz8ZqHXr3Y7b6SftyRxBGjwMtJj1OhNbmlc1wZzLNAlAcvyIiE8a6ZA==", + "dev": true + }, + "clone": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz", + "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=", + "dev": true + }, + "clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", + "dev": true + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + }, + "cloneable-readable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.0.0.tgz", + "integrity": "sha1-pikNQT8hemEjL5XkWP84QYz7ARc=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "process-nextick-args": "1.0.7", + "through2": "2.0.3" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "color-convert": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", + "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, + "combined-stream": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "dev": true, + "requires": { + "delayed-stream": "1.0.0" + } + }, + "commander": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", + "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=", + "dev": true + }, + "commandpost": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/commandpost/-/commandpost-1.2.1.tgz", + "integrity": "sha512-V1wzc+DTFsO96te2W/U+fKNRSOWtOwXhkkZH2WRLLbucrY+YrDNsRr4vtfSf83MUZVF3E6B4nwT30fqaTpzipQ==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "convert-source-map": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "dev": true, + "requires": { + "boom": "2.10.1" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "1.0.2" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "dateformat": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", + "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=", + "dev": true + }, + "debounce": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.1.0.tgz", + "integrity": "sha512-ZQVKfRVlwRfD150ndzEK8M90ABT+Y/JQKs4Y7U4MXdpuoUkkrr4DwKbVux3YjylA5bUMUj0Nc3pMxPJX6N2QQQ==", + "dev": true + }, + "debounce-hashed": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/debounce-hashed/-/debounce-hashed-0.1.2.tgz", + "integrity": "sha1-oN/jB8Gn2zD2kRyM+8DvhB831K8=", + "dev": true + }, + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "requires": { + "ms": "0.7.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "deep-assign": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/deep-assign/-/deep-assign-1.0.0.tgz", + "integrity": "sha1-sJJ0O+hCfcYh6gBnzex+cN0Z83s=", + "dev": true, + "requires": { + "is-obj": "1.0.1" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "4.0.5" + } + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "requires": { + "clone": "1.0.3" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "deprecated": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz", + "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=", + "dev": true + }, + "detect-file": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz", + "integrity": "sha1-STXe39lIhkjgBrASlWbpOGcR6mM=", + "dev": true, + "requires": { + "fs-exists-sync": "0.1.0" + } + }, + "diff": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", + "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", + "dev": true + }, + "diff-match-patch": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.0.tgz", + "integrity": "sha1-HMPIOkkNZ/ldkeOfatHy4Ia2MEg=" + }, + "doctrine": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz", + "integrity": "sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM=", + "dev": true, + "requires": { + "esutils": "1.1.6", + "isarray": "0.0.1" + }, + "dependencies": { + "esutils": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz", + "integrity": "sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U=", + "dev": true + } + } + }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "dev": true + }, + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "dev": true, + "requires": { + "readable-stream": "1.1.14" + } + }, + "duplexify": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.1.tgz", + "integrity": "sha512-j5goxHTwVED1Fpe5hh3q9R93Kip0Bg2KVAt4f8CEYM3UEwYcPSvWbXaUQOzdX/HtiNomipv+gU7ASQPDbV7pGQ==", + "dev": true, + "requires": { + "end-of-stream": "1.4.0", + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "stream-shift": "1.0.0" + }, + "dependencies": { + "end-of-stream": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", + "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", + "dev": true, + "requires": { + "once": "1.4.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "editorconfig": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.0.tgz", + "integrity": "sha512-j7JBoj/bpNzvoTQylfRZSc85MlLNKWQiq5y6gwKhmqD2h1eZ+tH4AXbkhEJD468gjDna/XMx2YtSkCxBRX9OGg==", + "dev": true, + "requires": { + "@types/commander": "2.12.2", + "@types/semver": "5.4.0", + "commander": "2.12.2", + "lru-cache": "4.1.1", + "semver": "5.4.1", + "sigmund": "1.0.1" + }, + "dependencies": { + "commander": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz", + "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==", + "dev": true + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + } + } + }, + "end-of-stream": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", + "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=", + "dev": true, + "requires": { + "once": "1.3.3" + } + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "event-stream": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", + "dev": true, + "requires": { + "duplexer": "0.1.1", + "from": "0.1.7", + "map-stream": "0.1.0", + "pause-stream": "0.0.11", + "split": "0.3.3", + "stream-combiner": "0.0.4", + "through": "2.3.8" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "requires": { + "fill-range": "2.2.3" + } + }, + "expand-tilde": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", + "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", + "dev": true, + "requires": { + "os-homedir": "1.0.2" + } + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "dev": true + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fancy-log": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", + "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "time-stamp": "1.1.0" + } + }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "dev": true, + "requires": { + "pend": "1.2.0" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } + }, + "find-index": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", + "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", + "dev": true + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "findup-sync": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.3.tgz", + "integrity": "sha1-QAQ5Kee8YK3wt/SCfExudaDeyhI=", + "dev": true, + "requires": { + "detect-file": "0.1.0", + "is-glob": "2.0.1", + "micromatch": "2.3.11", + "resolve-dir": "0.1.1" + } + }, + "fined": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.0.tgz", + "integrity": "sha1-s33IRLdqL15wgeiE98CuNE8VNHY=", + "dev": true, + "requires": { + "expand-tilde": "2.0.2", + "is-plain-object": "2.0.4", + "object.defaults": "1.1.0", + "object.pick": "1.3.0", + "parse-filepath": "1.0.1" + }, + "dependencies": { + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "1.0.1" + } + } + } + }, + "first-chunk-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", + "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=", + "dev": true + }, + "flagged-respawn": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.2.tgz", + "integrity": "sha1-/xke3c1wiKZ1smEP/8l2vpuAdLU=", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "1.0.2" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "dev": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.17" + } + }, + "formatio": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", + "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", + "dev": true, + "requires": { + "samsam": "1.3.0" + } + }, + "from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", + "dev": true + }, + "fs-exists-sync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=", + "dev": true + }, + "fs-extra": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.2.tgz", + "integrity": "sha1-+RcExT0bRh+JNFKwwwfZmXZHq2s=", + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "4.0.0", + "universalify": "0.1.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz", + "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", + "dev": true, + "optional": true, + "requires": { + "nan": "2.8.0", + "node-pre-gyp": "0.6.39" + }, + "dependencies": { + "abbrev": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "ajv": { + "version": "4.11.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.2.9" + } + }, + "asn1": { + "version": "0.2.3", + "bundled": true, + "dev": true, + "optional": true + }, + "assert-plus": { + "version": "0.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "asynckit": { + "version": "0.4.0", + "bundled": true, + "dev": true, + "optional": true + }, + "aws-sign2": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "aws4": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "balanced-match": { + "version": "0.4.2", + "bundled": true, + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "block-stream": { + "version": "0.0.9", + "bundled": true, + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "boom": { + "version": "2.10.1", + "bundled": true, + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "brace-expansion": { + "version": "1.1.7", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "concat-map": "0.0.1" + } + }, + "buffer-shims": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "caseless": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true + }, + "co": { + "version": "4.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "combined-stream": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "requires": { + "delayed-stream": "1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "cryptiles": { + "version": "2.0.5", + "bundled": true, + "dev": true, + "requires": { + "boom": "2.10.1" + } + }, + "dashdash": { + "version": "1.14.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "debug": { + "version": "2.6.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.4.2", + "bundled": true, + "dev": true, + "optional": true + }, + "delayed-stream": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "ecc-jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "extend": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "extsprintf": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "optional": true + }, + "form-data": { + "version": "2.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.15" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "fstream": { + "version": "1.0.11", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.1" + } + }, + "fstream-ignore": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fstream": "1.0.11", + "inherits": "2.0.3", + "minimatch": "3.0.4" + } + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "1.1.1", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" + } + }, + "getpass": { + "version": "0.1.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "bundled": true, + "dev": true + }, + "har-schema": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "har-validator": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ajv": "4.11.8", + "har-schema": "1.0.5" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "hawk": { + "version": "3.1.3", + "bundled": true, + "dev": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "hoek": { + "version": "2.16.3", + "bundled": true, + "dev": true + }, + "http-signature": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.0", + "sshpk": "1.13.0" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.4", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "isstream": { + "version": "0.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "jodid25519": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "bundled": true, + "dev": true, + "optional": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "jsonify": { + "version": "0.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "jsprim": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.0.2", + "json-schema": "0.2.3", + "verror": "1.3.6" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "mime-db": { + "version": "1.27.0", + "bundled": true, + "dev": true + }, + "mime-types": { + "version": "2.1.15", + "bundled": true, + "dev": true, + "requires": { + "mime-db": "1.27.0" + } + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "node-pre-gyp": { + "version": "0.6.39", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "1.0.2", + "hawk": "3.1.3", + "mkdirp": "0.5.1", + "nopt": "4.0.1", + "npmlog": "4.1.0", + "rc": "1.2.1", + "request": "2.81.0", + "rimraf": "2.6.1", + "semver": "5.3.0", + "tar": "2.2.1", + "tar-pack": "3.4.0" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1.1.0", + "osenv": "0.1.4" + } + }, + "npmlog": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "performance-now": { + "version": "0.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "1.0.7", + "bundled": true, + "dev": true + }, + "punycode": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true + }, + "qs": { + "version": "6.4.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.4", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.2.9", + "bundled": true, + "dev": true, + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "1.0.1", + "util-deprecate": "1.0.2" + } + }, + "request": { + "version": "2.81.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "4.2.1", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.15", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.0.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.6.0", + "uuid": "3.0.1" + } + }, + "rimraf": { + "version": "2.6.1", + "bundled": true, + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "safe-buffer": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.3.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sntp": { + "version": "1.0.9", + "bundled": true, + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "sshpk": { + "version": "1.13.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jodid25519": "1.0.2", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string_decoder": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, + "stringstream": { + "version": "0.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "2.2.1", + "bundled": true, + "dev": true, + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" + } + }, + "tar-pack": { + "version": "3.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "2.6.8", + "fstream": "1.0.11", + "fstream-ignore": "1.0.5", + "once": "1.4.0", + "readable-stream": "2.2.9", + "rimraf": "2.6.1", + "tar": "2.2.1", + "uid-number": "0.0.6" + } + }, + "tough-cookie": { + "version": "2.3.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "punycode": "1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "bundled": true, + "dev": true, + "optional": true + }, + "uid-number": { + "version": "0.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "uuid": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "verror": { + "version": "1.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "extsprintf": "1.0.2" + } + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + } + } + }, + "fstream": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.2" + } + }, + "fuzzy": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/fuzzy/-/fuzzy-0.1.3.tgz", + "integrity": "sha1-THbsL/CsGjap3M+aAN+GIweNTtg=" + }, + "gaze": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", + "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=", + "dev": true, + "requires": { + "globule": "0.1.0" + } + }, + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "dev": true + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "requires": { + "is-property": "1.0.2" + } + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=" + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "glob": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", + "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "2.0.10", + "once": "1.3.3" + }, + "dependencies": { + "minimatch": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + } + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + }, + "glob-stream": { + "version": "3.1.18", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", + "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", + "dev": true, + "requires": { + "glob": "4.5.3", + "glob2base": "0.0.12", + "minimatch": "2.0.10", + "ordered-read-streams": "0.1.0", + "through2": "0.6.5", + "unique-stream": "1.0.0" + }, + "dependencies": { + "minimatch": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + } + } + } + }, + "glob-watcher": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz", + "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=", + "dev": true, + "requires": { + "gaze": "0.5.2" + } + }, + "glob2base": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", + "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", + "dev": true, + "requires": { + "find-index": "0.1.1" + } + }, + "global-modules": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", + "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", + "dev": true, + "requires": { + "global-prefix": "0.1.5", + "is-windows": "0.2.0" + } + }, + "global-prefix": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", + "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", + "dev": true, + "requires": { + "homedir-polyfill": "1.0.1", + "ini": "1.3.5", + "is-windows": "0.2.0", + "which": "1.3.0" + } + }, + "globule": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", + "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", + "dev": true, + "requires": { + "glob": "3.1.21", + "lodash": "1.0.2", + "minimatch": "0.2.14" + }, + "dependencies": { + "glob": { + "version": "3.1.21", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", + "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", + "dev": true, + "requires": { + "graceful-fs": "1.2.3", + "inherits": "1.0.2", + "minimatch": "0.2.14" + } + }, + "graceful-fs": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", + "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=", + "dev": true + }, + "inherits": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", + "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=", + "dev": true + }, + "lodash": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", + "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=", + "dev": true + }, + "minimatch": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", + "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", + "dev": true, + "requires": { + "lru-cache": "2.7.3", + "sigmund": "1.0.1" + } + } + } + }, + "glogg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", + "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", + "dev": true, + "requires": { + "sparkles": "1.0.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "growl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "dev": true + }, + "gulp": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz", + "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=", + "dev": true, + "requires": { + "archy": "1.0.0", + "chalk": "1.1.3", + "deprecated": "0.0.1", + "gulp-util": "3.0.8", + "interpret": "1.1.0", + "liftoff": "2.3.0", + "minimist": "1.2.0", + "orchestrator": "0.3.8", + "pretty-hrtime": "1.0.3", + "semver": "4.3.6", + "tildify": "1.2.0", + "v8flags": "2.1.1", + "vinyl-fs": "0.3.14" + }, + "dependencies": { + "semver": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", + "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", + "dev": true + } + } + }, + "gulp-chmod": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/gulp-chmod/-/gulp-chmod-2.0.0.tgz", + "integrity": "sha1-AMOQuSigeZslGsz2MaoJ4BzGKZw=", + "dev": true, + "requires": { + "deep-assign": "1.0.0", + "stat-mode": "0.2.2", + "through2": "2.0.3" + } + }, + "gulp-debounced-watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/gulp-debounced-watch/-/gulp-debounced-watch-1.0.4.tgz", + "integrity": "sha1-WkfU4kzkY2XOguysMqKjA+QysSo=", + "dev": true, + "requires": { + "debounce-hashed": "0.1.2", + "gulp-watch": "4.3.11", + "object-assign": "3.0.0" + } + }, + "gulp-filter": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/gulp-filter/-/gulp-filter-5.0.1.tgz", + "integrity": "sha512-5olRzAhFdXB2klCu1lnazP65aO9YdA/5WfC9VdInIc8PrUeDIoZfaA3Edb0yUBGhVdHv4eHKL9Fg5tUoEJ9z5A==", + "dev": true, + "requires": { + "gulp-util": "3.0.8", + "multimatch": "2.1.0", + "streamfilter": "1.0.6" + } + }, + "gulp-gitmodified": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/gulp-gitmodified/-/gulp-gitmodified-1.1.1.tgz", + "integrity": "sha1-hfNnWRXB1RtmgH8o3g67WR5+nfQ=", + "dev": true, + "requires": { + "gulp-util": "2.2.20", + "lodash.find": "3.2.1", + "through2": "2.0.3", + "vinyl": "0.4.6", + "which": "1.0.9" + }, + "dependencies": { + "ansi-regex": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", + "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", + "dev": true + }, + "ansi-styles": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", + "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", + "dev": true + }, + "chalk": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", + "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", + "dev": true, + "requires": { + "ansi-styles": "1.1.0", + "escape-string-regexp": "1.0.5", + "has-ansi": "0.1.0", + "strip-ansi": "0.3.0", + "supports-color": "0.2.0" + } + }, + "clone": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", + "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", + "dev": true + }, + "dateformat": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", + "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", + "dev": true, + "requires": { + "get-stdin": "4.0.1", + "meow": "3.7.0" + } + }, + "gulp-util": { + "version": "2.2.20", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-2.2.20.tgz", + "integrity": "sha1-1xRuVyiRC9jwR6awseVJvCLb1kw=", + "dev": true, + "requires": { + "chalk": "0.5.1", + "dateformat": "1.0.12", + "lodash._reinterpolate": "2.4.1", + "lodash.template": "2.4.1", + "minimist": "0.2.0", + "multipipe": "0.1.2", + "through2": "0.5.1", + "vinyl": "0.2.3" + }, + "dependencies": { + "through2": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz", + "integrity": "sha1-390BLrnHAOIyP9M084rGIqs3Lac=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "3.0.0" + } + }, + "vinyl": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.2.3.tgz", + "integrity": "sha1-vKk4IJWC7FpJrVOKAPofEl5RMlI=", + "dev": true, + "requires": { + "clone-stats": "0.0.1" + } + } + } + }, + "has-ansi": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", + "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", + "dev": true, + "requires": { + "ansi-regex": "0.2.1" + } + }, + "lodash._reinterpolate": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz", + "integrity": "sha1-TxInqlqHEfxjL1sHofRgequLMiI=", + "dev": true + }, + "lodash.escape": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz", + "integrity": "sha1-LOEsXghNsKV92l5dHu659dF1o7Q=", + "dev": true, + "requires": { + "lodash._escapehtmlchar": "2.4.1", + "lodash._reunescapedhtml": "2.4.1", + "lodash.keys": "2.4.1" + } + }, + "lodash.keys": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", + "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", + "dev": true, + "requires": { + "lodash._isnative": "2.4.1", + "lodash._shimkeys": "2.4.1", + "lodash.isobject": "2.4.1" + } + }, + "lodash.template": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-2.4.1.tgz", + "integrity": "sha1-nmEQB+32KRKal0qzxIuBez4c8g0=", + "dev": true, + "requires": { + "lodash._escapestringchar": "2.4.1", + "lodash._reinterpolate": "2.4.1", + "lodash.defaults": "2.4.1", + "lodash.escape": "2.4.1", + "lodash.keys": "2.4.1", + "lodash.templatesettings": "2.4.1", + "lodash.values": "2.4.1" + } + }, + "lodash.templatesettings": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz", + "integrity": "sha1-6nbHXRHrhtTb6JqDiTu4YZKaxpk=", + "dev": true, + "requires": { + "lodash._reinterpolate": "2.4.1", + "lodash.escape": "2.4.1" + } + }, + "minimist": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz", + "integrity": "sha1-Tf/lJdriuGTGbC4jxicdev3s784=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "strip-ansi": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", + "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", + "dev": true, + "requires": { + "ansi-regex": "0.2.1" + } + }, + "supports-color": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", + "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", + "dev": true + }, + "vinyl": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", + "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", + "dev": true, + "requires": { + "clone": "0.2.0", + "clone-stats": "0.0.1" + } + }, + "which": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz", + "integrity": "sha1-RgwdoPgQED0DIam2M6+eV15kSG8=", + "dev": true + }, + "xtend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", + "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", + "dev": true + } + } + }, + "gulp-gunzip": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulp-gunzip/-/gulp-gunzip-1.0.0.tgz", + "integrity": "sha1-FbdBFF6Dqcb1CIYkG1fMWHHxUak=", + "dev": true, + "requires": { + "through2": "0.6.5", + "vinyl": "0.4.6" + }, + "dependencies": { + "clone": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", + "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + } + }, + "vinyl": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", + "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", + "dev": true, + "requires": { + "clone": "0.2.0", + "clone-stats": "0.0.1" + } + } + } + }, + "gulp-remote-src": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/gulp-remote-src/-/gulp-remote-src-0.4.3.tgz", + "integrity": "sha1-VyjP1kNDPdSEXd7wlp8PlxoqtKE=", + "dev": true, + "requires": { + "event-stream": "3.3.4", + "node.extend": "1.1.6", + "request": "2.79.0", + "through2": "2.0.3", + "vinyl": "2.0.2" + }, + "dependencies": { + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true + }, + "request": { + "version": "2.79.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz", + "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=", + "dev": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.11.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "2.0.6", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.17", + "oauth-sign": "0.8.2", + "qs": "6.3.2", + "stringstream": "0.0.5", + "tough-cookie": "2.3.3", + "tunnel-agent": "0.4.3", + "uuid": "3.1.0" + } + }, + "vinyl": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.0.2.tgz", + "integrity": "sha1-CjcT2NTpIhxY8QyhbAEWyeJe2nw=", + "dev": true, + "requires": { + "clone": "1.0.3", + "clone-buffer": "1.0.0", + "clone-stats": "1.0.0", + "cloneable-readable": "1.0.0", + "is-stream": "1.1.0", + "remove-trailing-separator": "1.1.0", + "replace-ext": "1.0.0" + } + } + } + }, + "gulp-sourcemaps": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz", + "integrity": "sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw=", + "dev": true, + "requires": { + "convert-source-map": "1.5.1", + "graceful-fs": "4.1.11", + "strip-bom": "2.0.0", + "through2": "2.0.3", + "vinyl": "1.2.0" + }, + "dependencies": { + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dev": true, + "requires": { + "clone": "1.0.3", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + } + } + }, + "gulp-symdest": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/gulp-symdest/-/gulp-symdest-1.1.0.tgz", + "integrity": "sha1-wWUyBzLRks5W/ZQnH/oSMjS/KuA=", + "dev": true, + "requires": { + "event-stream": "3.3.4", + "mkdirp": "0.5.1", + "queue": "3.1.0", + "vinyl-fs": "2.4.4" + }, + "dependencies": { + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.3.3", + "path-is-absolute": "1.0.1" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "3.1.0", + "path-dirname": "1.0.2" + } + }, + "glob-stream": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", + "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", + "dev": true, + "requires": { + "extend": "3.0.1", + "glob": "5.0.15", + "glob-parent": "3.1.0", + "micromatch": "2.3.11", + "ordered-read-streams": "0.3.0", + "through2": "0.6.5", + "to-absolute-glob": "0.1.1", + "unique-stream": "2.2.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + } + } + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "ordered-read-streams": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", + "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", + "dev": true, + "requires": { + "is-stream": "1.1.0", + "readable-stream": "2.3.3" + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + }, + "strip-bom-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz", + "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=", + "dev": true, + "requires": { + "first-chunk-stream": "1.0.0", + "strip-bom": "2.0.0" + } + }, + "unique-stream": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", + "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", + "dev": true, + "requires": { + "json-stable-stringify": "1.0.1", + "through2-filter": "2.0.0" + } + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dev": true, + "requires": { + "clone": "1.0.3", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + }, + "vinyl-fs": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", + "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", + "dev": true, + "requires": { + "duplexify": "3.5.1", + "glob-stream": "5.3.5", + "graceful-fs": "4.1.11", + "gulp-sourcemaps": "1.6.0", + "is-valid-glob": "0.3.0", + "lazystream": "1.0.0", + "lodash.isequal": "4.5.0", + "merge-stream": "1.0.1", + "mkdirp": "0.5.1", + "object-assign": "4.1.1", + "readable-stream": "2.3.3", + "strip-bom": "2.0.0", + "strip-bom-stream": "1.0.0", + "through2": "2.0.3", + "through2-filter": "2.0.0", + "vali-date": "1.0.0", + "vinyl": "1.2.0" + } + } + } + }, + "gulp-typescript": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-3.2.3.tgz", + "integrity": "sha512-Np2sJXgtDUwIAoMtlJ9uXsVmpu1FWXlKZw164hLuo56uJa7qo5W2KZ0yAYiYH/HUsaz5L0O2toMOcLIokpFCPg==", + "dev": true, + "requires": { + "gulp-util": "3.0.8", + "source-map": "0.5.7", + "through2": "2.0.3", + "vinyl-fs": "2.4.4" + }, + "dependencies": { + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.3.3", + "path-is-absolute": "1.0.1" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "3.1.0", + "path-dirname": "1.0.2" + } + }, + "glob-stream": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", + "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", + "dev": true, + "requires": { + "extend": "3.0.1", + "glob": "5.0.15", + "glob-parent": "3.1.0", + "micromatch": "2.3.11", + "ordered-read-streams": "0.3.0", + "through2": "0.6.5", + "to-absolute-glob": "0.1.1", + "unique-stream": "2.2.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + } + } + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "ordered-read-streams": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", + "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", + "dev": true, + "requires": { + "is-stream": "1.1.0", + "readable-stream": "2.3.3" + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + }, + "strip-bom-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz", + "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=", + "dev": true, + "requires": { + "first-chunk-stream": "1.0.0", + "strip-bom": "2.0.0" + } + }, + "unique-stream": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", + "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", + "dev": true, + "requires": { + "json-stable-stringify": "1.0.1", + "through2-filter": "2.0.0" + } + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dev": true, + "requires": { + "clone": "1.0.3", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + }, + "vinyl-fs": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", + "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", + "dev": true, + "requires": { + "duplexify": "3.5.1", + "glob-stream": "5.3.5", + "graceful-fs": "4.1.11", + "gulp-sourcemaps": "1.6.0", + "is-valid-glob": "0.3.0", + "lazystream": "1.0.0", + "lodash.isequal": "4.5.0", + "merge-stream": "1.0.1", + "mkdirp": "0.5.1", + "object-assign": "4.1.1", + "readable-stream": "2.3.3", + "strip-bom": "2.0.0", + "strip-bom-stream": "1.0.0", + "through2": "2.0.3", + "through2-filter": "2.0.0", + "vali-date": "1.0.0", + "vinyl": "1.2.0" + } + } + } + }, + "gulp-untar": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/gulp-untar/-/gulp-untar-0.0.6.tgz", + "integrity": "sha1-1r3v3n6ajgVMnxYjhaB4LEvnQAA=", + "dev": true, + "requires": { + "event-stream": "3.3.4", + "gulp-util": "3.0.8", + "streamifier": "0.1.1", + "tar": "2.2.1", + "through2": "2.0.3" + } + }, + "gulp-util": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", + "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", + "dev": true, + "requires": { + "array-differ": "1.0.0", + "array-uniq": "1.0.3", + "beeper": "1.1.1", + "chalk": "1.1.3", + "dateformat": "2.2.0", + "fancy-log": "1.3.0", + "gulplog": "1.0.0", + "has-gulplog": "0.1.0", + "lodash._reescape": "3.0.0", + "lodash._reevaluate": "3.0.0", + "lodash._reinterpolate": "3.0.0", + "lodash.template": "3.6.2", + "minimist": "1.2.0", + "multipipe": "0.1.2", + "object-assign": "3.0.0", + "replace-ext": "0.0.1", + "through2": "2.0.3", + "vinyl": "0.5.3" + } + }, + "gulp-vinyl-zip": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/gulp-vinyl-zip/-/gulp-vinyl-zip-2.1.0.tgz", + "integrity": "sha1-JOQGhdwFtxSZlSRQmeBZAmO+ja0=", + "dev": true, + "requires": { + "event-stream": "3.3.4", + "queue": "4.4.2", + "through2": "2.0.3", + "vinyl": "2.1.0", + "vinyl-fs": "2.4.4", + "yauzl": "2.9.1", + "yazl": "2.4.3" + }, + "dependencies": { + "clone": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", + "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", + "dev": true + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.3.3", + "path-is-absolute": "1.0.1" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "3.1.0", + "path-dirname": "1.0.2" + } + }, + "glob-stream": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", + "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", + "dev": true, + "requires": { + "extend": "3.0.1", + "glob": "5.0.15", + "glob-parent": "3.1.0", + "micromatch": "2.3.11", + "ordered-read-streams": "0.3.0", + "through2": "0.6.5", + "to-absolute-glob": "0.1.1", + "unique-stream": "2.2.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + } + } + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "ordered-read-streams": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", + "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", + "dev": true, + "requires": { + "is-stream": "1.1.0", + "readable-stream": "2.3.3" + } + }, + "queue": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/queue/-/queue-4.4.2.tgz", + "integrity": "sha512-fSMRXbwhMwipcDZ08enW2vl+YDmAmhcNcr43sCJL8DIg+CFOsoRLG23ctxA+fwNk1w55SePSiS7oqQQSgQoVJQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + }, + "strip-bom-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz", + "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=", + "dev": true, + "requires": { + "first-chunk-stream": "1.0.0", + "strip-bom": "2.0.0" + } + }, + "unique-stream": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", + "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", + "dev": true, + "requires": { + "json-stable-stringify": "1.0.1", + "through2-filter": "2.0.0" + } + }, + "vinyl": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz", + "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=", + "dev": true, + "requires": { + "clone": "2.1.1", + "clone-buffer": "1.0.0", + "clone-stats": "1.0.0", + "cloneable-readable": "1.0.0", + "remove-trailing-separator": "1.1.0", + "replace-ext": "1.0.0" + } + }, + "vinyl-fs": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", + "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", + "dev": true, + "requires": { + "duplexify": "3.5.1", + "glob-stream": "5.3.5", + "graceful-fs": "4.1.11", + "gulp-sourcemaps": "1.6.0", + "is-valid-glob": "0.3.0", + "lazystream": "1.0.0", + "lodash.isequal": "4.5.0", + "merge-stream": "1.0.1", + "mkdirp": "0.5.1", + "object-assign": "4.1.1", + "readable-stream": "2.3.3", + "strip-bom": "2.0.0", + "strip-bom-stream": "1.0.0", + "through2": "2.0.3", + "through2-filter": "2.0.0", + "vali-date": "1.0.0", + "vinyl": "1.2.0" + }, + "dependencies": { + "clone": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz", + "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=", + "dev": true + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dev": true, + "requires": { + "clone": "1.0.3", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + } + } + } + } + }, + "gulp-watch": { + "version": "4.3.11", + "resolved": "https://registry.npmjs.org/gulp-watch/-/gulp-watch-4.3.11.tgz", + "integrity": "sha1-Fi/FY96fx3DpH5p845VVE6mhGMA=", + "dev": true, + "requires": { + "anymatch": "1.3.2", + "chokidar": "1.7.0", + "glob-parent": "3.1.0", + "gulp-util": "3.0.8", + "object-assign": "4.1.1", + "path-is-absolute": "1.0.1", + "readable-stream": "2.3.3", + "slash": "1.0.0", + "vinyl": "1.2.0", + "vinyl-file": "2.0.0" + }, + "dependencies": { + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "3.1.0", + "path-dirname": "1.0.2" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dev": true, + "requires": { + "clone": "1.0.3", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + } + } + }, + "gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "dev": true, + "requires": { + "glogg": "1.0.0" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "commander": "2.12.2", + "is-my-json-valid": "2.16.1", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "commander": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz", + "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==", + "dev": true + } + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "dev": true, + "requires": { + "sparkles": "1.0.0" + } + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "dev": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "dev": true + }, + "homedir-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", + "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "dev": true, + "requires": { + "parse-passwd": "1.0.0" + } + }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "dev": true + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "dev": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" + } + }, + "husky": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-0.14.3.tgz", + "integrity": "sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA==", + "dev": true, + "requires": { + "is-ci": "1.0.10", + "normalize-path": "1.0.0", + "strip-indent": "2.0.0" + }, + "dependencies": { + "normalize-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz", + "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=", + "dev": true + }, + "strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true + } + } + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.3.3", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "inversify": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/inversify/-/inversify-4.5.2.tgz", + "integrity": "sha512-nyXPqxMVdJDCbeq+eWSq5wEYvm6jlBNkBS+rMAXdxlEibAIXuzXXNgvETsP0MVcsWc4bAwUMhqr6X/5sUzNrFw==" + }, + "is": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is/-/is-3.2.1.tgz", + "integrity": "sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU=", + "dev": true + }, + "is-absolute": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz", + "integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=", + "dev": true, + "requires": { + "is-relative": "0.2.1", + "is-windows": "0.2.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "1.11.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-ci": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", + "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", + "dev": true, + "requires": { + "ci-info": "1.1.2" + } + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "requires": { + "is-primitive": "2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "is-my-json-valid": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz", + "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==", + "dev": true, + "requires": { + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, + "is-relative": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz", + "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=", + "dev": true, + "requires": { + "is-unc-path": "0.1.2" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-unc-path": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz", + "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=", + "dev": true, + "requires": { + "unc-path-regex": "0.1.2" + } + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-valid-glob": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-0.3.0.tgz", + "integrity": "sha1-1LVcafUYhvm2XHDWwmItN+KfSP4=", + "dev": true + }, + "is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "jade": { + "version": "0.26.3", + "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", + "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=", + "dev": true, + "requires": { + "commander": "0.6.1", + "mkdirp": "0.3.0" + }, + "dependencies": { + "commander": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", + "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=", + "dev": true + }, + "mkdirp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", + "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=", + "dev": true + } + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "4.1.11" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dev": true, + "requires": { + "readable-stream": "2.3.3" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "liftoff": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.3.0.tgz", + "integrity": "sha1-qY8v9nGD2Lp8+soQVIvX/wVQs4U=", + "dev": true, + "requires": { + "extend": "3.0.1", + "findup-sync": "0.4.3", + "fined": "1.1.0", + "flagged-respawn": "0.3.2", + "lodash.isplainobject": "4.0.6", + "lodash.isstring": "4.0.1", + "lodash.mapvalues": "4.6.0", + "rechoir": "0.6.2", + "resolve": "1.5.0" + } + }, + "line-by-line": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/line-by-line/-/line-by-line-0.1.5.tgz", + "integrity": "sha1-GcRbWfCoBjLDC1xDpkf+Faq5BcI=" + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + } + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + }, + "lodash._basecallback": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/lodash._basecallback/-/lodash._basecallback-3.3.1.tgz", + "integrity": "sha1-t7K7Q9whYEJKIczybFfkQ3cqjic=", + "dev": true, + "requires": { + "lodash._baseisequal": "3.0.7", + "lodash._bindcallback": "3.0.1", + "lodash.isarray": "3.0.4", + "lodash.pairs": "3.0.1" + } + }, + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "lodash._baseeach": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash._baseeach/-/lodash._baseeach-3.0.4.tgz", + "integrity": "sha1-z4cGVyyhROjZ11InyZDamC+TKvM=", + "dev": true, + "requires": { + "lodash.keys": "3.1.2" + } + }, + "lodash._basefind": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basefind/-/lodash._basefind-3.0.0.tgz", + "integrity": "sha1-srugXMZF+XLeLPkl+iv2Og9gyK4=", + "dev": true + }, + "lodash._basefindindex": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/lodash._basefindindex/-/lodash._basefindindex-3.6.0.tgz", + "integrity": "sha1-8IM2ChsCJBjtgbyJm+sxLiHnSk8=", + "dev": true + }, + "lodash._baseisequal": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/lodash._baseisequal/-/lodash._baseisequal-3.0.7.tgz", + "integrity": "sha1-2AJfdjOdKTQnZ9zIh85cuVpbUfE=", + "dev": true, + "requires": { + "lodash.isarray": "3.0.4", + "lodash.istypedarray": "3.0.6", + "lodash.keys": "3.1.2" + } + }, + "lodash._basetostring": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", + "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", + "dev": true + }, + "lodash._basevalues": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", + "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", + "dev": true + }, + "lodash._bindcallback": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", + "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=", + "dev": true + }, + "lodash._escapehtmlchar": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz", + "integrity": "sha1-32fDu2t+jh6DGrSL+geVuSr+iZ0=", + "dev": true, + "requires": { + "lodash._htmlescapes": "2.4.1" + } + }, + "lodash._escapestringchar": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz", + "integrity": "sha1-7P4iYYoq3lC/7qQ5N+Ud9m8O23I=", + "dev": true + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash._htmlescapes": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz", + "integrity": "sha1-MtFL8IRLbeb4tioFG09nwii2JMs=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "lodash._isnative": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz", + "integrity": "sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw=", + "dev": true + }, + "lodash._objecttypes": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz", + "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=", + "dev": true + }, + "lodash._reescape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", + "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", + "dev": true + }, + "lodash._reevaluate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", + "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", + "dev": true + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash._reunescapedhtml": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz", + "integrity": "sha1-dHxPxAED6zu4oJduVx96JlnpO6c=", + "dev": true, + "requires": { + "lodash._htmlescapes": "2.4.1", + "lodash.keys": "2.4.1" + }, + "dependencies": { + "lodash.keys": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", + "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", + "dev": true, + "requires": { + "lodash._isnative": "2.4.1", + "lodash._shimkeys": "2.4.1", + "lodash.isobject": "2.4.1" + } + } + } + }, + "lodash._root": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", + "dev": true + }, + "lodash._shimkeys": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz", + "integrity": "sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM=", + "dev": true, + "requires": { + "lodash._objecttypes": "2.4.1" + } + }, + "lodash.defaults": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-2.4.1.tgz", + "integrity": "sha1-p+iIXwXmiFEUS24SqPNngCa8TFQ=", + "dev": true, + "requires": { + "lodash._objecttypes": "2.4.1", + "lodash.keys": "2.4.1" + }, + "dependencies": { + "lodash.keys": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", + "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", + "dev": true, + "requires": { + "lodash._isnative": "2.4.1", + "lodash._shimkeys": "2.4.1", + "lodash.isobject": "2.4.1" + } + } + } + }, + "lodash.escape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", + "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", + "dev": true, + "requires": { + "lodash._root": "3.0.1" + } + }, + "lodash.find": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/lodash.find/-/lodash.find-3.2.1.tgz", + "integrity": "sha1-BG4xnzrOkSrGySRsf2g8XsB7Nq0=", + "dev": true, + "requires": { + "lodash._basecallback": "3.3.1", + "lodash._baseeach": "3.0.4", + "lodash._basefind": "3.0.0", + "lodash._basefindindex": "3.6.0", + "lodash.isarray": "3.0.4", + "lodash.keys": "3.1.2" + } + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", + "dev": true + }, + "lodash.isobject": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz", + "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=", + "dev": true, + "requires": { + "lodash._objecttypes": "2.4.1" + } + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", + "dev": true + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", + "dev": true + }, + "lodash.istypedarray": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz", + "integrity": "sha1-yaR3SYYHUB2OhJTSg7h8OSgc72I=", + "dev": true + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "3.9.1", + "lodash.isarguments": "3.1.0", + "lodash.isarray": "3.0.4" + } + }, + "lodash.mapvalues": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", + "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=", + "dev": true + }, + "lodash.pairs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash.pairs/-/lodash.pairs-3.0.1.tgz", + "integrity": "sha1-u+CNV4bu6qCaFckevw3LfSvjJqk=", + "dev": true, + "requires": { + "lodash.keys": "3.1.2" + } + }, + "lodash.restparam": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", + "dev": true + }, + "lodash.template": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", + "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", + "dev": true, + "requires": { + "lodash._basecopy": "3.0.1", + "lodash._basetostring": "3.0.1", + "lodash._basevalues": "3.0.0", + "lodash._isiterateecall": "3.0.9", + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0", + "lodash.keys": "3.1.2", + "lodash.restparam": "3.6.1", + "lodash.templatesettings": "3.1.1" + } + }, + "lodash.templatesettings": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", + "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", + "dev": true, + "requires": { + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0" + } + }, + "lodash.values": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-2.4.1.tgz", + "integrity": "sha1-q/UUQ2s8twUAFieXjLzzCxKA7qQ=", + "dev": true, + "requires": { + "lodash.keys": "2.4.1" + }, + "dependencies": { + "lodash.keys": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", + "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", + "dev": true, + "requires": { + "lodash._isnative": "2.4.1", + "lodash._shimkeys": "2.4.1", + "lodash.isobject": "2.4.1" + } + } + } + }, + "lolex": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz", + "integrity": "sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY=", + "dev": true + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" + } + }, + "lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", + "dev": true + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", + "dev": true + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.4.0", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" + }, + "dependencies": { + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + } + } + }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "dev": true, + "requires": { + "readable-stream": "2.3.3" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" + } + }, + "mime-db": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", + "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=", + "dev": true + }, + "mime-types": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", + "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "dev": true, + "requires": { + "mime-db": "1.30.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } + } + }, + "mocha": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-2.5.3.tgz", + "integrity": "sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg=", + "dev": true, + "requires": { + "commander": "2.3.0", + "debug": "2.2.0", + "diff": "1.4.0", + "escape-string-regexp": "1.0.2", + "glob": "3.2.11", + "growl": "1.9.2", + "jade": "0.26.3", + "mkdirp": "0.5.1", + "supports-color": "1.2.0", + "to-iso-string": "0.0.2" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz", + "integrity": "sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE=", + "dev": true + }, + "glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimatch": "0.3.0" + } + }, + "minimatch": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", + "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", + "dev": true, + "requires": { + "lru-cache": "2.7.3", + "sigmund": "1.0.1" + } + }, + "supports-color": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz", + "integrity": "sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4=", + "dev": true + } + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + }, + "multimatch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "dev": true, + "requires": { + "array-differ": "1.0.0", + "array-union": "1.0.2", + "arrify": "1.0.1", + "minimatch": "3.0.4" + } + }, + "multipipe": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "dev": true, + "requires": { + "duplexer2": "0.0.2" + } + }, + "named-js-regexp": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/named-js-regexp/-/named-js-regexp-1.3.3.tgz", + "integrity": "sha512-zIUAXzGQOp16VR0Ct89SDstU62hzAPBluNUrUrsdD7MNSRbm/vyqGhEnp+4hnsMjmX3C2wh1cbIEP0joKMFLxw==" + }, + "nan": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz", + "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=", + "dev": true, + "optional": true + }, + "native-promise-only": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", + "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", + "dev": true + }, + "natives": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.0.tgz", + "integrity": "sha1-6f+EFBimsux6SV6TmYT3jxY+bjE=", + "dev": true + }, + "node.extend": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-1.1.6.tgz", + "integrity": "sha1-p7iCyC1sk6SGOlUEvV3o7IYli5Y=", + "dev": true, + "requires": { + "is": "3.2.1" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "2.5.0", + "is-builtin-module": "1.0.0", + "semver": "5.4.1", + "validate-npm-package-license": "3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "1.1.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "dev": true + }, + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", + "dev": true + }, + "object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, + "requires": { + "array-each": "1.0.1", + "array-slice": "1.1.0", + "for-own": "1.0.0", + "isobject": "3.0.1" + }, + "dependencies": { + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "1.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "orchestrator": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz", + "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=", + "dev": true, + "requires": { + "end-of-stream": "0.1.5", + "sequencify": "0.0.7", + "stream-consume": "0.1.0" + } + }, + "ordered-read-streams": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz", + "integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "parse-filepath": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.1.tgz", + "integrity": "sha1-FZ1hVdQ5BNFsEO9piRHaHpGWm3M=", + "dev": true, + "requires": { + "is-absolute": "0.2.6", + "map-cache": "0.2.2", + "path-root": "0.1.1" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "1.3.1" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, + "requires": { + "path-root-regex": "0.1.2" + } + }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", + "dev": true, + "requires": { + "through": "2.3.8" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "qs": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", + "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=", + "dev": true + }, + "querystringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-1.0.0.tgz", + "integrity": "sha1-YoYkIRLFtxL6ZU5SZlK/ahP/Bcs=", + "dev": true + }, + "queue": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/queue/-/queue-3.1.0.tgz", + "integrity": "sha1-bEnQHwCeIlZ4h4nyv/rGuLmZBYU=", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "randomatic": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + } + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "readable-stream": "2.3.3", + "set-immediate-shim": "1.0.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "1.5.0" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "2.1.0", + "strip-indent": "1.0.1" + } + }, + "reflect-metadata": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.10.tgz", + "integrity": "sha1-tPg3BEFqytiZiMmxVjXUfgO5NEo=" + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "requires": { + "is-equal-shallow": "0.1.3" + } + }, + "relative": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/relative/-/relative-3.0.2.tgz", + "integrity": "sha1-Dc2OxUpdNaPBXhBFA9ZTdbWlNn8=", + "dev": true, + "requires": { + "isobject": "2.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "1.0.2" + } + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true + }, + "request": { + "version": "2.83.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", + "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", + "dev": true, + "requires": { + "aws-sign2": "0.7.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.3.1", + "har-validator": "5.0.3", + "hawk": "6.0.2", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.17", + "oauth-sign": "0.8.2", + "performance-now": "2.1.0", + "qs": "6.5.1", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.3", + "tunnel-agent": "0.6.0", + "uuid": "3.1.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "boom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", + "dev": true, + "requires": { + "hoek": "4.2.0" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "cryptiles": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", + "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", + "dev": true, + "requires": { + "boom": "5.2.0" + }, + "dependencies": { + "boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "dev": true, + "requires": { + "hoek": "4.2.0" + } + } + } + }, + "form-data": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", + "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", + "dev": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.17" + } + }, + "har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "dev": true, + "requires": { + "ajv": "5.5.1", + "har-schema": "2.0.0" + } + }, + "hawk": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "dev": true, + "requires": { + "boom": "4.3.1", + "cryptiles": "3.1.2", + "hoek": "4.2.0", + "sntp": "2.1.0" + } + }, + "hoek": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", + "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==", + "dev": true + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" + } + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "dev": true + }, + "sntp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", + "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "dev": true, + "requires": { + "hoek": "4.2.0" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", + "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", + "dev": true, + "requires": { + "path-parse": "1.0.5" + } + }, + "resolve-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", + "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", + "dev": true, + "requires": { + "expand-tilde": "1.2.2", + "global-modules": "0.2.3" + } + }, + "retyped-diff-match-patch-tsd-ambient": { + "version": "1.0.0-1", + "resolved": "https://registry.npmjs.org/retyped-diff-match-patch-tsd-ambient/-/retyped-diff-match-patch-tsd-ambient-1.0.0-1.tgz", + "integrity": "sha1-Jkgr9JFcftn4MAu1y+xI/U/1vGI=", + "dev": true + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "7.1.2" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.3.3", + "path-is-absolute": "1.0.1" + } + } + } + }, + "rxjs": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.3.tgz", + "integrity": "sha512-VWockSz7xmDveeZ7wv8RvdipGGZ1NmL/m4jnpvN9BH4x1fW/TPoD23yXh+qDkbWSlajXVVfLIbGmyxa94Ls84w==", + "requires": { + "symbol-observable": "1.1.0" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + }, + "samsam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", + "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", + "dev": true + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" + }, + "sequencify": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz", + "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=", + "dev": true + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "sinon": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-2.4.1.tgz", + "integrity": "sha512-vFTrO9Wt0ECffDYIPSP/E5bBugt0UjcBQOfQUMh66xzkyPEnhl/vM2LRZi2ajuTdkH07sA6DzrM6KvdvGIH8xw==", + "dev": true, + "requires": { + "diff": "3.4.0", + "formatio": "1.2.0", + "lolex": "1.6.0", + "native-promise-only": "0.8.1", + "path-to-regexp": "1.7.0", + "samsam": "1.3.0", + "text-encoding": "0.6.4", + "type-detect": "4.0.5" + }, + "dependencies": { + "diff": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz", + "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==", + "dev": true + } + } + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-support": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.0.tgz", + "integrity": "sha512-vUoN3I7fHQe0R/SJLKRdKYuEdRGogsviXFkHHo17AWaTGv17VLnxw+CFXvqy+y4ORZ3doWLQcxRYfwKrsd/H7Q==", + "dev": true, + "requires": { + "source-map": "0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "sparkles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", + "dev": true + }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true, + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, + "split": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", + "dev": true, + "requires": { + "through": "2.3.8" + } + }, + "sshpk": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", + "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "dev": true, + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "stat-mode": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-0.2.2.tgz", + "integrity": "sha1-5sgLYjEj19gM8TLOU480YokHJQI=", + "dev": true + }, + "stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", + "dev": true, + "requires": { + "duplexer": "0.1.1" + } + }, + "stream-consume": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz", + "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=", + "dev": true + }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "dev": true + }, + "streamfilter": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/streamfilter/-/streamfilter-1.0.6.tgz", + "integrity": "sha512-JM3zxd/lvOuo+EZJlZNYdQucfybA+Jr6jRtZwWlMAq1dAV0LIjZrqSNBBK62qCtflJ8rL/+cAnxy69CPhkTJNA==", + "dev": true, + "requires": { + "readable-stream": "2.3.3" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "streamifier": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/streamifier/-/streamifier-0.1.1.tgz", + "integrity": "sha1-l+mNj6TRBdYqJpHR3AfoINuN/E8=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-bom": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz", + "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=", + "dev": true, + "requires": { + "first-chunk-stream": "1.0.0", + "is-utf8": "0.2.1" + } + }, + "strip-bom-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz", + "integrity": "sha1-+H217yYT9paKpUWr/h7HKLaoKco=", + "dev": true, + "requires": { + "first-chunk-stream": "2.0.0", + "strip-bom": "2.0.0" + }, + "dependencies": { + "first-chunk-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz", + "integrity": "sha1-G97NuOCDwGZLkZRVgVd6Q6nzHXA=", + "dev": true, + "requires": { + "readable-stream": "2.3.3" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + } + } + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "4.0.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "symbol-observable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.1.0.tgz", + "integrity": "sha512-dQoid9tqQ+uotGhuTKEY11X4xhyYePVnqGSoSm3OGKh2E8LZ6RPULp1uXTctk33IeERlrRJYoVSBglsL05F5Uw==" + }, + "tar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "dev": true, + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" + } + }, + "text-encoding": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "2.3.3", + "xtend": "4.0.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "through2-filter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz", + "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=", + "dev": true, + "requires": { + "through2": "2.0.3", + "xtend": "4.0.1" + } + }, + "tildify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", + "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", + "dev": true, + "requires": { + "os-homedir": "1.0.2" + } + }, + "time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", + "dev": true + }, + "tmp": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.29.tgz", + "integrity": "sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA=", + "requires": { + "os-tmpdir": "1.0.2" + } + }, + "to-absolute-glob": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz", + "integrity": "sha1-HN+kcqnvUMI57maZm2YsoOs5k38=", + "dev": true, + "requires": { + "extend-shallow": "2.0.1" + } + }, + "to-iso-string": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/to-iso-string/-/to-iso-string-0.0.2.tgz", + "integrity": "sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE=", + "dev": true + }, + "tough-cookie": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", + "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "dev": true, + "requires": { + "punycode": "1.4.1" + } + }, + "tree-kill": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.0.tgz", + "integrity": "sha512-DlX6dR0lOIRDFxI0mjL9IYg6OTncLm/Zt+JiBhE5OlFcAR8yc9S7FFXU9so0oda47frdM/JFsk7UjNt9vscKcg==" + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "tslib": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.8.0.tgz", + "integrity": "sha512-ymKWWZJST0/CkgduC2qkzjMOWr4bouhuURNXCn/inEX0L57BnRG6FhX76o7FOnsjHazCjfU2LKeSrlS2sIKQJg==", + "dev": true + }, + "tslint": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", + "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", + "dev": true, + "requires": { + "babel-code-frame": "6.26.0", + "builtin-modules": "1.1.1", + "chalk": "2.3.0", + "commander": "2.12.2", + "diff": "3.4.0", + "glob": "7.1.2", + "minimatch": "3.0.4", + "resolve": "1.5.0", + "semver": "5.4.1", + "tslib": "1.8.0", + "tsutils": "2.13.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "commander": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz", + "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==", + "dev": true + }, + "diff": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz", + "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.3.3", + "path-is-absolute": "1.0.1" + } + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "tslint-eslint-rules": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tslint-eslint-rules/-/tslint-eslint-rules-4.1.1.tgz", + "integrity": "sha1-fDDniC8mvCdr/5HSOEl1xp2viLo=", + "dev": true, + "requires": { + "doctrine": "0.7.2", + "tslib": "1.8.0", + "tsutils": "1.9.1" + }, + "dependencies": { + "tsutils": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-1.9.1.tgz", + "integrity": "sha1-ufmrROVa+WgYMdXyjQrur1x1DLA=", + "dev": true + } + } + }, + "tslint-microsoft-contrib": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-5.0.1.tgz", + "integrity": "sha1-Mo7pwo0HzfeTKTIEyW4v+rkiGZQ=", + "dev": true, + "requires": { + "tsutils": "1.9.1" + }, + "dependencies": { + "tsutils": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-1.9.1.tgz", + "integrity": "sha1-ufmrROVa+WgYMdXyjQrur1x1DLA=", + "dev": true + } + } + }, + "tsutils": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.13.0.tgz", + "integrity": "sha512-FuWzNJbMsp3gcZMbI3b5DomhW4Ia41vMxjN63nKWI0t7f+I3UmHfRl0TrXJTwI2LUduDG+eR1Mksp3pvtlyCFQ==", + "dev": true, + "requires": { + "tslib": "1.8.0" + } + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", + "dev": true + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true, + "optional": true + }, + "type-detect": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.5.tgz", + "integrity": "sha512-N9IvkQslUGYGC24RkJk1ba99foK6TkwC2FHAEBlQFBP0RxQZS8ZpJuAZcwiY/w9ZJHFQb1aOXBI60OdxhTrwEQ==", + "dev": true + }, + "typescript": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz", + "integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=", + "dev": true + }, + "typescript-formatter": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/typescript-formatter/-/typescript-formatter-6.1.0.tgz", + "integrity": "sha512-o2TJSBDSdua8yl8gXNJonM4jr4f7ZuLhsbG7zMG80iJluhE8MWI0R/mPzA3in3omwAJwkcbkc5Xxm74io/J7WA==", + "dev": true, + "requires": { + "commandpost": "1.2.1", + "editorconfig": "0.15.0" + } + }, + "uint64be": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uint64be/-/uint64be-1.0.1.tgz", + "integrity": "sha1-H3FUIC8qG4rzU4cd2mUb80zpPpU=" + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, + "unique-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", + "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=", + "dev": true + }, + "universalify": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", + "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=" + }, + "untildify": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-3.0.2.tgz", + "integrity": "sha1-fx8wIFWz/qDz6B3HjrNnZstl4/E=" + }, + "url-parse": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.2.0.tgz", + "integrity": "sha512-DT1XbYAfmQP65M/mE6OALxmXzZ/z1+e5zk2TcSKe/KiYbNGZxgtttzC0mR/sjopbpOXcbniq7eIKmocJnUWlEw==", + "dev": true, + "requires": { + "querystringify": "1.0.0", + "requires-port": "1.0.0" + } + }, + "user-home": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", + "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", + "dev": true + }, + "v8flags": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", + "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", + "dev": true, + "requires": { + "user-home": "1.1.1" + } + }, + "vali-date": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz", + "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "1.3.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "vinyl": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", + "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", + "dev": true, + "requires": { + "clone": "1.0.3", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + }, + "vinyl-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vinyl-file/-/vinyl-file-2.0.0.tgz", + "integrity": "sha1-p+v1/779obfRjRQPyweyI++2dRo=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0", + "strip-bom-stream": "2.0.0", + "vinyl": "1.2.0" + }, + "dependencies": { + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dev": true, + "requires": { + "clone": "1.0.3", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + } + } + }, + "vinyl-fs": { + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz", + "integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=", + "dev": true, + "requires": { + "defaults": "1.0.3", + "glob-stream": "3.1.18", + "glob-watcher": "0.0.6", + "graceful-fs": "3.0.11", + "mkdirp": "0.5.1", + "strip-bom": "1.0.0", + "through2": "0.6.5", + "vinyl": "0.4.6" + }, + "dependencies": { + "clone": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", + "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", + "dev": true + }, + "graceful-fs": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz", + "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", + "dev": true, + "requires": { + "natives": "1.1.0" + } + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + } + }, + "vinyl": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", + "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", + "dev": true, + "requires": { + "clone": "0.2.0", + "clone-stats": "0.0.1" + } + } + } + }, + "vinyl-source-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vinyl-source-stream/-/vinyl-source-stream-1.1.0.tgz", + "integrity": "sha1-RMvlEIIFJ53rDFZTwJSiiHk4sas=", + "dev": true, + "requires": { + "through2": "0.6.5", + "vinyl": "0.4.6" + }, + "dependencies": { + "clone": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", + "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + } + }, + "vinyl": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", + "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", + "dev": true, + "requires": { + "clone": "0.2.0", + "clone-stats": "0.0.1" + } + } + } + }, + "vscode": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.9.tgz", + "integrity": "sha512-xhSh410NntYViiBYIPimAwF0U6NZgORtqQenlpTI/qKBGwHMtZSCJcL3/JIhfCw43HBXqPg59kA947OT3UvZKQ==", + "dev": true, + "requires": { + "glob": "7.1.2", + "gulp-chmod": "2.0.0", + "gulp-filter": "5.0.1", + "gulp-gunzip": "1.0.0", + "gulp-remote-src": "0.4.3", + "gulp-symdest": "1.1.0", + "gulp-untar": "0.0.6", + "gulp-vinyl-zip": "2.1.0", + "mocha": "4.0.1", + "request": "2.83.0", + "semver": "5.4.1", + "source-map-support": "0.5.0", + "url-parse": "1.2.0", + "vinyl-source-stream": "1.1.0" + }, + "dependencies": { + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "diff": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", + "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.3.3", + "path-is-absolute": "1.0.1" + } + }, + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "dev": true + }, + "mocha": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.0.1.tgz", + "integrity": "sha512-evDmhkoA+cBNiQQQdSKZa2b9+W2mpLoj50367lhy+Klnx9OV8XlCIhigUnn1gaTFLQCa0kdNhEGDr0hCXOQFDw==", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.3.1", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", + "mkdirp": "0.5.1", + "supports-color": "4.4.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "vscode-debugadapter": { + "version": "1.25.0", + "resolved": "https://registry.npmjs.org/vscode-debugadapter/-/vscode-debugadapter-1.25.0.tgz", + "integrity": "sha512-tsOtNNKKTbnQanARdkFfUxI8qKVKba+QHOKWC1reDDeeyvzoNKkLMGkL/xsiKn5vQDeaP3zFBcLY8Ysak9GrvQ==", + "requires": { + "vscode-debugprotocol": "1.25.0" + } + }, + "vscode-debugprotocol": { + "version": "1.25.0", + "resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.25.0.tgz", + "integrity": "sha512-e1EUy/5npqa0NlAwRCUu8A9LnVRf6tkwiPQcCLyUFCC9o2GxcAqH5Va4mqXDoxQ58ar3zODivKQeRb3z1KH7WA==" + }, + "vscode-extension-telemetry": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.5.tgz", + "integrity": "sha1-IeKrtMvOMybkad27MiEjs3AvP4U=", + "requires": { + "applicationinsights": "0.15.6", + "winreg": "0.0.13" + }, + "dependencies": { + "winreg": { + "version": "0.0.13", + "resolved": "https://registry.npmjs.org/winreg/-/winreg-0.0.13.tgz", + "integrity": "sha1-dr/gLh3QycgnX7n98XqfNoRuNIM=" + } + } + }, + "vscode-jsonrpc": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.5.0.tgz", + "integrity": "sha1-hyOdnhZrLXNSJFuKgTWXgEwdY6o=" + }, + "vscode-languageclient": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-3.5.0.tgz", + "integrity": "sha1-NtAswYaoNlpEZ3GaKQ+yAKmuSQo=", + "requires": { + "vscode-languageserver-protocol": "3.5.0" + } + }, + "vscode-languageserver": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-3.5.0.tgz", + "integrity": "sha1-0oCZvG3dqMHdFrcH5FThsd2uDbo=", + "requires": { + "vscode-languageserver-protocol": "3.5.0", + "vscode-uri": "1.0.1" + } + }, + "vscode-languageserver-protocol": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.5.0.tgz", + "integrity": "sha1-Bnxcvidwl5U5jRGWksl+u6FFIgk=", + "requires": { + "vscode-jsonrpc": "3.5.0", + "vscode-languageserver-types": "3.5.0" + } + }, + "vscode-languageserver-types": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.5.0.tgz", + "integrity": "sha1-5I15li8LjgLelV4/UkkI4rGcA3Q=" + }, + "vscode-uri": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.1.tgz", + "integrity": "sha1-Eahr7+rDxKo+wIYjZRo8gabQu8g=" + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "winreg": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.4.tgz", + "integrity": "sha1-ugZWKbepJRMOFXeRCM9UCZDpjRs=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "requires": { + "sax": "1.2.4", + "xmlbuilder": "9.0.4" + } + }, + "xmlbuilder": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.4.tgz", + "integrity": "sha1-UZy0ymhtAFqEINNJbz8MruzKWA8=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yauzl": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz", + "integrity": "sha1-qBmB6nCleUYTOIPwKcWCGok1mn8=", + "dev": true, + "requires": { + "buffer-crc32": "0.2.13", + "fd-slicer": "1.0.1" + } + }, + "yazl": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.4.3.tgz", + "integrity": "sha1-7CblzIfVYBud+EMtvdPNLlFzoHE=", + "dev": true, + "requires": { + "buffer-crc32": "0.2.13" + } + } + } } diff --git a/package.json b/package.json index f94a081c3bed..2290b3331645 100644 --- a/package.json +++ b/package.json @@ -1550,7 +1550,7 @@ "xml2js": "^0.4.17" }, "devDependencies": { - "@types/chai": "^4.0.4", + "@types/chai": "4.0.6", "@types/chai-as-promised": "^7.1.0", "@types/fs-extra": "^4.0.2", "@types/get-port": "^3.2.0", @@ -1566,10 +1566,12 @@ "chai": "^4.1.2", "chai-as-promised": "^7.1.1", "colors": "^1.1.2", + "debounce": "^1.1.0", "event-stream": "^3.3.4", "gulp": "^3.9.1", "gulp-debounced-watch": "^1.0.4", "gulp-filter": "^5.0.1", + "gulp-gitmodified": "^1.1.1", "gulp-typescript": "^3.2.2", "gulp-watch": "^4.3.11", "husky": "^0.14.3", @@ -1580,7 +1582,7 @@ "tslint": "^5.7.0", "tslint-eslint-rules": "^4.1.1", "tslint-microsoft-contrib": "^5.0.1", - "typescript": "^2.5.2", + "typescript": "^2.6.2", "typescript-formatter": "^6.0.0", "vscode": "^1.1.5" } diff --git a/pythonFiles/PythonTools/visualstudio_py_launcher_nodebug.py b/pythonFiles/PythonTools/visualstudio_py_launcher_nodebug.py index 79184dfa1e0d..6a526aa04a52 100644 --- a/pythonFiles/PythonTools/visualstudio_py_launcher_nodebug.py +++ b/pythonFiles/PythonTools/visualstudio_py_launcher_nodebug.py @@ -83,7 +83,7 @@ def run(file, port_num, debug_id, pid, run_as='script'): def attach_process(port_num, pid, debug_id): global conn - for i in xrange(50): + for i in range(50): try: conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) conn.connect(('127.0.0.1', port_num)) diff --git a/src/client/banner.ts b/src/client/banner.ts index 137e44b175c7..fb839d5e848e 100644 --- a/src/client/banner.ts +++ b/src/client/banner.ts @@ -3,12 +3,12 @@ import { window } from 'vscode'; import { launch } from './common/net/browser'; -import { IPersistentStateFactory, PersistentState } from './common/persistentState'; +import { IPersistentState, IPersistentStateFactory } from './common/types'; const BANNER_URL = 'https://aka.ms/pvsc-at-msft'; export class BannerService { - private shouldShowBanner: PersistentState; + private shouldShowBanner: IPersistentState; constructor(persistentStateFactory: IPersistentStateFactory) { this.shouldShowBanner = persistentStateFactory.createGlobalPersistentState('SHOW_NEW_PUBLISHER_BANNER', true); this.showBanner(); diff --git a/src/client/common/configSettings.ts b/src/client/common/configSettings.ts index c21649159419..b0111424ceb0 100644 --- a/src/client/common/configSettings.ts +++ b/src/client/common/configSettings.ts @@ -6,7 +6,7 @@ import * as path from 'path'; import * as vscode from 'vscode'; import { Uri } from 'vscode'; import { InterpreterInfoCache } from './interpreterInfoCache'; -import { SystemVariables } from './systemVariables'; +import { SystemVariables } from './variables/systemVariables'; // tslint:disable-next-line:no-require-imports no-var-requires const untildify = require('untildify'); @@ -126,9 +126,11 @@ export interface ITerminalSettings { executeInFileDir: boolean; launchArgs: string[]; } -// tslint:disable-next-line:interface-name -// tslint:disable-next-line:no-string-literal -const IS_TEST_EXECUTION = process.env['VSC_PYTHON_CI_TEST'] === '1'; + +function isTestExecution(): boolean { + // tslint:disable-next-line:interface-name no-string-literal + return process.env['VSC_PYTHON_CI_TEST'] === '1'; +} // tslint:disable-next-line:completed-docs export class PythonSettings extends EventEmitter implements IPythonSettings { @@ -151,7 +153,6 @@ export class PythonSettings extends EventEmitter implements IPythonSettings { private disposables: vscode.Disposable[] = []; // tslint:disable-next-line:variable-name private _pythonPath: string; - constructor(workspaceFolder?: Uri) { super(); this.workspaceRoot = workspaceFolder ? workspaceFolder : vscode.Uri.file(__dirname); @@ -178,7 +179,7 @@ export class PythonSettings extends EventEmitter implements IPythonSettings { } // tslint:disable-next-line:function-name public static dispose() { - if (!IS_TEST_EXECUTION) { + if (!isTestExecution()) { throw new Error('Dispose can only be called from unit tests'); } // tslint:disable-next-line:no-void-expression @@ -332,7 +333,7 @@ export class PythonSettings extends EventEmitter implements IPythonSettings { Object.assign(this.unitTest, unitTestSettings); } else { this.unitTest = unitTestSettings; - if (IS_TEST_EXECUTION && !this.unitTest) { + if (isTestExecution() && !this.unitTest) { // tslint:disable-next-line:prefer-type-cast this.unitTest = { nosetestArgs: [], pyTestArgs: [], unittestArgs: [], @@ -369,7 +370,7 @@ export class PythonSettings extends EventEmitter implements IPythonSettings { Object.assign(this.terminal, terminalSettings); } else { this.terminal = terminalSettings; - if (IS_TEST_EXECUTION && !this.terminal) { + if (isTestExecution() && !this.terminal) { // tslint:disable-next-line:prefer-type-cast this.terminal = {} as ITerminalSettings; } @@ -405,7 +406,7 @@ export class PythonSettings extends EventEmitter implements IPythonSettings { function getAbsolutePath(pathToCheck: string, rootDir: string): string { // tslint:disable-next-line:prefer-type-cast no-unsafe-any pathToCheck = untildify(pathToCheck) as string; - if (IS_TEST_EXECUTION && !pathToCheck) { return rootDir; } + if (isTestExecution() && !pathToCheck) { return rootDir; } if (pathToCheck.indexOf(path.sep) === -1) { return pathToCheck; } diff --git a/src/client/common/envFileParser.ts b/src/client/common/envFileParser.ts index d6ca7a7024e1..aa84f66b0a53 100644 --- a/src/client/common/envFileParser.ts +++ b/src/client/common/envFileParser.ts @@ -1,58 +1,62 @@ -import * as fs from 'fs'; -import * as path from 'path'; +import * as fs from 'fs-extra'; +import 'reflect-metadata'; +import { EnvironmentVariablesService } from './variables/environment'; +import { EnvironmentVariables } from './variables/types'; +export const IS_WINDOWS = /^win/.test(process.platform); -type EnvVars = Object & { [key: string]: string }; +function parseEnvironmentVariables(contents: string): EnvironmentVariables | undefined { + if (typeof contents !== 'string' || contents.length === 0) { + return undefined; + } -export function parseEnvFile(envFile: string, mergeWithProcessEnvVars: boolean = true): EnvVars { - const buffer = fs.readFileSync(envFile, 'utf8'); - const env = {}; - buffer.split('\n').forEach(line => { - const r = line.match(/^\s*([\w\.\-]+)\s*=\s*(.*)?\s*$/); - if (r !== null) { - let value = r[2] || ''; + const env = {} as EnvironmentVariables; + contents.split('\n').forEach(line => { + const match = line.match(/^\s*([\w\.\-]+)\s*=\s*(.*)?\s*$/); + if (match !== null) { + let value = typeof match[2] === 'string' ? match[2] : ''; if (value.length > 0 && value.charAt(0) === '"' && value.charAt(value.length - 1) === '"') { value = value.replace(/\\n/gm, '\n'); } - env[r[1]] = value.replace(/(^['"]|['"]$)/g, ''); + env[match[1]] = value.replace(/(^['"]|['"]$)/g, ''); } }); - return mergeWithProcessEnvVars ? mergeEnvVariables(env, process.env) : mergePythonPath(env, process.env.PYTHONPATH); + return env; +} + +export function parseEnvFile(envFile: string, mergeWithProcessEnvVars: boolean = true): EnvironmentVariables { + const buffer = fs.readFileSync(envFile, 'utf8'); + const env = parseEnvironmentVariables(buffer)!; + return mergeWithProcessEnvVars ? mergeEnvVariables(env, process.env) : mergePythonPath(env, process.env.PYTHONPATH as string); } /** * Merge the target environment variables into the source. * Note: The source variables are modified and returned (i.e. it modifies value passed in). * @export - * @param {EnvVars} targetEnvVars target environment variables. - * @param {EnvVars} [sourceEnvVars=process.env] source environment variables (defaults to current process variables). - * @returns {EnvVars} + * @param {EnvironmentVariables} targetEnvVars target environment variables. + * @param {EnvironmentVariables} [sourceEnvVars=process.env] source environment variables (defaults to current process variables). + * @returns {EnvironmentVariables} */ -export function mergeEnvVariables(targetEnvVars: EnvVars, sourceEnvVars: EnvVars = process.env): EnvVars { - Object.keys(sourceEnvVars).forEach(setting => { - if (targetEnvVars[setting] === undefined) { - targetEnvVars[setting] = sourceEnvVars[setting]; - } - }); - return mergePythonPath(targetEnvVars, sourceEnvVars.PYTHONPATH); +export function mergeEnvVariables(targetEnvVars: EnvironmentVariables, sourceEnvVars: EnvironmentVariables = process.env): EnvironmentVariables { + const service = new EnvironmentVariablesService(IS_WINDOWS); + service.mergeVariables(sourceEnvVars, targetEnvVars); + service.appendPythonPath(targetEnvVars, sourceEnvVars.PYTHONPATH); + return targetEnvVars; } /** * Merge the target PYTHONPATH value into the env variables passed. * Note: The env variables passed in are modified and returned (i.e. it modifies value passed in). * @export - * @param {EnvVars} env target environment variables. + * @param {EnvironmentVariables} env target environment variables. * @param {string | undefined} [currentPythonPath] PYTHONPATH value. - * @returns {EnvVars} + * @returns {EnvironmentVariables} */ -export function mergePythonPath(env: EnvVars, currentPythonPath: string | undefined): EnvVars { +export function mergePythonPath(env: EnvironmentVariables, currentPythonPath: string | undefined): EnvironmentVariables { if (typeof currentPythonPath !== 'string' || currentPythonPath.length === 0) { return env; } - - if (typeof env.PYTHONPATH === 'string' && env.PYTHONPATH.length > 0) { - env.PYTHONPATH = env.PYTHONPATH + path.delimiter + currentPythonPath; - } else { - env.PYTHONPATH = currentPythonPath; - } + const service = new EnvironmentVariablesService(IS_WINDOWS); + service.appendPythonPath(env, currentPythonPath!); return env; } diff --git a/src/client/common/featureDeprecationManager.ts b/src/client/common/featureDeprecationManager.ts index 2e72a6fee614..dea79684e306 100644 --- a/src/client/common/featureDeprecationManager.ts +++ b/src/client/common/featureDeprecationManager.ts @@ -3,7 +3,7 @@ import { commands, Disposable, window, workspace, WorkspaceConfiguration } from 'vscode'; import { launch } from './net/browser'; -import { IPersistentStateFactory } from './persistentState'; +import { IPersistentStateFactory } from './types'; type deprecatedFeatureInfo = { doNotDisplayPromptStateKey: string; @@ -82,7 +82,8 @@ export class FeatureDeprecationManager implements IFeatureDeprecationManager { } if (notify) { - this.notifyDeprecation(deprecatedInfo); + this.notifyDeprecation(deprecatedInfo) + .catch(ex => console.error('Python Extension: notifyDeprecation', ex)); } } private isDeprecatedSettingAndValueUsed(pythonConfig: WorkspaceConfiguration, deprecatedSetting: deprecatedSettingAndValue) { diff --git a/src/client/common/helpers.ts b/src/client/common/helpers.ts index 47e88d03e24f..9040cb62b70e 100644 --- a/src/client/common/helpers.ts +++ b/src/client/common/helpers.ts @@ -26,6 +26,7 @@ class DeferredImpl implements Deferred { private _rejected: boolean = false; private _promise: Promise; constructor(private scope: any = null) { + // tslint:disable-next-line:promise-must-complete this._promise = new Promise((res, rej) => { this._resolve = res; this._reject = rej; @@ -70,4 +71,4 @@ export function createTemporaryFile(extension: string, temporaryDirectory?: stri resolve({ filePath: tmpFile, cleanupCallback: cleanupCallback }); }); }); -} \ No newline at end of file +} diff --git a/src/client/common/persistentState.ts b/src/client/common/persistentState.ts index 09321b649310..fb505c97826a 100644 --- a/src/client/common/persistentState.ts +++ b/src/client/common/persistentState.ts @@ -3,9 +3,12 @@ 'use strict'; +import { inject, injectable, named } from 'inversify'; +import 'reflect-metadata'; import { Memento } from 'vscode'; +import { GLOBAL_MEMENTO, IMemento, IPersistentState, IPersistentStateFactory, WORKSPACE_MEMENTO } from './types'; -export class PersistentState { +class PersistentState implements IPersistentState{ constructor(private storage: Memento, private key: string, private defaultValue: T) { } public get value(): T { @@ -17,17 +20,14 @@ export class PersistentState { } } -export interface IPersistentStateFactory { - createGlobalPersistentState(key: string, defaultValue: T): PersistentState; - createWorkspacePersistentState(key: string, defaultValue: T): PersistentState; -} - +@injectable() export class PersistentStateFactory implements IPersistentStateFactory { - constructor(private globalState: Memento, private workspaceState: Memento) { } - public createGlobalPersistentState(key: string, defaultValue: T): PersistentState { + constructor( @inject(IMemento) @named(GLOBAL_MEMENTO) private globalState: Memento, + @inject(IMemento) @named(WORKSPACE_MEMENTO) private workspaceState: Memento) { } + public createGlobalPersistentState(key: string, defaultValue: T): IPersistentState { return new PersistentState(this.globalState, key, defaultValue); } - public createWorkspacePersistentState(key: string, defaultValue: T): PersistentState { + public createWorkspacePersistentState(key: string, defaultValue: T): IPersistentState { return new PersistentState(this.workspaceState, key, defaultValue); } } diff --git a/src/client/common/platform/constants.ts b/src/client/common/platform/constants.ts new file mode 100644 index 000000000000..b93ccbd82c91 --- /dev/null +++ b/src/client/common/platform/constants.ts @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +export const WINDOWS_PATH_VARIABLE_NAME = 'Path'; +export const NON_WINDOWS_PATH_VARIABLE_NAME = 'PATH'; +export const IS_WINDOWS = /^win/.test(process.platform); diff --git a/src/client/common/process/constants.ts b/src/client/common/process/constants.ts new file mode 100644 index 000000000000..ccf8e6c6850d --- /dev/null +++ b/src/client/common/process/constants.ts @@ -0,0 +1,4 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +export const DEFAULT_ENCODING = 'utf8'; diff --git a/src/client/common/process/decoder.ts b/src/client/common/process/decoder.ts new file mode 100644 index 000000000000..e3a35a458ab4 --- /dev/null +++ b/src/client/common/process/decoder.ts @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import * as iconv from 'iconv-lite'; +import { injectable } from 'inversify'; +import 'reflect-metadata'; +import { DEFAULT_ENCODING } from './constants'; +import { IBufferDecoder } from './types'; + +@injectable() +export class BufferDecoder implements IBufferDecoder { + public decode(buffers: Buffer[], encoding: string = DEFAULT_ENCODING): string { + encoding = iconv.encodingExists(encoding) ? encoding : DEFAULT_ENCODING; + return iconv.decode(Buffer.concat(buffers), encoding); + } +} diff --git a/src/client/common/process/proc.ts b/src/client/common/process/proc.ts new file mode 100644 index 000000000000..9144b6c6f598 --- /dev/null +++ b/src/client/common/process/proc.ts @@ -0,0 +1,123 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { spawn } from 'child_process'; +import { inject, injectable } from 'inversify'; +import 'reflect-metadata'; +import * as Rx from 'rxjs'; +import { Disposable } from 'vscode'; +import { createDeferred } from '../helpers'; +import { DEFAULT_ENCODING } from './constants'; +import { ExecutionResult, IBufferDecoder, IProcessService, ObservableExecutionResult, Output, SpawnOptions, StdErrError } from './types'; + +@injectable() +export class ProcessService implements IProcessService { + constructor( @inject(IBufferDecoder) private decoder: IBufferDecoder) { } + public execObservable(file: string, args: string[], options: SpawnOptions = {}): ObservableExecutionResult { + const encoding = options.encoding = typeof options.encoding === 'string' && options.encoding.length > 0 ? options.encoding : DEFAULT_ENCODING; + const spawnOptions = { ...options }; + if (!spawnOptions.env || Object.keys(spawnOptions).length === 0) { + spawnOptions.env = process.env; + } + const proc = spawn(file, args, spawnOptions); + let procExited = false; + + const output = new Rx.Observable>(subscriber => { + const disposables: Disposable[] = []; + + const on = (ee: NodeJS.EventEmitter, name: string, fn: Function) => { + ee.on(name, fn); + disposables.push({ dispose: () => ee.removeListener(name, fn) }); + }; + + if (options.token) { + disposables.push(options.token.onCancellationRequested(() => { + if (!procExited && !proc.killed) { + proc.kill(); + procExited = true; + } + })); + } + + const sendOutput = (source: 'stdout' | 'stderr', data: Buffer) => { + const out = this.decoder.decode([data], encoding); + if (source === 'stderr' && options.throwOnStdErr) { + subscriber.error(new StdErrError(out)); + } else { + source = options.mergeStdOutErr ? 'stdout' : source; + subscriber.next({ source, out: out }); + } + }; + + on(proc.stdout, 'data', (data: Buffer) => sendOutput('stdout', data)); + on(proc.stderr, 'data', (data: Buffer) => sendOutput('stderr', data)); + + proc.once('close', () => { + procExited = true; + subscriber.complete(); + disposables.forEach(disposable => disposable.dispose()); + }); + proc.once('error', ex => { + procExited = true; + subscriber.error(ex); + disposables.forEach(disposable => disposable.dispose()); + }); + }); + + return { proc, out: output }; + } + public async exec(file: string, args: string[], options: SpawnOptions = {}): Promise> { + const encoding = options.encoding = typeof options.encoding === 'string' && options.encoding.length > 0 ? options.encoding : DEFAULT_ENCODING; + const spawnOptions = { ...options }; + if (!spawnOptions.env || Object.keys(spawnOptions).length === 0) { + spawnOptions.env = process.env; + } + const proc = spawn(file, args, spawnOptions); + const deferred = createDeferred>(); + const disposables: Disposable[] = []; + + const on = (ee: NodeJS.EventEmitter, name: string, fn: Function) => { + ee.on(name, fn); + disposables.push({ dispose: () => ee.removeListener(name, fn) }); + }; + + if (options.token) { + disposables.push(options.token.onCancellationRequested(() => { + if (!proc.killed && !deferred.completed) { + proc.kill(); + } + })); + } + + const stdoutBuffers: Buffer[] = []; + on(proc.stdout, 'data', (data: Buffer) => stdoutBuffers.push(data)); + const stderrBuffers: Buffer[] = []; + on(proc.stderr, 'data', (data: Buffer) => { + if (options.mergeStdOutErr) { + stdoutBuffers.push(data); + } else { + stderrBuffers.push(data); + } + }); + + proc.once('close', () => { + if (deferred.completed) { + return; + } + const stderr: string | undefined = stderrBuffers.length === 0 ? undefined : this.decoder.decode(stderrBuffers, encoding); + if (stderr && stderr.length > 0 && options.throwOnStdErr) { + deferred.reject(new StdErrError(stderr)); + } else { + const stdout = this.decoder.decode(stdoutBuffers, encoding); + deferred.resolve({ stdout, stderr }); + } + disposables.forEach(disposable => disposable.dispose()); + }); + proc.once('error', ex => { + deferred.reject(ex); + disposables.forEach(disposable => disposable.dispose()); + }); + + return deferred.promise; + } +} diff --git a/src/client/common/process/pythonExecutionFactory.ts b/src/client/common/process/pythonExecutionFactory.ts new file mode 100644 index 000000000000..4465f63c924d --- /dev/null +++ b/src/client/common/process/pythonExecutionFactory.ts @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { inject, injectable } from 'inversify'; +import 'reflect-metadata'; +import { Uri } from 'vscode'; +import { PythonSettings } from '../configSettings'; +import { IEnvironmentVariablesProvider } from '../variables/types'; +import { PythonExecutionService } from './pythonProcess'; +import { IProcessService, IPythonExecutionFactory, IPythonExecutionService } from './types'; + +@injectable() +export class PythonExecutionFactory implements IPythonExecutionFactory { + constructor( @inject(IProcessService) private procService: IProcessService, + @inject(IEnvironmentVariablesProvider) private envVarsService: IEnvironmentVariablesProvider) { } + public async create(resource?: Uri): Promise { + const settings = PythonSettings.getInstance(resource); + return this.envVarsService.getEnvironmentVariables(true, resource) + .then(customEnvVars => { + return new PythonExecutionService(this.procService, settings.pythonPath, customEnvVars); + }); + } +} diff --git a/src/client/common/process/pythonProcess.ts b/src/client/common/process/pythonProcess.ts new file mode 100644 index 000000000000..0c84b25e94e6 --- /dev/null +++ b/src/client/common/process/pythonProcess.ts @@ -0,0 +1,53 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { injectable } from 'inversify'; +import 'reflect-metadata'; +import { EnvironmentVariables } from '../variables/types'; +import { ExecutionResult, IProcessService, IPythonExecutionService, ObservableExecutionResult, SpawnOptions } from './types'; + +@injectable() +export class PythonExecutionService implements IPythonExecutionService { + constructor(private procService: IProcessService, private pythonPath: string, private envVars: EnvironmentVariables | undefined) { } + public async getVersion(): Promise { + return this.procService.exec(this.pythonPath, ['--version'], { env: this.envVars, mergeStdOutErr: true }) + .then(output => output.stdout.trim()); + } + public async getExecutablePath(): Promise { + return this.procService.exec(this.pythonPath, ['-c', 'import sys;print(sys.executable)'], { env: this.envVars, throwOnStdErr: true }) + .then(output => output.stdout.trim()); + } + public async isModuleInstalled(moduleName: string): Promise { + return this.procService.exec(this.pythonPath, ['-c', `import ${moduleName}`], { env: this.envVars, throwOnStdErr: true }) + .then(() => true).catch(() => false); + } + + public execObservable(args: string[], options: SpawnOptions): ObservableExecutionResult { + const opts: SpawnOptions = { ...options }; + if (this.envVars) { + opts.env = this.envVars; + } + return this.procService.execObservable(this.pythonPath, args, opts); + } + public execModuleObservable(moduleName: string, args: string[], options: SpawnOptions): ObservableExecutionResult { + const opts: SpawnOptions = { ...options }; + if (this.envVars) { + opts.env = this.envVars; + } + return this.procService.execObservable(this.pythonPath, ['-m', moduleName, ...args], opts); + } + public async exec(args: string[], options: SpawnOptions): Promise> { + const opts: SpawnOptions = { ...options }; + if (this.envVars) { + opts.env = this.envVars; + } + return this.procService.exec(this.pythonPath, args, opts); + } + public async execModule(moduleName: string, args: string[], options: SpawnOptions): Promise> { + const opts: SpawnOptions = { ...options }; + if (this.envVars) { + opts.env = this.envVars; + } + return this.procService.exec(this.pythonPath, ['-m', moduleName, ...args], opts); + } +} diff --git a/src/client/common/process/serviceRegistry.ts b/src/client/common/process/serviceRegistry.ts new file mode 100644 index 000000000000..1e9e6191322f --- /dev/null +++ b/src/client/common/process/serviceRegistry.ts @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// tslint:disable-next-line:no-import-side-effect +import 'reflect-metadata'; +import { IServiceManager } from '../../ioc/types'; +import { BufferDecoder } from './decoder'; +import { ProcessService } from './proc'; +import { PythonExecutionFactory } from './pythonExecutionFactory'; +import { IBufferDecoder, IProcessService, IPythonExecutionFactory } from './types'; + +export function registerTypes(serviceManager: IServiceManager) { + serviceManager.addSingleton(IBufferDecoder, BufferDecoder); + serviceManager.addSingleton(IProcessService, ProcessService); + serviceManager.addSingleton(IPythonExecutionFactory, PythonExecutionFactory); +} diff --git a/src/client/common/process/types.ts b/src/client/common/process/types.ts new file mode 100644 index 000000000000..69f9c871181d --- /dev/null +++ b/src/client/common/process/types.ts @@ -0,0 +1,71 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { ChildProcess, SpawnOptions as ChildProcessSpawnOptions } from 'child_process'; +import * as Rx from 'rxjs'; +import { CancellationToken, Uri } from 'vscode'; +import { EnvironmentVariables } from '../variables/types'; + +export const IBufferDecoder = Symbol('IBufferDecoder'); +export interface IBufferDecoder { + decode(buffers: Buffer[], encoding: string): string; +} + +export type Output = { + source: 'stdout' | 'stderr'; + out: T; +}; +export type ObservableExecutionResult = { + proc: ChildProcess; + out: Rx.Observable>; +}; + +// tslint:disable-next-line:interface-name +export type SpawnOptions = ChildProcessSpawnOptions & { + encoding?: string; + token?: CancellationToken; + mergeStdOutErr?: boolean; + throwOnStdErr?: boolean; +}; + +export type ExecutionResult = { + stdout: T; + stderr?: string; +}; + +export const IProcessService = Symbol('IProcessService'); + +export interface IProcessService { + execObservable(file: string, args: string[], options: SpawnOptions): ObservableExecutionResult; + exec(file: string, args: string[], options: SpawnOptions): Promise>; +} + +export const IPythonExecutionFactory = Symbol('IPythonExecutionFactory'); + +export interface IPythonExecutionFactory { + create(resource?: Uri): Promise; +} + +export const IPythonExecutionService = Symbol('IPythonExecutionService'); + +export interface IPythonExecutionService { + getVersion(): Promise; + getExecutablePath(): Promise; + isModuleInstalled(moduleName: string): Promise; + + execObservable(args: string[], options: SpawnOptions): ObservableExecutionResult; + execModuleObservable(moduleName: string, args: string[], options: SpawnOptions): ObservableExecutionResult; + + exec(args: string[], options: SpawnOptions): Promise>; + execModule(moduleName: string, args: string[], options: SpawnOptions): Promise>; +} + +export class StdErrError extends Error { + constructor(message: string) { + super(message); + } +} + +export interface IExecutionEnvironmentVariablesService { + getEnvironmentVariables(resource?: Uri): Promise; +} diff --git a/src/client/common/serviceRegistry.ts b/src/client/common/serviceRegistry.ts new file mode 100644 index 000000000000..9ebebc460f2f --- /dev/null +++ b/src/client/common/serviceRegistry.ts @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import 'reflect-metadata'; +import { IServiceManager } from '../ioc/types'; +import { PersistentStateFactory } from './persistentState'; +import { IS_WINDOWS as isWindows } from './platform/constants'; +import { IPersistentStateFactory, IsWindows } from './types'; + +export function registerTypes(serviceManager: IServiceManager) { + serviceManager.addSingletonInstance(IsWindows, isWindows); + serviceManager.addSingleton(IPersistentStateFactory, PersistentStateFactory); +} diff --git a/src/client/common/types.ts b/src/client/common/types.ts index 46954a02dcfe..eddd1e96590c 100644 --- a/src/client/common/types.ts +++ b/src/client/common/types.ts @@ -1,155 +1,21 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. -const _typeof = { - number: 'number', - string: 'string', - undefined: 'undefined', - object: 'object', - function: 'function' -}; +export const IOutputChannel = Symbol('IOutputChannel'); +export const IDocumentSymbolProvider = Symbol('IDocumentSymbolProvider'); +export const IsWindows = Symbol('IS_WINDOWS'); +export const IDiposableRegistry = Symbol('IDiposableRegistry'); +export const IMemento = Symbol('IGlobalMemento'); +export const GLOBAL_MEMENTO = Symbol('IGlobalMemento'); +export const WORKSPACE_MEMENTO = Symbol('IWorkspaceMemento'); -/** - * @returns whether the provided parameter is a JavaScript Array or not. - */ -export function isArray(array: any): array is any[] { - if (Array.isArray) { - return Array.isArray(array); - } - - if (array && typeof (array.length) === _typeof.number && array.constructor === Array) { - return true; - } - - return false; -} - -/** - * @returns whether the provided parameter is a JavaScript String or not. - */ -export function isString(str: any): str is string { - if (typeof (str) === _typeof.string || str instanceof String) { - return true; - } - - return false; -} - -/** - * @returns whether the provided parameter is a JavaScript Array and each element in the array is a string. - */ -export function isStringArray(value: any): value is string[] { - return isArray(value) && (value).every(elem => isString(elem)); -} - -/** - * - * @returns whether the provided parameter is of type `object` but **not** - * `null`, an `array`, a `regexp`, nor a `date`. - */ -export function isObject(obj: any): obj is any { - return typeof obj === _typeof.object - && obj !== null - && !Array.isArray(obj) - && !(obj instanceof RegExp) - && !(obj instanceof Date); -} - -/** - * In **contrast** to just checking `typeof` this will return `false` for `NaN`. - * @returns whether the provided parameter is a JavaScript Number or not. - */ -export function isNumber(obj: any): obj is number { - if ((typeof (obj) === _typeof.number || obj instanceof Number) && !isNaN(obj)) { - return true; - } - - return false; -} - -/** - * @returns whether the provided parameter is a JavaScript Boolean or not. - */ -export function isBoolean(obj: any): obj is boolean { - return obj === true || obj === false; -} - -/** - * @returns whether the provided parameter is undefined. - */ -export function isUndefined(obj: any): boolean { - return typeof (obj) === _typeof.undefined; -} - -/** - * @returns whether the provided parameter is undefined or null. - */ -export function isUndefinedOrNull(obj: any): boolean { - return isUndefined(obj) || obj === null; -} - - -const hasOwnProperty = Object.prototype.hasOwnProperty; - -/** - * @returns whether the provided parameter is an empty JavaScript Object or not. - */ -export function isEmptyObject(obj: any): obj is any { - if (!isObject(obj)) { - return false; - } - - for (let key in obj) { - if (hasOwnProperty.call(obj, key)) { - return false; - } - } - - return true; -} - -/** - * @returns whether the provided parameter is a JavaScript Function or not. - */ -export function isFunction(obj: any): obj is Function { - return typeof obj === _typeof.function; -} - -/** - * @returns whether the provided parameters is are JavaScript Function or not. - */ -export function areFunctions(...objects: any[]): boolean { - return objects && objects.length > 0 && objects.every(isFunction); -} - -export type TypeConstraint = string | Function; - -export function validateConstraints(args: any[], constraints: TypeConstraint[]): void { - const len = Math.min(args.length, constraints.length); - for (let i = 0; i < len; i++) { - validateConstraint(args[i], constraints[i]); - } +export interface IPersistentState { + value: T; } -export function validateConstraint(arg: any, constraint: TypeConstraint): void { +export const IPersistentStateFactory = Symbol('IPersistentStateFactory'); - if (isString(constraint)) { - if (typeof arg !== constraint) { - throw new Error(`argument does not match constraint: typeof ${constraint}`); - } - } else if (isFunction(constraint)) { - if (arg instanceof constraint) { - return; - } - if (arg && arg.constructor === constraint) { - return; - } - if (constraint.length === 1 && constraint.call(undefined, arg) === true) { - return; - } - throw new Error(`argument does not match one of these constraints: arg instanceof constraint, arg.constructor === constraint, nor constraint(arg) === true`); - } +export interface IPersistentStateFactory { + createGlobalPersistentState(key: string, defaultValue: T): IPersistentState; + createWorkspacePersistentState(key: string, defaultValue: T): IPersistentState; } diff --git a/src/client/common/utils.ts b/src/client/common/utils.ts index ae6de92ee7b6..34cefb118342 100644 --- a/src/client/common/utils.ts +++ b/src/client/common/utils.ts @@ -1,6 +1,8 @@ 'use strict'; +// tslint:disable: no-any one-line no-suspicious-comment prefer-template prefer-const no-unnecessary-callback-wrapper no-function-expression no-string-literal no-control-regex no-shadowed-variable // TODO: Cleanup this place // Add options for execPythonFile + import * as child_process from 'child_process'; import * as fs from 'fs'; import * as fsExtra from 'fs-extra'; @@ -61,7 +63,6 @@ async function getPythonInterpreterDirectory(resource?: Uri): Promise { return cache.pythonInterpreterDirectory; } - // Check if we have the path if (path.basename(pythonFileName) === pythonFileName) { try { diff --git a/src/client/common/variables/environment.ts b/src/client/common/variables/environment.ts new file mode 100644 index 000000000000..eac2ab93eea7 --- /dev/null +++ b/src/client/common/variables/environment.ts @@ -0,0 +1,97 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import * as fs from 'fs-extra'; +import { inject, injectable } from 'inversify'; +import * as path from 'path'; +import 'reflect-metadata'; +import { NON_WINDOWS_PATH_VARIABLE_NAME, WINDOWS_PATH_VARIABLE_NAME } from '../platform/constants'; +import { IsWindows } from '../types'; +import { EnvironmentVariables, IEnvironmentVariablesService } from './types'; + +@injectable() +export class EnvironmentVariablesService implements IEnvironmentVariablesService { + constructor( @inject(IsWindows) private isWidows: boolean) { } + public async parseFile(filePath: string): Promise { + const exists = await fs.pathExists(filePath); + if (!exists) { + return undefined; + } + return new Promise((resolve, reject) => { + fs.readFile(filePath, 'utf8', (error, data) => { + if (error) { + return reject(error); + } + const vars = parseEnvironmentVariables(data)!; + if (!vars || Object.keys(vars).length === 0) { + return resolve(undefined); + } + this.appendPythonPath(vars, process.env.PYTHONPATH); + const pathVariable = this.isWidows ? WINDOWS_PATH_VARIABLE_NAME : NON_WINDOWS_PATH_VARIABLE_NAME; + this.appendPath(vars, process.env[pathVariable]); + resolve(vars); + }); + }); + } + public mergeVariables(source: EnvironmentVariables, target: EnvironmentVariables) { + if (!target) { + return; + } + const pathVariable = this.isWidows ? WINDOWS_PATH_VARIABLE_NAME : NON_WINDOWS_PATH_VARIABLE_NAME; + const settingsNotToMerge = ['PYTHONPATH', pathVariable]; + Object.keys(source).forEach(setting => { + if (settingsNotToMerge.indexOf(setting) >= 0) { + return; + } + if (target[setting] === undefined) { + target[setting] = source[setting]; + } + }); + } + public prependPythonPath(vars: EnvironmentVariables, ...pythonPaths: string[]) { + return this.appendOrPrependPaths(vars, 'PYTHONPATH', false, ...pythonPaths); + } + public appendPythonPath(vars: EnvironmentVariables, ...pythonPaths: string[]) { + return this.appendOrPrependPaths(vars, 'PYTHONPATH', true, ...pythonPaths); + } + public prependPath(vars: EnvironmentVariables, ...paths: string[]) { + const pathVariable = this.isWidows ? WINDOWS_PATH_VARIABLE_NAME : NON_WINDOWS_PATH_VARIABLE_NAME; + return this.appendOrPrependPaths(vars, pathVariable, false, ...paths); + } + public appendPath(vars: EnvironmentVariables, ...paths: string[]) { + const pathVariable = this.isWidows ? WINDOWS_PATH_VARIABLE_NAME : NON_WINDOWS_PATH_VARIABLE_NAME; + return this.appendOrPrependPaths(vars, pathVariable, true, ...paths); + } + private appendOrPrependPaths(vars: EnvironmentVariables, variableName: 'PATH' | 'Path' | 'PYTHONPATH', append: boolean, ...pythonPaths: string[]) { + const pathToInsert = pythonPaths.filter(item => typeof item === 'string' && item.length > 0).join(path.delimiter); + if (pathToInsert.length === 0) { + return vars; + } + + if (typeof vars[variableName] === 'string' && vars[variableName].length > 0) { + vars[variableName] = append ? (vars[variableName] + path.delimiter + pathToInsert) : (pathToInsert + path.delimiter + vars[variableName]); + } else { + vars[variableName] = pathToInsert; + } + return vars; + } +} + +function parseEnvironmentVariables(contents: string): EnvironmentVariables | undefined { + if (typeof contents !== 'string' || contents.length === 0) { + return undefined; + } + + const env = {} as EnvironmentVariables; + contents.split('\n').forEach(line => { + const match = line.match(/^\s*([\w\.\-]+)\s*=\s*(.*)?\s*$/); + if (match !== null) { + let value = typeof match[2] === 'string' ? match[2] : ''; + if (value.length > 0 && value.charAt(0) === '"' && value.charAt(value.length - 1) === '"') { + value = value.replace(/\\n/gm, '\n'); + } + env[match[1]] = value.replace(/(^['"]|['"]$)/g, ''); + } + }); + return env; +} diff --git a/src/client/common/variables/environmentVariablesProvider.ts b/src/client/common/variables/environmentVariablesProvider.ts new file mode 100644 index 000000000000..13b76dd62ff0 --- /dev/null +++ b/src/client/common/variables/environmentVariablesProvider.ts @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { inject, injectable } from 'inversify'; +import 'reflect-metadata'; +import { Disposable, FileSystemWatcher, Uri, workspace } from 'vscode'; +import { PythonSettings } from '../configSettings'; +import { NON_WINDOWS_PATH_VARIABLE_NAME, WINDOWS_PATH_VARIABLE_NAME } from '../platform/constants'; +import { IDiposableRegistry, IsWindows } from '../types'; +import { EnvironmentVariables, IEnvironmentVariablesProvider, IEnvironmentVariablesService } from './types'; + +@injectable() +export class EnvironmentVariablesProvider implements IEnvironmentVariablesProvider, Disposable { + private cache = new Map(); + private fileWatchers = new Map(); + private disposables: Disposable[] = []; + + constructor( @inject(IEnvironmentVariablesService) private envVarsService: IEnvironmentVariablesService, + @inject(IDiposableRegistry) disposableRegistry: Disposable[], @inject(IsWindows) private isWidows: boolean) { + disposableRegistry.push(this); + } + + public dispose() { + this.fileWatchers.forEach(watcher => { + watcher.dispose(); + }); + } + public async getEnvironmentVariables(mergeWithProcEnvVariables: boolean, resource?: Uri): Promise { + const settings = PythonSettings.getInstance(resource); + if (!this.cache.has(settings.envFile)) { + this.createFileWatcher(settings.envFile); + const vars = await this.envVarsService.parseFile(settings.envFile); + let mergedVars = await this.envVarsService.parseFile(settings.envFile); + if (!mergedVars || Object.keys(mergedVars).length === 0) { + mergedVars = { ...process.env }; + } + this.envVarsService.mergeVariables(process.env, mergedVars!); + const pathVariable = this.isWidows ? WINDOWS_PATH_VARIABLE_NAME : NON_WINDOWS_PATH_VARIABLE_NAME; + this.envVarsService.appendPath(mergedVars!, process.env[pathVariable]); + this.envVarsService.appendPythonPath(mergedVars!, process.env.PYTHONPATH); + this.cache.set(settings.envFile, { vars, mergedWithProc: mergedVars! }); + } + const data = this.cache.get(settings.envFile)!; + return mergeWithProcEnvVariables ? data.mergedWithProc : data.vars; + } + private createFileWatcher(envFile: string) { + if (this.fileWatchers.has(envFile)) { + return; + } + const envFileWatcher = workspace.createFileSystemWatcher(envFile); + this.fileWatchers.set(envFile, envFileWatcher); + this.disposables.push(envFileWatcher.onDidChange(() => this.cache.delete(envFile))); + this.disposables.push(envFileWatcher.onDidCreate(() => this.cache.delete(envFile))); + this.disposables.push(envFileWatcher.onDidDelete(() => this.cache.delete(envFile))); + } +} diff --git a/src/client/common/variables/serviceRegistry.ts b/src/client/common/variables/serviceRegistry.ts new file mode 100644 index 000000000000..eb2d368edce8 --- /dev/null +++ b/src/client/common/variables/serviceRegistry.ts @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// tslint:disable-next-line:no-import-side-effect +import 'reflect-metadata'; +import { IServiceManager } from '../../ioc/types'; +import { EnvironmentVariablesService } from './environment'; +import { EnvironmentVariablesProvider } from './environmentVariablesProvider'; +import { IEnvironmentVariablesProvider, IEnvironmentVariablesService } from './types'; + +export function registerTypes(serviceManager: IServiceManager) { + serviceManager.addSingleton(IEnvironmentVariablesService, EnvironmentVariablesService); + serviceManager.addSingleton(IEnvironmentVariablesProvider, EnvironmentVariablesProvider); +} diff --git a/src/client/common/variables/sysTypes.ts b/src/client/common/variables/sysTypes.ts new file mode 100644 index 000000000000..8dd82d83fbde --- /dev/null +++ b/src/client/common/variables/sysTypes.ts @@ -0,0 +1,156 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +/* tslint:disable:rule1 no-any no-unnecessary-callback-wrapper jsdoc-format no-for-in prefer-const no-increment-decrement */ + +const _typeof = { + number: 'number', + string: 'string', + undefined: 'undefined', + object: 'object', + function: 'function' +}; + +/** + * @returns whether the provided parameter is a JavaScript Array or not. + */ +export function isArray(array: any): array is any[] { + if (Array.isArray) { + return Array.isArray(array); + } + + if (array && typeof (array.length) === _typeof.number && array.constructor === Array) { + return true; + } + + return false; +} + +/** + * @returns whether the provided parameter is a JavaScript String or not. + */ +export function isString(str: any): str is string { + if (typeof (str) === _typeof.string || str instanceof String) { + return true; + } + + return false; +} + +/** + * @returns whether the provided parameter is a JavaScript Array and each element in the array is a string. + */ +export function isStringArray(value: any): value is string[] { + return isArray(value) && (value).every(elem => isString(elem)); +} + +/** + * + * @returns whether the provided parameter is of type `object` but **not** + * `null`, an `array`, a `regexp`, nor a `date`. + */ +export function isObject(obj: any): obj is any { + return typeof obj === _typeof.object + && obj !== null + && !Array.isArray(obj) + && !(obj instanceof RegExp) + && !(obj instanceof Date); +} + +/** + * In **contrast** to just checking `typeof` this will return `false` for `NaN`. + * @returns whether the provided parameter is a JavaScript Number or not. + */ +export function isNumber(obj: any): obj is number { + if ((typeof (obj) === _typeof.number || obj instanceof Number) && !isNaN(obj)) { + return true; + } + + return false; +} + +/** + * @returns whether the provided parameter is a JavaScript Boolean or not. + */ +export function isBoolean(obj: any): obj is boolean { + return obj === true || obj === false; +} + +/** + * @returns whether the provided parameter is undefined. + */ +export function isUndefined(obj: any): boolean { + return typeof (obj) === _typeof.undefined; +} + +/** + * @returns whether the provided parameter is undefined or null. + */ +export function isUndefinedOrNull(obj: any): boolean { + return isUndefined(obj) || obj === null; +} + +const hasOwnProperty = Object.prototype.hasOwnProperty; + +/** + * @returns whether the provided parameter is an empty JavaScript Object or not. + */ +export function isEmptyObject(obj: any): obj is any { + if (!isObject(obj)) { + return false; + } + + for (let key in obj) { + if (hasOwnProperty.call(obj, key)) { + return false; + } + } + + return true; +} + +/** + * @returns whether the provided parameter is a JavaScript Function or not. + */ +export function isFunction(obj: any): obj is Function { + return typeof obj === _typeof.function; +} + +/** + * @returns whether the provided parameters is are JavaScript Function or not. + */ +export function areFunctions(...objects: any[]): boolean { + return objects && objects.length > 0 && objects.every(isFunction); +} + +export type TypeConstraint = string | Function; + +export function validateConstraints(args: any[], constraints: TypeConstraint[]): void { + const len = Math.min(args.length, constraints.length); + for (let i = 0; i < len; i++) { + validateConstraint(args[i], constraints[i]); + } +} + +export function validateConstraint(arg: any, constraint: TypeConstraint): void { + + if (isString(constraint)) { + if (typeof arg !== constraint) { + throw new Error(`argument does not match constraint: typeof ${constraint}`); + } + } else if (isFunction(constraint)) { + if (arg instanceof constraint) { + return; + } + if (arg && arg.constructor === constraint) { + return; + } + if (constraint.length === 1 && constraint.call(undefined, arg) === true) { + return; + } + throw new Error('argument does not match one of these constraints: arg instanceof constraint, arg.constructor === constraint, nor constraint(arg) === true'); + } +} diff --git a/src/client/common/systemVariables.ts b/src/client/common/variables/systemVariables.ts similarity index 71% rename from src/client/common/systemVariables.ts rename to src/client/common/variables/systemVariables.ts index 50962cc77b64..65c90e111efb 100644 --- a/src/client/common/systemVariables.ts +++ b/src/client/common/variables/systemVariables.ts @@ -1,61 +1,46 @@ -import * as Types from './types'; -import * as vscode from 'vscode'; import * as Path from 'path'; - -/** - * An interface for a JavaScript object that - * acts a dictionary. The keys are strings. - */ -export interface IStringDictionary { - [name: string]: V; -} +import * as Types from './sysTypes'; +import { IStringDictionary, ISystemVariables } from './types'; +/* tslint:disable:rule1 no-any no-unnecessary-callback-wrapper jsdoc-format no-for-in prefer-const no-increment-decrement */ export abstract class Parser { - protected log(message: string): void { - } - - protected is(value: any, func: (value: any) => boolean, wrongTypeState?: any, wrongTypeMessage?: string, undefinedState?: any, undefinedMessage?: string): boolean { - if (Types.isUndefined(value)) { - return false; - } - if (!func(value)) { - return false; - } - return true; - } protected static merge(destination: T, source: T, overwrite: boolean): void { Object.keys(source).forEach((key) => { - let destValue = destination[key]; - let sourceValue = source[key]; + const destValue = (destination as any as { [key: string]: string })[key]; + const sourceValue = (source as any as { [key: string]: string })[key]; if (Types.isUndefined(sourceValue)) { return; } if (Types.isUndefined(destValue)) { - destination[key] = sourceValue; + (destination as any as { [key: string]: string })[key] = sourceValue; } else { if (overwrite) { if (Types.isObject(destValue) && Types.isObject(sourceValue)) { this.merge(destValue, sourceValue, overwrite); } else { - destination[key] = sourceValue; + (destination as any as { [key: string]: string })[key] = sourceValue; } } } }); } -} + // tslint:disable-next-line:no-empty + protected log(message: string): void { } -export interface ISystemVariables { - resolve(value: string): string; - resolve(value: string[]): string[]; - resolve(value: IStringDictionary): IStringDictionary; - resolve(value: IStringDictionary): IStringDictionary; - resolve(value: IStringDictionary>): IStringDictionary>; - resolveAny(value: T): T; - [key: string]: any; + // tslint:disable-next-line:no-any + protected is(value: any, func: (value: any) => boolean, wrongTypeState?: any, wrongTypeMessage?: string, undefinedState?: any, undefinedMessage?: string): boolean { + if (Types.isUndefined(value)) { + return false; + } + if (!func(value)) { + return false; + } + return true; + } } + export abstract class AbstractSystemVariables implements ISystemVariables { public resolve(value: string): string; @@ -63,6 +48,7 @@ export abstract class AbstractSystemVariables implements ISystemVariables { public resolve(value: IStringDictionary): IStringDictionary; public resolve(value: IStringDictionary): IStringDictionary; public resolve(value: IStringDictionary>): IStringDictionary>; + // tslint:disable-next-line:no-any public resolve(value: any): any { if (Types.isString(value)) { return this.__resolveString(value); @@ -75,8 +61,9 @@ export abstract class AbstractSystemVariables implements ISystemVariables { return value; } - resolveAny(value: T): T; - resolveAny(value: any): any { + public resolveAny(value: T): T; + // tslint:disable-next-line:no-any + public resolveAny(value: any): any { if (Types.isString(value)) { return this.__resolveString(value); } else if (Types.isArray(value)) { @@ -89,9 +76,10 @@ export abstract class AbstractSystemVariables implements ISystemVariables { } private __resolveString(value: string): string { - let regexp = /\$\{(.*?)\}/g; + const regexp = /\$\{(.*?)\}/g; return value.replace(regexp, (match: string, name: string) => { - let newValue = (this)[name]; + // tslint:disable-next-line:no-any + const newValue = (this)[name]; if (Types.isString(newValue)) { return newValue; } else { @@ -101,19 +89,22 @@ export abstract class AbstractSystemVariables implements ISystemVariables { } private __resolveLiteral(values: IStringDictionary | string[]>): IStringDictionary | string[]> { - let result: IStringDictionary | string[]> = Object.create(null); + const result: IStringDictionary | string[]> = Object.create(null); Object.keys(values).forEach(key => { - let value = values[key]; + const value = values[key]; + // tslint:disable-next-line:no-any result[key] = this.resolve(value); }); return result; } private __resolveAnyLiteral(values: T): T; - private __resolveAnyLiteral(values: any): any { - let result: IStringDictionary | string[]> = Object.create(null); + // tslint:disable-next-line:no-any + private __resolveAnyLiteral(values: any): any { + const result: IStringDictionary | string[]> = Object.create(null); Object.keys(values).forEach(key => { - let value = values[key]; + const value = values[key]; + // tslint:disable-next-line:no-any result[key] = this.resolveAny(value); }); return result; @@ -124,12 +115,12 @@ export abstract class AbstractSystemVariables implements ISystemVariables { } private __resolveAnyArray(value: T[]): T[]; + // tslint:disable-next-line:no-any private __resolveAnyArray(value: any[]): any[] { return value.map(s => this.resolveAny(s)); } } - export class SystemVariables extends AbstractSystemVariables { private _workspaceFolder: string; private _workspaceFolderName: string; @@ -139,7 +130,7 @@ export class SystemVariables extends AbstractSystemVariables { this._workspaceFolder = typeof workspaceFolder === 'string' ? workspaceFolder : __dirname; this._workspaceFolderName = Path.basename(this._workspaceFolder); Object.keys(process.env).forEach(key => { - this[`env:${key}`] = this[`env.${key}`] = process.env[key]; + (this as any as { [key: string]: string })[`env:${key}`] = (this as any as { [key: string]: string })[`env.${key}`] = process.env[key]; }); } diff --git a/src/client/common/variables/types.ts b/src/client/common/variables/types.ts new file mode 100644 index 000000000000..5a04581b8bc9 --- /dev/null +++ b/src/client/common/variables/types.ts @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { Uri } from 'vscode'; + +export type EnvironmentVariables = Object & { + [key: string]: string; +}; + +export const IEnvironmentVariablesService = Symbol('IEnvironmentVariablesService'); + +export interface IEnvironmentVariablesService { + parseFile(filePath: string): Promise; + mergeVariables(source: EnvironmentVariables, target: EnvironmentVariables): void; + prependPythonPath(vars: EnvironmentVariables, ...pythonPaths: string[]): void; + appendPythonPath(vars: EnvironmentVariables, ...pythonPaths: string[]): void; + prependPath(vars: EnvironmentVariables, ...paths: string[]): void; + appendPath(vars: EnvironmentVariables, ...paths: string[]): void; +} + +/** + * An interface for a JavaScript object that + * acts as a dictionary. The keys are strings. + */ +export interface IStringDictionary { + [name: string]: V; +} + +export interface ISystemVariables { + resolve(value: string): string; + resolve(value: string[]): string[]; + resolve(value: IStringDictionary): IStringDictionary; + resolve(value: IStringDictionary): IStringDictionary; + resolve(value: IStringDictionary>): IStringDictionary>; + resolveAny(value: T): T; + // tslint:disable-next-line:no-any + [key: string]: any; +} + +export const IEnvironmentVariablesProvider = Symbol('IEnvironmentVariablesProvider'); + +export interface IEnvironmentVariablesProvider { + getEnvironmentVariables(mergeWithProcEnvVariables: boolean, resource?: Uri): Promise; +} diff --git a/src/client/debugger/DebugClients/LocalDebugClient.ts b/src/client/debugger/DebugClients/LocalDebugClient.ts index 8b0032ad760a..a1a34c686b04 100644 --- a/src/client/debugger/DebugClients/LocalDebugClient.ts +++ b/src/client/debugger/DebugClients/LocalDebugClient.ts @@ -108,7 +108,9 @@ export class LocalDebugClient extends DebugClient { // Here we wait for the application to connect to the socket server. // Only once connected do we know that the application has successfully launched. - this.debugServer.DebugClientConnected.then(resolve); + this.debugServer.DebugClientConnected + .then(resolve) + .catch(ex => console.error('Python Extension: debugServer.DebugClientConnected', ex)); } } }); diff --git a/src/client/debugger/Main.ts b/src/client/debugger/Main.ts index 9ff88164fab0..adc8b7b587d1 100644 --- a/src/client/debugger/Main.ts +++ b/src/client/debugger/Main.ts @@ -2,6 +2,7 @@ import * as fs from "fs"; import * as path from "path"; +import 'reflect-metadata'; import { DebugSession, Handles, InitializedEvent, OutputEvent, Scope, Source, StackFrame, StoppedEvent, TerminatedEvent, Thread } from "vscode-debugadapter"; import { ThreadEvent } from "vscode-debugadapter"; import { DebugProtocol } from "vscode-debugprotocol"; diff --git a/src/client/debugger/PythonProcess.ts b/src/client/debugger/PythonProcess.ts index b37a70bafed8..151581e6dbd3 100644 --- a/src/client/debugger/PythonProcess.ts +++ b/src/client/debugger/PythonProcess.ts @@ -267,6 +267,7 @@ export class PythonProcess extends EventEmitter implements IPythonProcess { } public BindBreakpoint(brkpoint: IPythonBreakpoint): Promise { + // tslint:disable-next-line:promise-must-complete return new Promise((resolve, reject) => { let bkCmd: IBreakpointCommand = { Id: brkpoint.Id, @@ -326,6 +327,7 @@ export class PythonProcess extends EventEmitter implements IPythonProcess { this.stream.Write(Commands.BreakAllCommandBytes); } public ExecuteText(text: string, reprKind: PythonEvaluationResultReprKind, stackFrame: IPythonStackFrame): Promise { + // tslint:disable-next-line:promise-must-complete return new Promise((resolve, reject) => { let executeId = this._idDispenser.Allocate(); let cmd: IExecutionCommand = { diff --git a/src/client/extension.ts b/src/client/extension.ts index ff1acf102139..a18ac328e44a 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -1,11 +1,16 @@ 'use strict'; +import { Container } from 'inversify'; import * as os from 'os'; import * as vscode from 'vscode'; +import { Disposable, Memento, OutputChannel } from 'vscode'; import { BannerService } from './banner'; import * as settings from './common/configSettings'; import { FeatureDeprecationManager } from './common/featureDeprecationManager'; import { createDeferred } from './common/helpers'; -import { PersistentStateFactory } from './common/persistentState'; +import { registerTypes as processRegisterTypes } from './common/process/serviceRegistry'; +import { registerTypes as commonRegisterTypes } from './common/serviceRegistry'; +import { GLOBAL_MEMENTO, IDiposableRegistry, IMemento, IOutputChannel, IPersistentStateFactory, WORKSPACE_MEMENTO } from './common/types'; +import { registerTypes as variableRegisterTypes } from './common/variables/serviceRegistry'; import { SimpleConfigurationProvider } from './debugger'; import { FeedbackService } from './feedback'; import { InterpreterManager } from './interpreter'; @@ -13,6 +18,9 @@ import { SetInterpreterProvider } from './interpreter/configuration/setInterpret import { ShebangCodeLensProvider } from './interpreter/display/shebangCodeLensProvider'; import { getCondaVersion } from './interpreter/helpers'; import { InterpreterVersionService } from './interpreter/interpreterVersion'; +import { ServiceContainer } from './ioc/container'; +import { ServiceManager } from './ioc/serviceManager'; +import { IServiceContainer } from './ioc/types'; import { JupyterProvider } from './jupyter/provider'; import { JediFactory } from './languageServices/jediProxyFactory'; import { PythonCompletionItemProvider } from './providers/completionProvider'; @@ -34,7 +42,9 @@ import { sendTelemetryEvent } from './telemetry'; import { EDITOR_LOAD } from './telemetry/constants'; import { StopWatch } from './telemetry/stopWatch'; import { BlockFormatProviders } from './typeFormatters/blockFormatProvider'; +import { TEST_OUTPUT_CHANNEL } from './unittests/common/constants'; import * as tests from './unittests/main'; +import { registerTypes as unitTestsRegisterTypes } from './unittests/serviceRegistry'; import { WorkspaceSymbols } from './workspaceSymbols/main'; const PYTHON: vscode.DocumentFilter = { language: 'python' }; @@ -43,15 +53,31 @@ let formatOutChannel: vscode.OutputChannel; let lintingOutChannel: vscode.OutputChannel; const activationDeferred = createDeferred(); export const activated = activationDeferred.promise; + +let cont: Container; +let serviceManager: ServiceManager; +let serviceContainer: ServiceContainer; + // tslint:disable-next-line:max-func-body-length export async function activate(context: vscode.ExtensionContext) { - const persistentStateFactory = new PersistentStateFactory(context.globalState, context.workspaceState); + cont = new Container(); + serviceManager = new ServiceManager(cont); + serviceContainer = new ServiceContainer(cont); + serviceManager.addSingletonInstance(IServiceContainer, serviceContainer); + serviceManager.addSingletonInstance(IDiposableRegistry, context.subscriptions); + serviceManager.addSingletonInstance(IMemento, context.globalState, GLOBAL_MEMENTO); + serviceManager.addSingletonInstance(IMemento, context.workspaceState, WORKSPACE_MEMENTO); + commonRegisterTypes(serviceManager); + processRegisterTypes(serviceManager); + variableRegisterTypes(serviceManager); + unitTestsRegisterTypes(serviceManager); + + const persistentStateFactory = serviceManager.get(IPersistentStateFactory); const pythonSettings = settings.PythonSettings.getInstance(); - // tslint:disable-next-line:no-floating-promises sendStartupTelemetry(activated); lintingOutChannel = vscode.window.createOutputChannel(pythonSettings.linting.outputWindow); - formatOutChannel = lintingOutChannel; + unitTestOutChannel = formatOutChannel = lintingOutChannel; if (pythonSettings.linting.outputWindow !== pythonSettings.formatting.outputWindow) { formatOutChannel = vscode.window.createOutputChannel(pythonSettings.formatting.outputWindow); formatOutChannel.clear(); @@ -61,11 +87,13 @@ export async function activate(context: vscode.ExtensionContext) { unitTestOutChannel.clear(); } + serviceManager.addSingletonInstance(IOutputChannel, unitTestOutChannel, TEST_OUTPUT_CHANNEL); + sortImports.activate(context, formatOutChannel); const interpreterManager = new InterpreterManager(); await interpreterManager.autoSetInterpreter(); - // tslint:disable-next-line:no-floating-promises - interpreterManager.refresh(); + interpreterManager.refresh() + .catch(ex => console.error('Python Extension: interpreterManager.refresh', ex)); context.subscriptions.push(interpreterManager); const interpreterVersionService = new InterpreterVersionService(); context.subscriptions.push(new SetInterpreterProvider(interpreterManager, interpreterVersionService)); @@ -136,7 +164,7 @@ export async function activate(context: vscode.ExtensionContext) { linterProvider.documentHasJupyterCodeCells = jupyterExtInstalled.exports.hasCodeCells; }); } - tests.activate(context, unitTestOutChannel, symbolProvider); + tests.activate(context, unitTestOutChannel, symbolProvider, serviceContainer); context.subscriptions.push(new WorkspaceSymbols(lintingOutChannel)); @@ -158,17 +186,18 @@ export async function activate(context: vscode.ExtensionContext) { context.subscriptions.push(new FeatureDeprecationManager(persistentStateFactory, !!jupyterExtInstalled)); } -async function sendStartupTelemetry(activatedPromise: Promise) { +function sendStartupTelemetry(activatedPromise: Promise) { const stopWatch = new StopWatch(); - // tslint:disable-next-line:no-floating-promises - activatedPromise.then(async () => { - const duration = stopWatch.elapsedTime; - let condaVersion: string | undefined; - try { - condaVersion = await getCondaVersion(); - // tslint:disable-next-line:no-empty - } catch { } - const props = condaVersion ? { condaVersion } : undefined; - sendTelemetryEvent(EDITOR_LOAD, duration, props); - }); + activatedPromise + .then(async () => { + const duration = stopWatch.elapsedTime; + let condaVersion: string | undefined; + try { + condaVersion = await getCondaVersion(); + // tslint:disable-next-line:no-empty + } catch { } + const props = condaVersion ? { condaVersion } : undefined; + sendTelemetryEvent(EDITOR_LOAD, duration, props); + }) + .catch(ex => console.error('Python Extension: sendStartupTelemetry', ex)); } diff --git a/src/client/feedback/feedbackService.ts b/src/client/feedback/feedbackService.ts index 2a99017309d3..98325d9de6f0 100644 --- a/src/client/feedback/feedbackService.ts +++ b/src/client/feedback/feedbackService.ts @@ -5,7 +5,7 @@ import { window } from 'vscode'; import { commands, Disposable, TextDocument, workspace } from 'vscode'; import { PythonLanguage } from '../common/constants'; import { launch } from '../common/net/browser'; -import { IPersistentStateFactory, PersistentState } from '../common/persistentState'; +import { IPersistentState, IPersistentStateFactory } from '../common/types'; import { FEEDBACK } from '../telemetry/constants'; import { captureTelemetry, sendTelemetryEvent } from '../telemetry/index'; import { FeedbackCounters } from './counters'; @@ -14,8 +14,8 @@ const FEEDBACK_URL = 'https://www.surveymonkey.com/r/293C9HY'; export class FeedbackService implements Disposable { private counters?: FeedbackCounters; - private showFeedbackPrompt: PersistentState; - private userResponded: PersistentState; + private showFeedbackPrompt: IPersistentState; + private userResponded: IPersistentState; private promptDisplayed: boolean; private disposables: Disposable[] = []; private get canShowPrompt(): boolean { diff --git a/src/client/formatters/baseFormatter.ts b/src/client/formatters/baseFormatter.ts index ec957fcb55f7..68e6a76bfdb8 100644 --- a/src/client/formatters/baseFormatter.ts +++ b/src/client/formatters/baseFormatter.ts @@ -82,7 +82,8 @@ export abstract class BaseFormatter { `Custom arguments to the formatter can be defined in 'python.formatter.${this.Id}Args' setting of settings.json.`; } else { customError += `\nYou could either install the '${this.Id}' formatter, turn it off or use another formatter.`; - this.installer.promptToInstall(this.product, resource); + this.installer.promptToInstall(this.product, resource) + .catch(ex => console.error('Python Extension: promptToInstall', ex)); } } diff --git a/src/client/interpreter/configuration/pythonPathUpdaterService.ts b/src/client/interpreter/configuration/pythonPathUpdaterService.ts index b0e52a6a94a4..54585d801c76 100644 --- a/src/client/interpreter/configuration/pythonPathUpdaterService.ts +++ b/src/client/interpreter/configuration/pythonPathUpdaterService.ts @@ -23,7 +23,8 @@ export class PythonPathUpdaterService { console.error(reason); } // do not wait for this to complete - this.sendTelemetry(stopWatch.elapsedTime, failed, trigger, pythonPath); + this.sendTelemetry(stopWatch.elapsedTime, failed, trigger, pythonPath) + .catch(ex => console.error('Python Extension: sendTelemetry', ex)); } private async sendTelemetry(duration: number, failed: boolean, trigger: 'ui' | 'shebang' | 'load', pythonPath: string) { let version: string | undefined; diff --git a/src/client/interpreter/index.ts b/src/client/interpreter/index.ts index 15f65f1a774e..15df277987b2 100644 --- a/src/client/interpreter/index.ts +++ b/src/client/interpreter/index.ts @@ -83,8 +83,8 @@ export class InterpreterManager implements Disposable { } private onConfigChanged() { if (this.display) { - // tslint:disable-next-line:no-floating-promises - this.display.refresh(); + this.display.refresh() + .catch(ex => console.error('Python Extension: display.refresh', ex)); } } } diff --git a/src/client/ioc/container.ts b/src/client/ioc/container.ts new file mode 100644 index 000000000000..2034737f141c --- /dev/null +++ b/src/client/ioc/container.ts @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { EventEmitter } from 'events'; +import { Container, decorate, injectable, interfaces } from 'inversify'; +import { Abstract, IServiceContainer, Newable } from './types'; + +// This needs to be done once, hence placed in a common location. +// Used by UnitTestSockerServer and also the extension unit tests. +decorate(injectable(), EventEmitter); + +@injectable() +export class ServiceContainer implements IServiceContainer { + constructor(private container: Container) { } + public get(serviceIdentifier: interfaces.ServiceIdentifier, name?: string | number | symbol): T { + return name ? this.container.getNamed(serviceIdentifier, name) : this.container.get(serviceIdentifier); + } + public getAll(serviceIdentifier: string | symbol | Newable | Abstract, name?: string | number | symbol | undefined): T[] { + return name ? this.container.getAllNamed(serviceIdentifier, name) : this.container.getAll(serviceIdentifier); + } +} diff --git a/src/client/ioc/index.ts b/src/client/ioc/index.ts new file mode 100644 index 000000000000..0ee4070d5ded --- /dev/null +++ b/src/client/ioc/index.ts @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { IServiceContainer } from './types'; + +let container: IServiceContainer; +export function getServiceContainer() { + return container; +} +export function setServiceContainer(serviceContainer: IServiceContainer) { + container = serviceContainer; +} diff --git a/src/client/ioc/serviceManager.ts b/src/client/ioc/serviceManager.ts new file mode 100644 index 000000000000..792358da06dd --- /dev/null +++ b/src/client/ioc/serviceManager.ts @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { Container, interfaces } from 'inversify'; +import { Abstract, IServiceManager, Newable } from './types'; + +type identifier = string | symbol | Newable | Abstract; + +export class ServiceManager implements IServiceManager { + constructor(private container: Container) { } + // tslint:disable-next-line:no-any + public add(serviceIdentifier: identifier, constructor: new (...args: any[]) => T, name?: string | number | symbol | undefined): void { + if (name) { + this.container.bind(serviceIdentifier).to(constructor).whenTargetNamed(name); + } else { + this.container.bind(serviceIdentifier).to(constructor); + } + } + // tslint:disable-next-line:no-any + public addFactory(factoryIdentifier: interfaces.ServiceIdentifier>, factoryMethod: interfaces.FactoryCreator): void { + this.container.bind>(factoryIdentifier).toFactory(factoryMethod); + } + // tslint:disable-next-line:no-any + public addSingleton(serviceIdentifier: identifier, constructor: new (...args: any[]) => T, name?: string | number | symbol | undefined): void { + if (name) { + this.container.bind(serviceIdentifier).to(constructor).inSingletonScope().whenTargetNamed(name); + } else { + this.container.bind(serviceIdentifier).to(constructor).inSingletonScope(); + } + } + // tslint:disable-next-line:no-any + public addSingletonInstance(serviceIdentifier: identifier, instance: T, name?: string | number | symbol | undefined): void { + if (name) { + this.container.bind(serviceIdentifier).toConstantValue(instance).whenTargetNamed(name); + } else { + this.container.bind(serviceIdentifier).toConstantValue(instance); + } + } + public get(serviceIdentifier: identifier, name?: string | number | symbol | undefined): T { + return name ? this.container.getNamed(serviceIdentifier, name) : this.container.get(serviceIdentifier); + } + public getAll(serviceIdentifier: identifier, name?: string | number | symbol | undefined): T[] { + return name ? this.container.getAllNamed(serviceIdentifier, name) : this.container.getAll(serviceIdentifier); + } +} diff --git a/src/client/ioc/types.ts b/src/client/ioc/types.ts new file mode 100644 index 000000000000..75fe3b312832 --- /dev/null +++ b/src/client/ioc/types.ts @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { interfaces } from 'inversify'; + +// tslint:disable-next-line:interface-name +export interface Newable { + // tslint:disable-next-line:no-any + new(...args: any[]): T; +} +// tslint:disable-next-line:interface-name +export interface Abstract { + prototype: T; +} +export type ClassType = { + // tslint:disable-next-line:no-any + new(...args: any[]): T; +}; + +export const IServiceManager = Symbol('IServiceManager'); + +export interface IServiceManager { + add(serviceIdentifier: interfaces.ServiceIdentifier, constructor: ClassType, name?: string | number | symbol): void; + addSingleton(serviceIdentifier: interfaces.ServiceIdentifier, constructor: ClassType, name?: string | number | symbol): void; + addSingletonInstance(serviceIdentifier: interfaces.ServiceIdentifier, instance: T, name?: string | number | symbol): void; + addFactory(factoryIdentifier: interfaces.ServiceIdentifier>, factoryMethod: interfaces.FactoryCreator): void; + get(serviceIdentifier: interfaces.ServiceIdentifier, name?: string | number | symbol): T; + getAll(serviceIdentifier: interfaces.ServiceIdentifier, name?: string | number | symbol): T[]; +} + +export const IServiceContainer = Symbol('IServiceContainer'); +export interface IServiceContainer { + get(serviceIdentifier: interfaces.ServiceIdentifier, name?: string | number | symbol): T; + getAll(serviceIdentifier: interfaces.ServiceIdentifier, name?: string | number | symbol): T[]; +} diff --git a/src/client/linters/errorHandlers/notInstalled.ts b/src/client/linters/errorHandlers/notInstalled.ts index f875997b184f..1aaf8602d40b 100644 --- a/src/client/linters/errorHandlers/notInstalled.ts +++ b/src/client/linters/errorHandlers/notInstalled.ts @@ -9,7 +9,8 @@ export class NotInstalledErrorHandler extends StandardErrorHandler { return false; } - this.installer.promptToInstall(this.product, resource); + this.installer.promptToInstall(this.product, resource) + .catch(ex => console.error('Python Extension: NotInstalledErrorHandler.promptToInstall', ex)); const customError = `Linting with ${this.id} failed.\nYou could either install the '${this.id}' linter or turn it off in setings.json via "python.linting.${this.id}Enabled = false".`; this.outputChannel.appendLine(`\n${customError}\n${error + ''}`); return true; diff --git a/src/client/linters/errorHandlers/standard.ts b/src/client/linters/errorHandlers/standard.ts index 966f8afa41a9..941b48487558 100644 --- a/src/client/linters/errorHandlers/standard.ts +++ b/src/client/linters/errorHandlers/standard.ts @@ -11,7 +11,8 @@ export class StandardErrorHandler { window.showErrorMessage(message, 'Disable linter', 'View Errors').then(item => { switch (item) { case 'Disable linter': { - this.installer.disableLinter(this.product, resource); + this.installer.disableLinter(this.product, resource) + .catch(ex => console.error('Python Extension: StandardErrorHandler.displayLinterError', ex)); break; } case 'View Errors': { diff --git a/src/client/linters/pep8Linter.ts b/src/client/linters/pep8Linter.ts index 18f77e4bce54..4c5a18c56b4f 100644 --- a/src/client/linters/pep8Linter.ts +++ b/src/client/linters/pep8Linter.ts @@ -25,14 +25,12 @@ export class Linter extends baseLinter.BaseLinter { pep8Args = ProductExecutableAndArgs.get(Product.pep8).args; } - return new Promise(resolve => { - this.run(pep8Path, pep8Args.concat(['--format=%(row)d,%(col)d,%(code).1s,%(code)s:%(text)s', document.uri.fsPath]), document, this.getWorkspaceRootPath(document), cancellation).then(messages => { - messages.forEach(msg => { - msg.severity = this.parseMessagesSeverity(msg.type, this.pythonSettings.linting.pep8CategorySeverity); - }); - - resolve(messages); + return this.run(pep8Path, pep8Args.concat(['--format=%(row)d,%(col)d,%(code).1s,%(code)s:%(text)s', document.uri.fsPath]), document, this.getWorkspaceRootPath(document), cancellation).then(messages => { + messages.forEach(msg => { + msg.severity = this.parseMessagesSeverity(msg.type, this.pythonSettings.linting.pep8CategorySeverity); }); + + return messages; }); } } diff --git a/src/client/linters/pydocstyle.ts b/src/client/linters/pydocstyle.ts index 81f2cdbd029f..9239d385038d 100644 --- a/src/client/linters/pydocstyle.ts +++ b/src/client/linters/pydocstyle.ts @@ -26,15 +26,13 @@ export class Linter extends baseLinter.BaseLinter { pydocstyleArgs = ProductExecutableAndArgs.get(Product.pydocstyle).args; } - return new Promise(resolve => { - this.run(pydocstylePath, pydocstyleArgs.concat([document.uri.fsPath]), document, null, cancellation).then(messages => { - // All messages in pep8 are treated as warnings for now - messages.forEach(msg => { - msg.severity = baseLinter.LintMessageSeverity.Information; - }); - - resolve(messages); + return this.run(pydocstylePath, pydocstyleArgs.concat([document.uri.fsPath]), document, null, cancellation).then(messages => { + // All messages in pep8 are treated as warnings for now + messages.forEach(msg => { + msg.severity = baseLinter.LintMessageSeverity.Information; }); + + return messages; }); } diff --git a/src/client/linters/pylama.ts b/src/client/linters/pylama.ts index f0251ee728ea..fa198f591498 100644 --- a/src/client/linters/pylama.ts +++ b/src/client/linters/pylama.ts @@ -27,15 +27,13 @@ export class Linter extends baseLinter.BaseLinter { pylamaArgs = ProductExecutableAndArgs.get(Product.pylama).args; } - return new Promise(resolve => { - this.run(pylamaPath, pylamaArgs.concat(['--format=parsable', document.uri.fsPath]), document, this.getWorkspaceRootPath(document), cancellation, REGEX).then(messages => { - // All messages in pylama are treated as warnings for now - messages.forEach(msg => { - msg.severity = baseLinter.LintMessageSeverity.Information; - }); - - resolve(messages); + return this.run(pylamaPath, pylamaArgs.concat(['--format=parsable', document.uri.fsPath]), document, this.getWorkspaceRootPath(document), cancellation, REGEX).then(messages => { + // All messages in pylama are treated as warnings for now. + messages.forEach(msg => { + msg.severity = baseLinter.LintMessageSeverity.Warning; }); + + return messages; }); } } diff --git a/src/client/providers/execInTerminalProvider.ts b/src/client/providers/execInTerminalProvider.ts index 31d07d83ff6a..bd1c356f1b2e 100644 --- a/src/client/providers/execInTerminalProvider.ts +++ b/src/client/providers/execInTerminalProvider.ts @@ -217,7 +217,8 @@ class DjangoContextInitializer implements vscode.Disposable { private disposables: Disposable[] = []; constructor() { this.isDjangoProject = new ContextKey('python.isDjangoProject'); - this.ensureState(); + this.ensureState() + .catch(ex => console.error('Python Extension: ensureState', ex)); this.disposables.push(vscode.workspace.onDidChangeWorkspaceFolders(() => this.updateContextKeyBasedOnActiveWorkspace())); } diff --git a/src/client/providers/jediProxy.ts b/src/client/providers/jediProxy.ts index 97f5c3edc2c1..f30b1dd91012 100644 --- a/src/client/providers/jediProxy.ts +++ b/src/client/providers/jediProxy.ts @@ -142,14 +142,14 @@ export class JediProxy implements vscode.Disposable { return this.cmdId++; } - // keep track of the directory so we can re-spawn the process + // keep track of the directory so we can re-spawn the process. private pythonProcessCWD = ""; private initialize(dir: string) { this.pythonProcessCWD = dir; this.spawnProcess(path.join(dir, "pythonFiles")); } - // Check if settings changes + // Check if settings changes. private lastKnownPythonInterpreter: string; private onPythonSettingsChanged() { if (this.lastKnownPythonInterpreter === this.pythonSettings.pythonPath) { @@ -200,11 +200,11 @@ export class JediProxy implements vscode.Disposable { if (typeof this.pythonSettings.jediPath !== 'string' || this.pythonSettings.jediPath.length === 0) { if (Array.isArray(this.pythonSettings.devOptions) && this.pythonSettings.devOptions.some(item => item.toUpperCase().trim() === 'USERELEASEAUTOCOMP')) { - // Use standard version of jedi library + // Use standard version of jedi library. args.push('std'); } else { - // Use preview version of jedi library + // Use preview version of jedi library. args.push('preview'); } } @@ -242,8 +242,8 @@ export class JediProxy implements vscode.Disposable { }); this.proc.stdout.setEncoding('utf8'); this.proc.stdout.on("data", (data: string) => { - //Possible there was an exception in parsing the data returned - //So append the data then parse it + // Possible there was an exception in parsing the data returned, + // so append the data then parse it. var dataStr = this.previousData = this.previousData + data + ""; var responses: any[]; try { @@ -251,8 +251,8 @@ export class JediProxy implements vscode.Disposable { this.previousData = ""; } catch (ex) { - // Possible we've only received part of the data, hence don't clear previousData - // Don't log errors when we haven't received the entire response + // Possible we've only received part of the data, hence don't clear previousData. + // Don't log errors when we haven't received the entire response. if (ex.message.indexOf('Unexpected end of input') === -1 && ex.message.indexOf('Unexpected end of JSON input') === -1 && ex.message.indexOf('Unexpected token') === -1) { @@ -263,8 +263,8 @@ export class JediProxy implements vscode.Disposable { responses.forEach((response) => { // What's this, can't remember, - // Great example of poorly written code (this whole file is a mess) - // I think this needs to be removed, because this is misspelt, it is argments, 'U' is missing + // Great example of poorly written code (this whole file is a mess). + // I think this needs to be removed, because this is misspelt, it is argments, 'U' is missing, // And that case is handled further down // case CommandType.Arguments: { // Rewrite this mess to use stratergy.. @@ -286,7 +286,7 @@ export class JediProxy implements vscode.Disposable { // telemetryHelper.sendTelemetryEvent(cmd.telemetryEvent, null, cmd.delays.toMeasures()); } - // Check if this command has expired + // Check if this command has expired. if (cmd.token.isCancellationRequested) { cmd.deferred.resolve(); return; @@ -416,7 +416,7 @@ export class JediProxy implements vscode.Disposable { } } - //Ok, check if too many pending requets + //Ok, check if too many pending requets. if (this.commandQueue.length > 10) { var items = this.commandQueue.splice(0, this.commandQueue.length - 10); items.forEach(id => { @@ -452,7 +452,7 @@ export class JediProxy implements vscode.Disposable { } catch (ex) { console.error(ex); - //If 'This socket is closed.' that means process didn't start at all (at least not properly) + //If 'This socket is closed.' that means process didn't start at all (at least not properly). if (ex.message === "This socket is closed.") { this.killProcess(); @@ -499,20 +499,20 @@ export class JediProxy implements vscode.Disposable { }); } private onConfigChanged() { - // We're only interested in changes to the python path + // We're only interested in changes to the python path. if (this.lastKnownPythonPath === this.pythonSettings.pythonPath) { return; } this.lastKnownPythonPath = this.pythonSettings.pythonPath; let filePaths = [ - // Sysprefix + // Sysprefix. this.getPathFromPythonCommand(["-c", "import sys;print(sys.prefix)"]), - // exeucutable path + // exeucutable path. this.getPathFromPythonCommand(["-c", "import sys;print(sys.executable)"]), - // Python specific site packages + // Python specific site packages. this.getPathFromPythonCommand(["-c", "from distutils.sysconfig import get_python_lib; print(get_python_lib())"]), - // Python global site packages, as a fallback in case user hasn't installed them in custom environment + // Python global site packages, as a fallback in case user hasn't installed them in custom environment. this.getPathFromPythonCommand(["-m", "site", "--user-site"]), ]; @@ -531,23 +531,25 @@ export class JediProxy implements vscode.Disposable { if (typeof PYTHONPATH === 'string' && PYTHONPATH.length > 0) { filePaths.push(Promise.resolve(PYTHONPATH.trim())); } - Promise.all(filePaths).then(paths => { - // Last item return a path, we need only the folder - if (paths[1].length > 0) { - paths[1] = path.dirname(paths[1]); - } + Promise.all(filePaths) + .then(paths => { + // Last item return a path, we need only the folder. + if (paths[1].length > 0) { + paths[1] = path.dirname(paths[1]); + } - // On windows we also need the libs path (second item will return c:\xxx\lib\site-packages) - // This is returned by "from distutils.sysconfig import get_python_lib; print(get_python_lib())" - if (IS_WINDOWS && paths[2].length > 0) { - paths.splice(3, 0, path.join(paths[2], "..")); - } - this.additionalAutoCopletePaths = paths.filter(p => p.length > 0); - }); + // On windows we also need the libs path (second item will return c:\xxx\lib\site-packages). + // This is returned by "from distutils.sysconfig import get_python_lib; print(get_python_lib())". + if (IS_WINDOWS && paths[2].length > 0) { + paths.splice(3, 0, path.join(paths[2], "..")); + } + this.additionalAutoCopletePaths = paths.filter(p => p.length > 0); + }) + .catch(ex => console.error('Python Extension: jediProxy.filePaths', ex)); } private getConfig() { - // Add support for paths relative to workspace + // Add support for paths relative to workspace. let extraPaths = this.pythonSettings.autoComplete.extraPaths.map(extraPath => { if (path.isAbsolute(extraPath)) { return extraPath; @@ -558,7 +560,7 @@ export class JediProxy implements vscode.Disposable { return path.join(this.workspacePath, extraPath); }); - // Always add workspace path into extra paths + // Always add workspace path into extra paths. if (typeof this.workspacePath === 'string') { extraPaths.unshift(this.workspacePath); } diff --git a/src/client/providers/lintProvider.ts b/src/client/providers/lintProvider.ts index 3ff52039b384..1c9d79ce60cd 100644 --- a/src/client/providers/lintProvider.ts +++ b/src/client/providers/lintProvider.ts @@ -94,7 +94,7 @@ export class LintProvider implements vscode.Disposable { if (e.languageId !== 'python' || !settings.linting.enabled) { return; } - // Exclude files opened by vscode when showing a diff view + // Exclude files opened by vscode when showing a diff view. if (uriSchemesToIgnore.indexOf(e.uri.scheme) >= 0) { return; } @@ -109,7 +109,7 @@ export class LintProvider implements vscode.Disposable { return; } - // Check if this document is still open as a duplicate editor + // Check if this document is still open as a duplicate editor. if (!this.isDocumentOpen(textDocument.uri) && this.diagnosticCollection.has(textDocument.uri)) { this.diagnosticCollection.set(textDocument.uri, []); } @@ -142,8 +142,8 @@ export class LintProvider implements vscode.Disposable { // tslint:disable-next-line:member-ordering no-any private lastTimeout: any; private lintDocument(document: vscode.TextDocument, delay: number, trigger: 'auto' | 'save'): void { - // Since this is a hack, lets wait for 2 seconds before linting - // Give user to continue typing before we waste CPU time + // Since this is a hack, lets wait for 2 seconds before linting. + // Give user to continue typing before we waste CPU time. if (this.lastTimeout) { clearTimeout(this.lastTimeout); this.lastTimeout = 0; @@ -196,39 +196,42 @@ export class LintProvider implements vscode.Disposable { sendTelemetryWhenDone(LINTING, promise, stopWatch, { tool: item.Id, hasCustomArgs, trigger, executableSpecified }); return promise; }); - this.documentHasJupyterCodeCells(document, cancelToken.token).then(hasJupyterCodeCells => { - // linters will resolve asynchronously - keep a track of all - // diagnostics reported as them come in. - let diagnostics: vscode.Diagnostic[] = []; - - promises.forEach(p => { - p.then(msgs => { - if (cancelToken.token.isCancellationRequested) { - return; - } - - // Build the message and suffix the message with the name of the linter used - msgs.forEach(d => { - // ignore magic commands from jupyter - if (hasJupyterCodeCells && document.lineAt(d.line - 1).text.trim().startsWith('%') && - (d.code === LinterErrors.pylint.InvalidSyntax || - d.code === LinterErrors.prospector.InvalidSyntax || - d.code === LinterErrors.flake8.InvalidSyntax)) { + this.documentHasJupyterCodeCells(document, cancelToken.token) + .then(hasJupyterCodeCells => { + // linters will resolve asynchronously - keep a track of all + // diagnostics reported as them come in. + let diagnostics: vscode.Diagnostic[] = []; + + promises.forEach(p => { + p.then(msgs => { + if (cancelToken.token.isCancellationRequested) { return; } - diagnostics.push(createDiagnostics(d, document)); - }); - // Limit the number of messages to the max value - diagnostics = diagnostics.filter((value, index) => index <= settings.linting.maxNumberOfProblems); - - if (!this.isDocumentOpen(document.uri)) { - diagnostics = []; - } - // set all diagnostics found in this pass, as this method always clears existing diagnostics. - this.diagnosticCollection.set(document.uri, diagnostics); + // Build the message and suffix the message with the name of the linter used. + msgs.forEach(d => { + // Ignore magic commands from jupyter. + if (hasJupyterCodeCells && document.lineAt(d.line - 1).text.trim().startsWith('%') && + (d.code === LinterErrors.pylint.InvalidSyntax || + d.code === LinterErrors.prospector.InvalidSyntax || + d.code === LinterErrors.flake8.InvalidSyntax)) { + return; + } + diagnostics.push(createDiagnostics(d, document)); + }); + + // Limit the number of messages to the max value. + diagnostics = diagnostics.filter((value, index) => index <= settings.linting.maxNumberOfProblems); + + if (!this.isDocumentOpen(document.uri)) { + diagnostics = []; + } + // Set all diagnostics found in this pass, as this method always clears existing diagnostics. + this.diagnosticCollection.set(document.uri, diagnostics); + }) + .catch(ex => console.error('Python Extension: documentHasJupyterCodeCells.promises', ex)); }); - }); - }); + }) + .catch(ex => console.error('Python Extension: documentHasJupyterCodeCells', ex)); } } diff --git a/src/client/providers/renameProvider.ts b/src/client/providers/renameProvider.ts index b1cdad8dce50..1997a65f0e9d 100644 --- a/src/client/providers/renameProvider.ts +++ b/src/client/providers/renameProvider.ts @@ -56,7 +56,8 @@ export class PythonRenameProvider implements vscode.RenameProvider { return getWorkspaceEditsFromPatch(fileDiffs, workspaceRoot); }).catch(reason => { if (reason === 'Not installed') { - this.installer.promptToInstall(Product.rope, document.uri); + this.installer.promptToInstall(Product.rope, document.uri) + .catch(ex => console.error('Python Extension: promptToInstall', ex)); return Promise.reject(''); } else { vscode.window.showErrorMessage(reason); diff --git a/src/client/providers/simpleRefactorProvider.ts b/src/client/providers/simpleRefactorProvider.ts index ad8d94686b7d..588b3cb06dea 100644 --- a/src/client/providers/simpleRefactorProvider.ts +++ b/src/client/providers/simpleRefactorProvider.ts @@ -151,7 +151,8 @@ function extractName(extensionDir: string, textEditor: vscode.TextEditor, range: } }).catch(error => { if (error === 'Not installed') { - installer.promptToInstall(Product.rope, textEditor.document.uri); + installer.promptToInstall(Product.rope, textEditor.document.uri) + .catch(ex => console.error('Python Extension: simpleRefactorProvider.promptToInstall', ex)); return Promise.reject(''); } let errorMessage = error + ''; diff --git a/src/client/refactor/proxy.ts b/src/client/refactor/proxy.ts index d434f522c0c7..9be8271a396e 100644 --- a/src/client/refactor/proxy.ts +++ b/src/client/refactor/proxy.ts @@ -94,6 +94,7 @@ export class RefactorProxy extends vscode.Disposable { } private sendCommand(command: string, telemetryEvent?: string): Promise { return this.initialize(this.pythonSettings.pythonPath).then(() => { + // tslint:disable-next-line:promise-must-complete return new Promise((resolve, reject) => { this._commandResolve = resolve; this._commandReject = reject; diff --git a/src/client/telemetry/stopWatch.ts b/src/client/telemetry/stopWatch.ts index 7b29fdc763fc..3e2a2132e94d 100644 --- a/src/client/telemetry/stopWatch.ts +++ b/src/client/telemetry/stopWatch.ts @@ -5,11 +5,7 @@ export class StopWatch { private started: number = Date.now(); - private stopped?: number; public get elapsedTime() { - return (this.stopped ? this.stopped : Date.now()) - this.started; - } - public stop() { - this.stopped = Date.now(); + return Date.now() - this.started; } } diff --git a/src/client/unittests/common/constants.ts b/src/client/unittests/common/constants.ts index 9bd66948c6e3..e361f4479bcf 100644 --- a/src/client/unittests/common/constants.ts +++ b/src/client/unittests/common/constants.ts @@ -1,3 +1,5 @@ +import { TestProvider } from './types'; + export const CANCELLATION_REASON = 'cancelled_user_request'; export enum CommandSource { auto = 'auto', @@ -5,3 +7,7 @@ export enum CommandSource { codelens = 'codelens', commandPalette = 'commandpalette' } +export const TEST_OUTPUT_CHANNEL = 'TEST_OUTPUT_CHANNEL'; +export const NOSETEST_PROVIDER: TestProvider = 'nosetest'; +export const PYTEST_PROVIDER: TestProvider = 'pytest'; +export const UNITTEST_PROVIDER: TestProvider = 'unittest'; diff --git a/src/client/unittests/common/debugLauncher.ts b/src/client/unittests/common/debugLauncher.ts index a5afa317f055..4e408a51fa34 100644 --- a/src/client/unittests/common/debugLauncher.ts +++ b/src/client/unittests/common/debugLauncher.ts @@ -1,81 +1,90 @@ import * as getFreePort from 'get-port'; +import { inject, injectable } from 'inversify'; import * as os from 'os'; -import { CancellationToken, debug, OutputChannel, Uri, workspace } from 'vscode'; +import 'reflect-metadata'; +import { debug, Uri, workspace } from 'vscode'; import { PythonSettings } from '../../common/configSettings'; +import { IPythonExecutionFactory } from '../../common/process/types'; import { createDeferred } from './../../common/helpers'; -import { execPythonFile } from './../../common/utils'; -import { ITestDebugLauncher } from './types'; +import { ITestDebugLauncher, launchOptions } from './types'; const HAND_SHAKE = `READY${os.EOL}`; +@injectable() export class DebugLauncher implements ITestDebugLauncher { + constructor( @inject(IPythonExecutionFactory) private pythonExecutionFactory: IPythonExecutionFactory) { } public getPort(resource?: Uri): Promise { const pythonSettings = PythonSettings.getInstance(resource); const port = pythonSettings.unitTest.debugPort; return new Promise((resolve, reject) => getFreePort({ host: 'localhost', port }).then(resolve, reject)); } - public async launchDebugger(rootDirectory: string, testArgs: string[], port: number, token?: CancellationToken, outChannel?: OutputChannel) { - const pythonSettings = PythonSettings.getInstance(rootDirectory ? Uri.file(rootDirectory) : undefined); - // tslint:disable-next-line:no-any - const def = createDeferred(); - // tslint:disable-next-line:no-any - const launchDef = createDeferred(); - let outputChannelShown = false; - let accumulatedData: string = ''; - execPythonFile(rootDirectory, pythonSettings.pythonPath, testArgs, rootDirectory, true, (data: string) => { - if (!launchDef.resolved) { - accumulatedData += data; - if (!accumulatedData.startsWith(HAND_SHAKE)) { - return; - } - // Socket server has started, lets start the debugger. - launchDef.resolve(); - data = accumulatedData.substring(HAND_SHAKE.length); - } + public async launchDebugger(options: launchOptions) { + const cwdUri = options.cwd ? Uri.file(options.cwd) : undefined; + return this.pythonExecutionFactory.create(cwdUri) + .then(executionService => { + // tslint:disable-next-line:no-any + const def = createDeferred(); + // tslint:disable-next-line:no-any + const launchDef = createDeferred(); - if (!outputChannelShown) { - outputChannelShown = true; - outChannel.show(); - } - outChannel.append(data); - }, token).catch(reason => { - if (!def.rejected && !def.resolved) { - def.reject(reason); - } - }).then(() => { - if (!def.rejected && !def.resolved) { - def.resolve(); - } - }).catch(reason => { - if (!def.rejected && !def.resolved) { - def.reject(reason); - } - }); + let outputChannelShown = false; + let accumulatedData: string = ''; + const result = executionService.execObservable(options.args, { cwd: options.cwd, mergeStdOutErr: true, token: options.token }); + result.out.subscribe(output => { + let data = output.out; + if (!launchDef.resolved) { + accumulatedData += output.out; + if (!accumulatedData.startsWith(HAND_SHAKE)) { + return; + } + // Socket server has started, lets start the vs debugger. + launchDef.resolve(); + data = accumulatedData.substring(HAND_SHAKE.length); + } - launchDef.promise.then(() => { - if (!Array.isArray(workspace.workspaceFolders) || workspace.workspaceFolders.length === 0) { - throw new Error('Please open a workspace'); - } - let workspaceFolder = workspace.getWorkspaceFolder(Uri.file(rootDirectory)); - if (!workspaceFolder) { - workspaceFolder = workspace.workspaceFolders[0]; - } - return debug.startDebugging(workspaceFolder, { - name: 'Debug Unit Test', - type: 'python', - request: 'attach', - localRoot: rootDirectory, - remoteRoot: rootDirectory, - port, - secret: 'my_secret', - host: 'localhost' - }); - }).catch(reason => { - if (!def.rejected && !def.resolved) { - def.reject(reason); - } - }); + if (!outputChannelShown) { + outputChannelShown = true; + options.outChannel!.show(); + } + options.outChannel!.append(data); + }, error => { + if (!def.completed) { + def.reject(error); + } + }, () => { + // Complete only when the process has completed. + if (!def.completed) { + def.resolve(); + } + }); + + launchDef.promise + .then(() => { + if (!Array.isArray(workspace.workspaceFolders) || workspace.workspaceFolders.length === 0) { + throw new Error('Please open a workspace'); + } + let workspaceFolder = workspace.getWorkspaceFolder(cwdUri!); + if (!workspaceFolder) { + workspaceFolder = workspace.workspaceFolders[0]; + } + return debug.startDebugging(workspaceFolder, { + name: 'Debug Unit Test', + type: 'python', + request: 'attach', + localRoot: options.cwd, + remoteRoot: options.cwd, + port: options.port, + secret: 'my_secret', + host: 'localhost' + }); + }) + .catch(reason => { + if (!def.completed) { + def.reject(reason); + } + }); - return def.promise; + return def.promise; + }); } } diff --git a/src/client/unittests/common/baseTestManager.ts b/src/client/unittests/common/managers/baseTestManager.ts similarity index 72% rename from src/client/unittests/common/baseTestManager.ts rename to src/client/unittests/common/managers/baseTestManager.ts index 029f09fabc0e..329680bb9d23 100644 --- a/src/client/unittests/common/baseTestManager.ts +++ b/src/client/unittests/common/managers/baseTestManager.ts @@ -1,38 +1,51 @@ -// import {TestFolder, TestsToRun, Tests, TestFile, TestSuite, TestFunction, TestStatus, FlattenedTestFunction, FlattenedTestSuite, CANCELLATION_REASON} from './contracts'; import * as vscode from 'vscode'; -import { Uri, workspace } from 'vscode'; -import { IPythonSettings, PythonSettings } from '../../common/configSettings'; -import { isNotInstalledError } from '../../common/helpers'; -import { Installer, Product } from '../../common/installer'; -import { UNITTEST_DISCOVER, UNITTEST_RUN } from '../../telemetry/constants'; -import { sendTelemetryEvent } from '../../telemetry/index'; -import { TestDiscoverytTelemetry, TestRunTelemetry } from '../../telemetry/types'; -import { CANCELLATION_REASON, CommandSource } from './constants'; -import { displayTestErrorMessage } from './testUtils'; -import { ITestCollectionStorageService, ITestResultsService, ITestsHelper, Tests, TestStatus, TestsToRun } from './types'; +import { Disposable, OutputChannel, Uri, workspace } from 'vscode'; +import { IPythonSettings, PythonSettings } from '../../../common/configSettings'; +import { isNotInstalledError } from '../../../common/helpers'; +import { Installer, Product } from '../../../common/installer'; +import { IDiposableRegistry, IOutputChannel } from '../../../common/types'; +import { IServiceContainer } from '../../../ioc/types'; +import { UNITTEST_DISCOVER, UNITTEST_RUN } from '../../../telemetry/constants'; +import { sendTelemetryEvent } from '../../../telemetry/index'; +import { TestDiscoverytTelemetry, TestRunTelemetry } from '../../../telemetry/types'; +import { CANCELLATION_REASON, CommandSource, TEST_OUTPUT_CHANNEL } from './../constants'; +import { displayTestErrorMessage } from './../testUtils'; +import { ITestCollectionStorageService, ITestDiscoveryService, ITestManager, ITestResultsService } from './../types'; +import { TestDiscoveryOptions, TestProvider, Tests, TestStatus, TestsToRun } from './../types'; enum CancellationTokenType { testDiscovery, testRunner } -type TestProvider = 'nosetest' | 'pytest' | 'unittest'; -export abstract class BaseTestManager { - public readonly workspace: Uri; + +export abstract class BaseTestManager implements ITestManager { protected readonly settings: IPythonSettings; - private tests: Tests; + protected get outputChannel() { + return this._outputChannel; + } + protected get testResultsService() { + return this._testResultsService; + } + private testCollectionStorage: ITestCollectionStorageService; + private _testResultsService: ITestResultsService; + private _outputChannel: OutputChannel; + private tests?: Tests; // tslint:disable-next-line:variable-name private _status: TestStatus = TestStatus.Unknown; - private testDiscoveryCancellationTokenSource: vscode.CancellationTokenSource; - private testRunnerCancellationTokenSource: vscode.CancellationTokenSource; + private testDiscoveryCancellationTokenSource?: vscode.CancellationTokenSource; + private testRunnerCancellationTokenSource?: vscode.CancellationTokenSource; private installer: Installer; - private discoverTestsPromise: Promise; - constructor(public readonly testProvider: TestProvider, private product: Product, protected rootDirectory: string, - protected outputChannel: vscode.OutputChannel, private testCollectionStorage: ITestCollectionStorageService, - protected testResultsService: ITestResultsService, protected testsHelper: ITestsHelper) { + private discoverTestsPromise?: Promise; + constructor(public readonly testProvider: TestProvider, private product: Product, public readonly workspaceFolder: Uri, protected rootDirectory: string, + protected serviceContainer: IServiceContainer) { this._status = TestStatus.Unknown; this.installer = new Installer(); this.settings = PythonSettings.getInstance(this.rootDirectory ? Uri.file(this.rootDirectory) : undefined); - this.workspace = workspace.getWorkspaceFolder(Uri.file(this.rootDirectory)).uri; + const disposables = serviceContainer.get(IDiposableRegistry); + disposables.push(this); + this._outputChannel = this.serviceContainer.get(IOutputChannel, TEST_OUTPUT_CHANNEL); + this.testCollectionStorage = this.serviceContainer.get(ITestCollectionStorageService); + this._testResultsService = this.serviceContainer.get(ITestResultsService); } protected get testDiscoveryCancellationToken(): vscode.CancellationToken | undefined { return this.testDiscoveryCancellationTokenSource ? this.testDiscoveryCancellationTokenSource.token : undefined; @@ -60,23 +73,23 @@ export abstract class BaseTestManager { } public reset() { this._status = TestStatus.Unknown; - this.tests = null; + this.tests = undefined; } public resetTestResults() { if (!this.tests) { return; } - this.testResultsService.resetResults(this.tests); + this.testResultsService.resetResults(this.tests!); } public async discoverTests(cmdSource: CommandSource, ignoreCache: boolean = false, quietMode: boolean = false, userInitiated: boolean = false): Promise { if (this.discoverTestsPromise) { - return this.discoverTestsPromise; + return this.discoverTestsPromise!; } - if (!ignoreCache && this.tests && this.tests.testFunctions.length > 0) { + if (!ignoreCache && this.tests! && this.tests!.testFunctions.length > 0) { this._status = TestStatus.Idle; - return Promise.resolve(this.tests); + return Promise.resolve(this.tests!); } this._status = TestStatus.Discovering; @@ -93,12 +106,14 @@ export abstract class BaseTestManager { }; this.createCancellationToken(CancellationTokenType.testDiscovery); - return this.discoverTestsPromise = this.discoverTestsImpl(ignoreCache) + const discoveryOptions = this.getDiscoveryOptions(ignoreCache); + const discoveryService = this.serviceContainer.get(ITestDiscoveryService, this.testProvider); + return discoveryService.discoverTests(discoveryOptions) .then(tests => { this.tests = tests; this._status = TestStatus.Idle; this.resetTestResults(); - this.discoverTestsPromise = null; + this.discoverTestsPromise = undefined; // have errors in Discovering let haveErrorsInDiscovering = false; @@ -114,19 +129,19 @@ export abstract class BaseTestManager { if (haveErrorsInDiscovering && !quietMode) { displayTestErrorMessage('There were some errors in discovering unit tests'); } - const wkspace = vscode.workspace.getWorkspaceFolder(vscode.Uri.file(this.rootDirectory)).uri; + const wkspace = workspace.getWorkspaceFolder(vscode.Uri.file(this.rootDirectory))!.uri; this.testCollectionStorage.storeTests(wkspace, tests); this.disposeCancellationToken(CancellationTokenType.testDiscovery); sendTelemetryEvent(UNITTEST_DISCOVER, undefined, telementryProperties); return tests; - }).catch(reason => { - if (isNotInstalledError(reason) && !quietMode) { - // tslint:disable-next-line:no-floating-promises - this.installer.promptToInstall(this.product, this.workspace); + }).catch((reason: {}) => { + if (isNotInstalledError(reason as Error) && !quietMode) { + this.installer.promptToInstall(this.product, this.workspaceFolder) + .catch(ex => console.error('Python Extension: isNotInstalledError', ex)); } - this.tests = null; - this.discoverTestsPromise = null; + this.tests = undefined; + this.discoverTestsPromise = undefined; if (this.testDiscoveryCancellationToken && this.testDiscoveryCancellationToken.isCancellationRequested) { reason = CANCELLATION_REASON; this._status = TestStatus.Idle; @@ -136,9 +151,9 @@ export abstract class BaseTestManager { this._status = TestStatus.Error; this.outputChannel.appendLine('Test Discovery failed: '); // tslint:disable-next-line:prefer-template - this.outputChannel.appendLine('' + reason); + this.outputChannel.appendLine(reason.toString()); } - const wkspace = vscode.workspace.getWorkspaceFolder(vscode.Uri.file(this.rootDirectory)).uri; + const wkspace = workspace.getWorkspaceFolder(vscode.Uri.file(this.rootDirectory))!.uri; this.testCollectionStorage.storeTests(wkspace, null); this.disposeCancellationToken(CancellationTokenType.testDiscovery); return Promise.reject(reason); @@ -161,7 +176,7 @@ export abstract class BaseTestManager { }; if (runFailedTests === true) { // tslint:disable-next-line:prefer-template - moreInfo.Run_Failed_Tests = runFailedTests + ''; + moreInfo.Run_Failed_Tests = runFailedTests.toString(); telementryProperties.scope = 'failed'; } if (testsToRun && typeof testsToRun === 'object') { @@ -209,7 +224,7 @@ export abstract class BaseTestManager { this._status = TestStatus.Idle; this.disposeCancellationToken(CancellationTokenType.testRunner); sendTelemetryEvent(UNITTEST_RUN, undefined, telementryProperties); - return this.tests; + return this.tests!; }).catch(reason => { if (this.testRunnerCancellationToken && this.testRunnerCancellationToken.isCancellationRequested) { reason = CANCELLATION_REASON; @@ -225,7 +240,7 @@ export abstract class BaseTestManager { } // tslint:disable-next-line:no-any protected abstract runTestImpl(tests: Tests, testsToRun?: TestsToRun, runFailedTests?: boolean, debug?: boolean): Promise; - protected abstract discoverTestsImpl(ignoreCache: boolean, debug?: boolean): Promise; + protected abstract getDiscoveryOptions(ignoreCache: boolean): TestDiscoveryOptions; private createCancellationToken(tokenType: CancellationTokenType) { this.disposeCancellationToken(tokenType); if (tokenType === CancellationTokenType.testDiscovery) { @@ -239,12 +254,12 @@ export abstract class BaseTestManager { if (this.testDiscoveryCancellationTokenSource) { this.testDiscoveryCancellationTokenSource.dispose(); } - this.testDiscoveryCancellationTokenSource = null; + this.testDiscoveryCancellationTokenSource = undefined; } else { if (this.testRunnerCancellationTokenSource) { this.testRunnerCancellationTokenSource.dispose(); } - this.testRunnerCancellationTokenSource = null; + this.testRunnerCancellationTokenSource = undefined; } } } diff --git a/src/client/unittests/common/testConfigurationManager.ts b/src/client/unittests/common/managers/testConfigurationManager.ts similarity index 93% rename from src/client/unittests/common/testConfigurationManager.ts rename to src/client/unittests/common/managers/testConfigurationManager.ts index afdad0192c87..9861c3afe5e4 100644 --- a/src/client/unittests/common/testConfigurationManager.ts +++ b/src/client/unittests/common/managers/testConfigurationManager.ts @@ -1,10 +1,10 @@ import * as path from 'path'; import * as vscode from 'vscode'; import { Uri } from 'vscode'; -import { createDeferred } from '../../common/helpers'; -import { Installer } from '../../common/installer'; -import { getSubDirectories } from '../../common/utils'; -import { ITestConfigSettingsService, UnitTestProduct } from './types'; +import { createDeferred } from '../../../common/helpers'; +import { Installer } from '../../../common/installer'; +import { getSubDirectories } from '../../../common/utils'; +import { ITestConfigSettingsService, UnitTestProduct } from './../types'; export abstract class TestConfigurationManager { constructor(protected workspace: Uri, diff --git a/src/client/unittests/common/runner.ts b/src/client/unittests/common/runner.ts index de3b90245e6e..554eeaca3b97 100644 --- a/src/client/unittests/common/runner.ts +++ b/src/client/unittests/common/runner.ts @@ -1,7 +1,92 @@ -import { CancellationToken, OutputChannel, window, workspace } from 'vscode'; -import { IS_WINDOWS, PATH_VARIABLE_NAME } from '../../common/utils'; -import { execPythonFile } from './../../common/utils'; +import * as path from 'path'; +import { CancellationToken, OutputChannel, Uri } from 'vscode'; +import { IPythonSettings, PythonSettings } from '../../common/configSettings'; +import { IProcessService, IPythonExecutionFactory, ObservableExecutionResult, SpawnOptions } from '../../common/process/types'; +import { IEnvironmentVariablesProvider } from '../../common/variables/types'; +import { IServiceContainer } from '../../ioc/types'; +import { NOSETEST_PROVIDER, PYTEST_PROVIDER, UNITTEST_PROVIDER } from './constants'; +import { TestProvider } from './types'; -export async function run(file: string, args: string[], cwd: string, token?: CancellationToken, outChannel?: OutputChannel): Promise { - return execPythonFile(cwd, file, args, cwd, true, (data: string) => outChannel.append(data), token); +export type Options = { + workspaceFolder: Uri; + cwd: string; + args: string[]; + outChannel?: OutputChannel; + token: CancellationToken; +}; + +export async function run(serviceContainer: IServiceContainer, testProvider: TestProvider, options: Options): Promise { + const testExecutablePath = getExecutablePath(testProvider, PythonSettings.getInstance(options.workspaceFolder)); + const moduleName = getTestModuleName(testProvider); + const spawnOptions = options as SpawnOptions; + spawnOptions.mergeStdOutErr = typeof spawnOptions.mergeStdOutErr === 'boolean' ? spawnOptions.mergeStdOutErr : true; + + let promise: Promise>; + + if (!testExecutablePath && testProvider === UNITTEST_PROVIDER) { + // Unit tests have a special way of being executed + const pythonServiceFactory = serviceContainer.get(IPythonExecutionFactory); + const pythonExecutionService = pythonServiceFactory.create(options.workspaceFolder); + promise = pythonExecutionService.then(executionService => { + return executionService.execObservable(options.args, { ...spawnOptions }); + }); + } else if (testExecutablePath) { + const processService = serviceContainer.get(IProcessService); + const envVarsService = serviceContainer.get(IEnvironmentVariablesProvider); + promise = envVarsService.getEnvironmentVariables(true, options.workspaceFolder).then(executionService => { + return processService.execObservable(testExecutablePath, options.args, { ...spawnOptions }); + }); + } else { + const pythonServiceFactory = serviceContainer.get(IPythonExecutionFactory); + const pythonExecutionService = pythonServiceFactory.create(options.workspaceFolder); + promise = pythonExecutionService.then(executionService => { + return executionService.execModuleObservable(moduleName, options.args, { ...spawnOptions }); + }); + } + + return promise.then(result => { + return new Promise((resolve, reject) => { + let stdOut = ''; + result.out.subscribe(output => { + stdOut += output.out; + if (options.outChannel) { + options.outChannel.append(output.out); + } + }, reject, () => resolve(stdOut)); + }); + }); +} + +function getExecutablePath(testProvider: TestProvider, settings: IPythonSettings): string | undefined { + let testRunnerExecutablePath: string | undefined; + switch (testProvider) { + case NOSETEST_PROVIDER: { + testRunnerExecutablePath = settings.unitTest.nosetestPath; + break; + } + case PYTEST_PROVIDER: { + testRunnerExecutablePath = settings.unitTest.pyTestPath; + break; + } + default: { + return undefined; + } + } + return path.basename(testRunnerExecutablePath) === testRunnerExecutablePath ? undefined : testRunnerExecutablePath; +} +function getTestModuleName(testProvider: TestProvider) { + switch (testProvider) { + case NOSETEST_PROVIDER: { + return 'nose'; + } + case PYTEST_PROVIDER: { + return 'pytest'; + } + case UNITTEST_PROVIDER: { + return 'unittest'; + } + default: { + throw new Error(`Test provider '${testProvider}' not supported`); + } + } } diff --git a/src/client/unittests/common/configSettingService.ts b/src/client/unittests/common/services/configSettingService.ts similarity index 96% rename from src/client/unittests/common/configSettingService.ts rename to src/client/unittests/common/services/configSettingService.ts index f6a90619f9fe..02a31597f673 100644 --- a/src/client/unittests/common/configSettingService.ts +++ b/src/client/unittests/common/services/configSettingService.ts @@ -1,6 +1,6 @@ import { ConfigurationTarget, Uri, workspace, WorkspaceConfiguration } from 'vscode'; -import { Product } from '../../common/installer'; -import { ITestConfigSettingsService, UnitTestProduct } from './types'; +import { Product } from '../../../common/installer'; +import { ITestConfigSettingsService, UnitTestProduct } from './../types'; export class TestConfigSettingsService implements ITestConfigSettingsService { private static getTestArgSetting(product: UnitTestProduct) { diff --git a/src/client/unittests/common/storageService.ts b/src/client/unittests/common/services/storageService.ts similarity index 64% rename from src/client/unittests/common/storageService.ts rename to src/client/unittests/common/services/storageService.ts index 775750de1fe9..d62c4c1dedcd 100644 --- a/src/client/unittests/common/storageService.ts +++ b/src/client/unittests/common/services/storageService.ts @@ -1,13 +1,20 @@ -import { Uri, workspace } from 'vscode'; -import { ITestCollectionStorageService, Tests } from './types'; +import { inject, injectable } from 'inversify'; +import 'reflect-metadata'; +import { Disposable, Uri, workspace } from 'vscode'; +import { IDiposableRegistry } from '../../../common/types'; +import { ITestCollectionStorageService, Tests } from './../types'; +@injectable() export class TestCollectionStorageService implements ITestCollectionStorageService { - private testsIndexedByWorkspaceUri = new Map(); + private testsIndexedByWorkspaceUri = new Map(); + constructor( @inject(IDiposableRegistry) disposables: Disposable[]) { + disposables.push(this); + } public getTests(wkspace: Uri): Tests | undefined { const workspaceFolder = this.getWorkspaceFolderPath(wkspace) || ''; return this.testsIndexedByWorkspaceUri.has(workspaceFolder) ? this.testsIndexedByWorkspaceUri.get(workspaceFolder) : undefined; } - public storeTests(wkspace: Uri, tests: Tests | null | undefined): void { + public storeTests(wkspace: Uri, tests: Tests | undefined): void { const workspaceFolder = this.getWorkspaceFolderPath(wkspace) || ''; this.testsIndexedByWorkspaceUri.set(workspaceFolder, tests); } diff --git a/src/client/unittests/common/services/testManagerService.ts b/src/client/unittests/common/services/testManagerService.ts new file mode 100644 index 000000000000..76d422c0fb07 --- /dev/null +++ b/src/client/unittests/common/services/testManagerService.ts @@ -0,0 +1,50 @@ +import { Disposable, Uri } from 'vscode'; +import { PythonSettings } from '../../../common/configSettings'; +import { Product } from '../../../common/installer'; +import { IDiposableRegistry } from '../../../common/types'; +import { IServiceContainer } from '../../../ioc/types'; +import { ITestManager, ITestManagerFactory, ITestManagerService, ITestsHelper, UnitTestProduct } from './../types'; + +export class TestManagerService implements ITestManagerService { + private cachedTestManagers = new Map(); + constructor(private wkspace: Uri, private testsHelper: ITestsHelper, private serviceContainer: IServiceContainer) { + const disposables = serviceContainer.get(IDiposableRegistry); + disposables.push(this); + } + public dispose() { + this.cachedTestManagers.forEach(info => { + info.dispose(); + }); + } + public getTestManager(): ITestManager | undefined { + const preferredTestManager = this.getPreferredTestManager(); + if (typeof preferredTestManager !== 'number') { + return; + } + + // tslint:disable-next-line:no-non-null-assertion + const instance = this.cachedTestManagers.get(preferredTestManager); + if (!instance) { + const testDirectory = this.getTestWorkingDirectory(); + const testProvider = this.testsHelper.parseProviderName(preferredTestManager); + const factory = this.serviceContainer.get(ITestManagerFactory); + this.cachedTestManagers.set(preferredTestManager, factory(testProvider, this.wkspace, testDirectory)); + } + return this.cachedTestManagers.get(preferredTestManager)!; + } + public getTestWorkingDirectory() { + const settings = PythonSettings.getInstance(this.wkspace); + return settings.unitTest.cwd && settings.unitTest.cwd.length > 0 ? settings.unitTest.cwd : this.wkspace.fsPath; + } + public getPreferredTestManager(): UnitTestProduct | undefined { + const settings = PythonSettings.getInstance(this.wkspace); + if (settings.unitTest.nosetestsEnabled) { + return Product.nosetest; + } else if (settings.unitTest.pyTestEnabled) { + return Product.pytest; + } else if (settings.unitTest.unittestEnabled) { + return Product.unittest; + } + return undefined; + } +} diff --git a/src/client/unittests/common/testResultsService.ts b/src/client/unittests/common/services/testResultsService.ts similarity index 68% rename from src/client/unittests/common/testResultsService.ts rename to src/client/unittests/common/services/testResultsService.ts index 8743b579d879..02e5f048e52d 100644 --- a/src/client/unittests/common/testResultsService.ts +++ b/src/client/unittests/common/services/testResultsService.ts @@ -1,13 +1,16 @@ -import { TestResultResetVisitor } from './testVisitors/resultResetVisitor'; -import { ITestResultsService, TestFile, TestFolder, Tests, TestStatus, TestSuite } from './types'; +import { inject, injectable, named } from 'inversify'; +import 'reflect-metadata'; +import { TestResultResetVisitor } from './../testVisitors/resultResetVisitor'; +import { ITestResultsService, ITestVisitor, TestFile, TestFolder, Tests, TestStatus, TestSuite } from './../types'; +@injectable() export class TestResultsService implements ITestResultsService { + constructor( @inject(ITestVisitor) @named('TestResultResetVisitor') private resultResetVisitor: ITestVisitor) { } public resetResults(tests: Tests): void { - const resultResetVisitor = new TestResultResetVisitor(); - tests.testFolders.forEach(f => resultResetVisitor.visitTestFolder(f)); - tests.testFunctions.forEach(fn => resultResetVisitor.visitTestFunction(fn.testFunction)); - tests.testSuites.forEach(suite => resultResetVisitor.visitTestSuite(suite.testSuite)); - tests.testFiles.forEach(testFile => resultResetVisitor.visitTestFile(testFile)); + tests.testFolders.forEach(f => this.resultResetVisitor.visitTestFolder(f)); + tests.testFunctions.forEach(fn => this.resultResetVisitor.visitTestFunction(fn.testFunction)); + tests.testSuites.forEach(suite => this.resultResetVisitor.visitTestSuite(suite.testSuite)); + tests.testFiles.forEach(testFile => this.resultResetVisitor.visitTestFile(testFile)); } public updateResults(tests: Tests): void { tests.testFiles.forEach(test => this.updateTestFileResults(test)); @@ -32,8 +35,8 @@ export class TestResultsService implements ITestResultsService { allFilesRan = false; } - testFolder.functionsFailed += fl.functionsFailed; - testFolder.functionsPassed += fl.functionsPassed; + testFolder.functionsFailed! += fl.functionsFailed!; + testFolder.functionsPassed! += fl.functionsPassed!; }); let allFoldersPassed = true; @@ -49,15 +52,15 @@ export class TestResultsService implements ITestResultsService { allFoldersRan = false; } - testFolder.functionsFailed += folder.functionsFailed; - testFolder.functionsPassed += folder.functionsPassed; + testFolder.functionsFailed! += folder.functionsFailed!; + testFolder.functionsPassed! += folder.functionsPassed!; }); if (allFilesRan && allFoldersRan) { testFolder.passed = allFilesPassed && allFoldersPassed; testFolder.status = testFolder.passed ? TestStatus.Idle : TestStatus.Fail; } else { - testFolder.passed = null; + testFolder.passed = undefined; testFolder.status = TestStatus.Unknown; } } @@ -70,9 +73,9 @@ export class TestResultsService implements ITestResultsService { totalTime += fn.time; if (typeof fn.passed === 'boolean') { if (fn.passed) { - test.functionsPassed += 1; + test.functionsPassed! += 1; } else { - test.functionsFailed += 1; + test.functionsFailed! += 1; allFunctionsPassed = false; } } else { @@ -94,8 +97,8 @@ export class TestResultsService implements ITestResultsService { allSuitesRan = false; } - test.functionsFailed += suite.functionsFailed; - test.functionsPassed += suite.functionsPassed; + test.functionsFailed! += suite.functionsFailed!; + test.functionsPassed! += suite.functionsPassed!; }); test.time = totalTime; @@ -103,7 +106,7 @@ export class TestResultsService implements ITestResultsService { test.passed = allFunctionsPassed && allSuitesPassed; test.status = test.passed ? TestStatus.Idle : TestStatus.Error; } else { - test.passed = null; + test.passed = undefined; test.status = TestStatus.Unknown; } } diff --git a/src/client/unittests/common/workspaceTestManagerService.ts b/src/client/unittests/common/services/workspaceTestManagerService.ts similarity index 62% rename from src/client/unittests/common/workspaceTestManagerService.ts rename to src/client/unittests/common/services/workspaceTestManagerService.ts index ff7e198cb423..6307bfaa7d78 100644 --- a/src/client/unittests/common/workspaceTestManagerService.ts +++ b/src/client/unittests/common/services/workspaceTestManagerService.ts @@ -1,32 +1,35 @@ +import { inject, injectable, named } from 'inversify'; +import 'reflect-metadata'; import { Disposable, OutputChannel, Uri, workspace } from 'vscode'; -import { Product } from '../../common/installer'; -import { BaseTestManager } from './baseTestManager'; -import { TestManagerService } from './testManagerService'; -import { ITestManagerService, ITestManagerServiceFactory, IWorkspaceTestManagerService, UnitTestProduct } from './types'; +import { IDiposableRegistry, IOutputChannel } from '../../../common/types'; +import { TEST_OUTPUT_CHANNEL } from './../constants'; +import { ITestManager, ITestManagerService, ITestManagerServiceFactory, IWorkspaceTestManagerService, UnitTestProduct } from './../types'; +@injectable() export class WorkspaceTestManagerService implements IWorkspaceTestManagerService, Disposable { private workspaceTestManagers = new Map(); - private disposables: Disposable[] = []; - constructor(private outChannel: OutputChannel, - private testManagerServiceFactory: ITestManagerServiceFactory) { + constructor( @inject(IOutputChannel) @named(TEST_OUTPUT_CHANNEL) private outChannel: OutputChannel, + @inject(ITestManagerServiceFactory) private testManagerServiceFactory: ITestManagerServiceFactory, + @inject(IDiposableRegistry) disposables: Disposable[]) { + disposables.push(this); } public dispose() { this.workspaceTestManagers.forEach(info => info.dispose()); } - public getTestManager(resource: Uri): BaseTestManager | undefined { + public getTestManager(resource: Uri): ITestManager | undefined { const wkspace = this.getWorkspace(resource); this.ensureTestManagerService(wkspace); - return this.workspaceTestManagers.get(wkspace.fsPath).getTestManager(); + return this.workspaceTestManagers.get(wkspace.fsPath)!.getTestManager(); } public getTestWorkingDirectory(resource: Uri) { const wkspace = this.getWorkspace(resource); this.ensureTestManagerService(wkspace); - return this.workspaceTestManagers.get(wkspace.fsPath).getTestWorkingDirectory(); + return this.workspaceTestManagers.get(wkspace.fsPath)!.getTestWorkingDirectory(); } - public getPreferredTestManager(resource: Uri): UnitTestProduct { + public getPreferredTestManager(resource: Uri): UnitTestProduct | undefined { const wkspace = this.getWorkspace(resource); this.ensureTestManagerService(wkspace); - return this.workspaceTestManagers.get(wkspace.fsPath).getPreferredTestManager(); + return this.workspaceTestManagers.get(wkspace.fsPath)!.getPreferredTestManager(); } private getWorkspace(resource: Uri): Uri { if (!Array.isArray(workspace.workspaceFolders) || workspace.workspaceFolders.length === 0) { @@ -47,7 +50,7 @@ export class WorkspaceTestManagerService implements IWorkspaceTestManagerService } private ensureTestManagerService(wkspace: Uri) { if (!this.workspaceTestManagers.has(wkspace.fsPath)) { - this.workspaceTestManagers.set(wkspace.fsPath, this.testManagerServiceFactory.createTestManagerService(wkspace)); + this.workspaceTestManagers.set(wkspace.fsPath, this.testManagerServiceFactory(wkspace)); } } } diff --git a/src/client/unittests/common/testManagerService.ts b/src/client/unittests/common/testManagerService.ts deleted file mode 100644 index 87cfa5d2c1e4..000000000000 --- a/src/client/unittests/common/testManagerService.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { OutputChannel, Uri } from 'vscode'; -import { PythonSettings } from '../../common/configSettings'; -import { Product } from '../../common/installer'; -import { TestManager as NoseTestManager } from '../nosetest/main'; -import { TestManager as PyTestTestManager } from '../pytest/main'; -import { TestManager as UnitTestTestManager } from '../unittest/main'; -import { BaseTestManager } from './baseTestManager'; -import { ITestCollectionStorageService, ITestDebugLauncher, ITestManagerService, ITestResultsService, ITestsHelper, UnitTestProduct } from './types'; - -type TestManagerInstanceInfo = { instance?: BaseTestManager, create(rootDirectory: string): BaseTestManager }; - -export class TestManagerService implements ITestManagerService { - private testManagers = new Map(); - constructor(private wkspace: Uri, private outChannel: OutputChannel, - testCollectionStorage: ITestCollectionStorageService, testResultsService: ITestResultsService, - testsHelper: ITestsHelper, debugLauncher: ITestDebugLauncher) { - this.testManagers.set(Product.nosetest, { - create: (rootDirectory: string) => new NoseTestManager(rootDirectory, this.outChannel, testCollectionStorage, testResultsService, testsHelper, debugLauncher) - }); - this.testManagers.set(Product.pytest, { - create: (rootDirectory: string) => new PyTestTestManager(rootDirectory, this.outChannel, testCollectionStorage, testResultsService, testsHelper, debugLauncher) - }); - this.testManagers.set(Product.unittest, { - create: (rootDirectory: string) => new UnitTestTestManager(rootDirectory, this.outChannel, testCollectionStorage, testResultsService, testsHelper, debugLauncher) - }); - } - public dispose() { - this.testManagers.forEach(info => { - if (info.instance) { - info.instance.dispose(); - } - }); - } - public getTestManager(): BaseTestManager | undefined { - const preferredTestManager = this.getPreferredTestManager(); - if (typeof preferredTestManager !== 'number') { - return; - } - - // tslint:disable-next-line:no-non-null-assertion - const info = this.testManagers.get(preferredTestManager)!; - if (!info.instance) { - const testDirectory = this.getTestWorkingDirectory(); - info.instance = info.create(testDirectory); - } - return info.instance; - } - public getTestWorkingDirectory() { - const settings = PythonSettings.getInstance(this.wkspace); - return settings.unitTest.cwd && settings.unitTest.cwd.length > 0 ? settings.unitTest.cwd : this.wkspace.fsPath; - } - public getPreferredTestManager(): UnitTestProduct | undefined { - const settings = PythonSettings.getInstance(this.wkspace); - if (settings.unitTest.nosetestsEnabled) { - return Product.nosetest; - } else if (settings.unitTest.pyTestEnabled) { - return Product.pytest; - } else if (settings.unitTest.unittestEnabled) { - return Product.unittest; - } - return undefined; - } -} diff --git a/src/client/unittests/common/testManagerServiceFactory.ts b/src/client/unittests/common/testManagerServiceFactory.ts deleted file mode 100644 index f10600ef8b45..000000000000 --- a/src/client/unittests/common/testManagerServiceFactory.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { OutputChannel, Uri } from 'vscode'; -import { TestManagerService } from './testManagerService'; -import { ITestCollectionStorageService, ITestDebugLauncher, ITestManagerService, ITestManagerServiceFactory, ITestResultsService, ITestsHelper } from './types'; - -export class TestManagerServiceFactory implements ITestManagerServiceFactory { - constructor(private outChannel: OutputChannel, private testCollectionStorage: ITestCollectionStorageService, - private testResultsService: ITestResultsService, private testsHelper: ITestsHelper, - private debugLauncher: ITestDebugLauncher) { } - public createTestManagerService(wkspace: Uri): ITestManagerService { - return new TestManagerService(wkspace, this.outChannel, this.testCollectionStorage, this.testResultsService, this.testsHelper, this.debugLauncher); - } -} diff --git a/src/client/unittests/common/testUtils.ts b/src/client/unittests/common/testUtils.ts index b552b4c82b7e..c064083e7f42 100644 --- a/src/client/unittests/common/testUtils.ts +++ b/src/client/unittests/common/testUtils.ts @@ -1,11 +1,14 @@ +import { inject, injectable, named } from 'inversify'; import * as path from 'path'; -import * as vscode from 'vscode'; +import 'reflect-metadata'; import { Uri, workspace } from 'vscode'; import { window } from 'vscode'; +import * as vscode from 'vscode'; import * as constants from '../../common/constants'; +import { Product } from '../../common/installer'; import { CommandSource } from './constants'; import { TestFlatteningVisitor } from './testVisitors/flatteningVisitor'; -import { TestFile, TestFolder, Tests, TestsToRun } from './types'; +import { ITestVisitor, TestFile, TestFolder, TestProvider, Tests, TestsToRun, UnitTestProduct } from './types'; import { ITestsHelper } from './types'; export async function selectTestWorkspace(): Promise { @@ -39,15 +42,32 @@ export function convertFileToPackage(filePath: string): string { return filePath.substring(0, lastIndex).replace(/\//g, '.').replace(/\\/g, '.'); } +@injectable() export class TestsHelper implements ITestsHelper { + constructor( @inject(ITestVisitor) @named('TestFlatteningVisitor') private flatteningVisitor: TestFlatteningVisitor) { } + public parseProviderName(product: UnitTestProduct): TestProvider { + switch (product) { + case Product.nosetest: { + return 'nosetest'; + } + case Product.pytest: { + return 'pytest'; + } + case Product.unittest: { + return 'unittest'; + } + default: { + throw new Error(`Unknown Test Product ${product}`); + } + } + } public flattenTestFiles(testFiles: TestFile[]): Tests { - const flatteningVisitor = new TestFlatteningVisitor(); - testFiles.forEach(testFile => flatteningVisitor.visitTestFile(testFile)); + testFiles.forEach(testFile => this.flatteningVisitor.visitTestFile(testFile)); const tests = { testFiles: testFiles, - testFunctions: flatteningVisitor.flattenedTestFunctions, - testSuites: flatteningVisitor.flattenedTestSuites, + testFunctions: this.flatteningVisitor.flattenedTestFunctions, + testSuites: this.flatteningVisitor.flattenedTestSuites, testFolders: [], rootTestFolders: [], summary: { passed: 0, failures: 0, errors: 0, skipped: 0 } @@ -74,7 +94,7 @@ export class TestsHelper implements ITestsHelper { folders.forEach(dir => { dir.split(path.sep).reduce((parentPath, currentName, index, values) => { let newPath = currentName; - let parentFolder: TestFolder; + let parentFolder: TestFolder | undefined; if (parentPath.length > 0) { parentFolder = folderMap.get(parentPath); newPath = path.join(parentPath, currentName); @@ -83,7 +103,7 @@ export class TestsHelper implements ITestsHelper { const testFolder: TestFolder = { name: newPath, testFiles: [], folders: [], nameToRun: newPath, time: 0 }; folderMap.set(newPath, testFolder); if (parentFolder) { - parentFolder.folders.push(testFolder); + parentFolder!.folders.push(testFolder); } else { tests.rootTestFolders.push(testFolder); } @@ -96,11 +116,12 @@ export class TestsHelper implements ITestsHelper { }, ''); }); } - public parseTestName(name: string, rootDirectory: string, tests: Tests): TestsToRun { + public parseTestName(name: string, rootDirectory: string, tests: Tests): TestsToRun | undefined { + // tslint:disable-next-line:no-suspicious-comment // TODO: We need a better way to match (currently we have raw name, name, xmlname, etc = which one do we. // Use to identify a file given the full file name, similarly for a folder and function. // Perhaps something like a parser or methods like TestFunction.fromString()... something). - if (!tests) { return null; } + if (!tests) { return undefined; } const absolutePath = path.isAbsolute(name) ? name : path.resolve(rootDirectory, name); const testFolders = tests.testFolders.filter(folder => folder.nameToRun === name || folder.name === name || folder.name === absolutePath); if (testFolders.length > 0) { return { testFolder: testFolders }; } diff --git a/src/client/unittests/common/testVisitors/flatteningVisitor.ts b/src/client/unittests/common/testVisitors/flatteningVisitor.ts index 4a8ed96babbc..5a0178a2437f 100644 --- a/src/client/unittests/common/testVisitors/flatteningVisitor.ts +++ b/src/client/unittests/common/testVisitors/flatteningVisitor.ts @@ -1,3 +1,5 @@ +import { injectable } from 'inversify'; +import 'reflect-metadata'; import { convertFileToPackage } from '../testUtils'; import { FlattenedTestFunction, @@ -9,6 +11,7 @@ import { TestSuite } from '../types'; +@injectable() export class TestFlatteningVisitor implements ITestVisitor { // tslint:disable-next-line:variable-name private _flattedTestFunctions = new Map(); diff --git a/src/client/unittests/common/testVisitors/folderGenerationVisitor.ts b/src/client/unittests/common/testVisitors/folderGenerationVisitor.ts index 46956873edd1..0f518c35b91f 100644 --- a/src/client/unittests/common/testVisitors/folderGenerationVisitor.ts +++ b/src/client/unittests/common/testVisitors/folderGenerationVisitor.ts @@ -1,6 +1,9 @@ +import { injectable } from 'inversify'; import * as path from 'path'; +import 'reflect-metadata'; import { ITestVisitor, TestFile, TestFolder, TestFunction, TestSuite } from '../types'; +@injectable() export class TestFolderGenerationVisitor implements ITestVisitor { // tslint:disable-next-line:variable-name private _testFolders: TestFolder[] = []; @@ -19,17 +22,16 @@ export class TestFolderGenerationVisitor implements ITestVisitor { public visitTestSuite(testSuite: TestSuite): void { } public visitTestFile(testFile: TestFile): void { // First get all the unique folders - const folders: string[] = []; const dir = path.dirname(testFile.name); if (this.folderMap.has(dir)) { - const folder = this.folderMap.get(dir); + const folder = this.folderMap.get(dir)!; folder.testFiles.push(testFile); return; } dir.split(path.sep).reduce((accumulatedPath, currentName, index) => { let newPath = currentName; - let parentFolder: TestFolder; + let parentFolder: TestFolder | undefined; if (accumulatedPath.length > 0) { parentFolder = this.folderMap.get(accumulatedPath); newPath = path.join(accumulatedPath, currentName); diff --git a/src/client/unittests/common/testVisitors/resultResetVisitor.ts b/src/client/unittests/common/testVisitors/resultResetVisitor.ts index 0d58c1076b04..79fdffd7e961 100644 --- a/src/client/unittests/common/testVisitors/resultResetVisitor.ts +++ b/src/client/unittests/common/testVisitors/resultResetVisitor.ts @@ -1,8 +1,11 @@ +import { injectable } from 'inversify'; +import 'reflect-metadata'; import { ITestVisitor, TestFile, TestFolder, TestFunction, TestStatus, TestSuite } from '../types'; +@injectable() export class TestResultResetVisitor implements ITestVisitor { public visitTestFunction(testFunction: TestFunction): void { - testFunction.passed = null; + testFunction.passed = undefined; testFunction.time = 0; testFunction.message = ''; testFunction.traceback = ''; @@ -12,7 +15,7 @@ export class TestResultResetVisitor implements ITestVisitor { testFunction.functionsDidNotRun = 0; } public visitTestSuite(testSuite: TestSuite): void { - testSuite.passed = null; + testSuite.passed = undefined; testSuite.time = 0; testSuite.status = TestStatus.Unknown; testSuite.functionsFailed = 0; @@ -20,7 +23,7 @@ export class TestResultResetVisitor implements ITestVisitor { testSuite.functionsDidNotRun = 0; } public visitTestFile(testFile: TestFile): void { - testFile.passed = null; + testFile.passed = undefined; testFile.time = 0; testFile.status = TestStatus.Unknown; testFile.functionsFailed = 0; @@ -31,7 +34,7 @@ export class TestResultResetVisitor implements ITestVisitor { testFolder.functionsDidNotRun = 0; testFolder.functionsFailed = 0; testFolder.functionsPassed = 0; - testFolder.passed = null; + testFolder.passed = undefined; testFolder.status = TestStatus.Unknown; } } diff --git a/src/client/unittests/common/types.ts b/src/client/unittests/common/types.ts index 9d993ece79e7..2511d66d8695 100644 --- a/src/client/unittests/common/types.ts +++ b/src/client/unittests/common/types.ts @@ -1,6 +1,28 @@ import { CancellationToken, Disposable, OutputChannel, Uri } from 'vscode'; import { Product } from '../../common/installer'; -import { BaseTestManager } from './baseTestManager'; +import { CommandSource } from './constants'; + +export type TestProvider = 'nosetest' | 'pytest' | 'unittest'; + +export type TestDiscoveryOptions = { + workspaceFolder: Uri; + cwd: string; + args: string[]; + token: CancellationToken; + ignoreCache: boolean; + outChannel: OutputChannel; +}; + +export type TestRunOptions = { + workspaceFolder: Uri; + cwd: string; + tests: Tests; + args: string[]; + testsToRun?: TestsToRun; + token: CancellationToken; + outChannel?: OutputChannel; + debug?: boolean; +}; export type TestFolder = TestResult & { name: string; @@ -110,26 +132,29 @@ export interface ITestConfigSettingsService { } export interface ITestManagerService extends Disposable { - getTestManager(): BaseTestManager | undefined; + getTestManager(): ITestManager | undefined; getTestWorkingDirectory(): string; getPreferredTestManager(): UnitTestProduct | undefined; } -export interface ITestManagerServiceFactory { - createTestManagerService(wkspace: Uri): ITestManagerService; -} +export const IWorkspaceTestManagerService = Symbol('IWorkspaceTestManagerService'); export interface IWorkspaceTestManagerService extends Disposable { - getTestManager(resource: Uri): BaseTestManager | undefined; + getTestManager(resource: Uri): ITestManager | undefined; getTestWorkingDirectory(resource: Uri): string; getPreferredTestManager(resource: Uri): UnitTestProduct | undefined; } +export const ITestsHelper = Symbol('ITestsHelper'); + export interface ITestsHelper { + parseProviderName(product: UnitTestProduct): TestProvider; flattenTestFiles(testFiles: TestFile[]): Tests; placeTestFilesIntoFolders(tests: Tests): void; } +export const ITestVisitor = Symbol('ITestVisitor'); + export interface ITestVisitor { visitTestFunction(testFunction: TestFunction): void; visitTestSuite(testSuite: TestSuite): void; @@ -137,17 +162,75 @@ export interface ITestVisitor { visitTestFolder(testFile: TestFolder): void; } +export const ITestCollectionStorageService = Symbol('ITestCollectionStorageService'); + export interface ITestCollectionStorageService extends Disposable { getTests(wkspace: Uri): Tests | undefined; storeTests(wkspace: Uri, tests: Tests | null | undefined): void; } +export const ITestResultsService = Symbol('ITestResultsService'); + export interface ITestResultsService { resetResults(tests: Tests): void; updateResults(tests: Tests): void; } +export type launchOptions = { + cwd: string; + args: string[]; + token?: CancellationToken; + outChannel?: OutputChannel; + port: number; +}; + +export const ITestDebugLauncher = Symbol('ITestDebugLauncher'); + export interface ITestDebugLauncher { getPort(resource?: Uri): Promise; - launchDebugger(rootDirectory: string, testArgs: string[], port: number, token?: CancellationToken, outChannel?: OutputChannel): Promise; + launchDebugger(options: launchOptions): Promise; +} + +export const ITestManagerFactory = Symbol('ITestManagerFactory'); + +export interface ITestManagerFactory extends Function { + // tslint:disable-next-line:callable-types + (testProvider: TestProvider, workspaceFolder: Uri, rootDirectory: string): ITestManager; +} +export const ITestManagerServiceFactory = Symbol('TestManagerServiceFactory'); + +export interface ITestManagerServiceFactory extends Function { + // tslint:disable-next-line:callable-types + (workspaceFolder: Uri): ITestManagerService; +} + +export const ITestManager = Symbol('ITestManager'); +export interface ITestManager extends Disposable { + readonly status: TestStatus; + readonly workingDirectory: string; + readonly workspaceFolder: Uri; + stop(): void; + resetTestResults(): void; + discoverTests(cmdSource: CommandSource, ignoreCache?: boolean, quietMode?: boolean, userInitiated?: boolean): Promise; + runTest(cmdSource: CommandSource, testsToRun?: TestsToRun, runFailedTests?: boolean, debug?: boolean): Promise; +} + +export const ITestDiscoveryService = Symbol('ITestDiscoveryService'); + +export interface ITestDiscoveryService { + discoverTests(options: TestDiscoveryOptions): Promise; +} + +export const ITestsParser = Symbol('ITestsParser'); +export interface ITestsParser { + parse(content: string, options: ParserOptions): Tests; +} + +export type ParserOptions = TestDiscoveryOptions; + +export const IUnitTestSocketServer = Symbol('IUnitTestSocketServer'); +export interface IUnitTestSocketServer extends Disposable { + on(event: string | symbol, listener: Function): this; + start(): Promise; + stop(): void; } diff --git a/src/client/unittests/configuration.ts b/src/client/unittests/configuration.ts index df49c7391204..9cd6267f822d 100644 --- a/src/client/unittests/configuration.ts +++ b/src/client/unittests/configuration.ts @@ -1,13 +1,12 @@ 'use strict'; import * as path from 'path'; -import * as vscode from 'vscode'; import { OutputChannel, Uri } from 'vscode'; +import * as vscode from 'vscode'; import { PythonSettings } from '../common/configSettings'; import { Installer, Product } from '../common/installer'; import { getSubDirectories } from '../common/utils'; -import { TestConfigSettingsService } from './common/configSettingService'; -import { TestConfigurationManager } from './common/testConfigurationManager'; -import { selectTestWorkspace } from './common/testUtils'; +import { TestConfigurationManager } from './common/managers/testConfigurationManager'; +import { TestConfigSettingsService } from './common/services/configSettingService'; import { UnitTestProduct } from './common/types'; import { ConfigurationManager } from './nosetest/testConfigurationManager'; import * as nose from './nosetest/testConfigurationManager'; @@ -23,15 +22,12 @@ async function promptToEnableAndConfigureTestFramework(wkspace: Uri, outputChann const configMgr: TestConfigurationManager = createTestConfigurationManager(wkspace, selectedTestRunner, outputChannel); if (enableOnly) { // Ensure others are disabled - if (selectedTestRunner !== Product.unittest) { - createTestConfigurationManager(wkspace, Product.unittest, outputChannel).disable(); - } - if (selectedTestRunner !== Product.pytest) { - createTestConfigurationManager(wkspace, Product.pytest, outputChannel).disable(); - } - if (selectedTestRunner !== Product.nosetest) { - createTestConfigurationManager(wkspace, Product.nosetest, outputChannel).disable(); - } + [Product.unittest, Product.pytest, Product.nosetest] + .filter(prod => selectedTestRunner !== prod) + .forEach(prod => { + createTestConfigurationManager(wkspace, prod, outputChannel).disable() + .catch(ex => console.error('Python Extension: createTestConfigurationManager.disable', ex)); + }); return configMgr.enable(); } @@ -83,7 +79,7 @@ export async function displayPromptToEnableTests(rootDir: string, outputChannel: return; } if (item === yes) { - await promptToEnableAndConfigureTestFramework(vscode.workspace.getWorkspaceFolder(vscode.Uri.file(rootDir)).uri, outputChannel); + await promptToEnableAndConfigureTestFramework(vscode.workspace.getWorkspaceFolder(vscode.Uri.file(rootDir))!.uri, outputChannel); } else { const pythonConfig = vscode.workspace.getConfiguration('python'); await pythonConfig.update('unitTest.promptToConfigure', false); diff --git a/src/client/unittests/display/main.ts b/src/client/unittests/display/main.ts index ab232152e295..b6f03f11c62f 100644 --- a/src/client/unittests/display/main.ts +++ b/src/client/unittests/display/main.ts @@ -13,7 +13,7 @@ export class TestResultDisplay { private progressTimeout; private progressPrefix: string; // tslint:disable-next-line:no-any - constructor(private outputChannel: vscode.OutputChannel, private onDidChange: vscode.EventEmitter = null) { + constructor(private outputChannel: vscode.OutputChannel, private onDidChange?: vscode.EventEmitter) { this.statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); } public dispose() { @@ -50,8 +50,8 @@ export class TestResultDisplay { this.clearProgressTicker(); // Treat errors as a special case, as we generally wouldn't have any errors - const statusText = []; - const toolTip = []; + const statusText: string[] = []; + const toolTip: string[] = []; let foreColor = ''; if (tests.summary.passed > 0) { @@ -135,7 +135,7 @@ export class TestResultDisplay { if (settingsToDisable.length === 0) { return def.resolve(); } - pythonConfig.update(settingsToDisable.shift(), false) + pythonConfig.update(settingsToDisable.shift()!, false) .then(disableTest.bind(this), disableTest.bind(this)); } @@ -157,8 +157,8 @@ export class TestResultDisplay { if (!haveTests) { vscode.window.showInformationMessage('No tests discovered, please check the configuration settings for the tests.', 'Disable Tests').then(item => { if (item === 'Disable Tests') { - // tslint:disable-next-line:no-floating-promises - this.disableTests(); + this.disableTests() + .catch(ex => console.error('Python Extension: disableTests', ex)); } }); } @@ -175,8 +175,10 @@ export class TestResultDisplay { if (reason !== CANCELLATION_REASON) { this.statusBar.text = '$(alert) Test discovery failed'; this.statusBar.tooltip = 'Discovering Tests failed (view \'Python Test Log\' output panel for details)'; + // tslint:disable-next-line:no-suspicious-comment // TODO: ignore this quitemode, always display the error message (inform the user). if (!isNotInstalledError(reason)) { + // tslint:disable-next-line:no-suspicious-comment // TODO: show an option that will invoke a command 'python.test.configureTest' or similar. // This will be hanlded by main.ts that will capture input from user and configure the tests. vscode.window.showErrorMessage('There was an error in discovering tests, please check the configuration settings for the tests.'); diff --git a/src/client/unittests/main.ts b/src/client/unittests/main.ts index 88bc265758c9..76136273bc16 100644 --- a/src/client/unittests/main.ts +++ b/src/client/unittests/main.ts @@ -1,21 +1,16 @@ 'use strict'; -import { Uri, window, workspace } from 'vscode'; +import { Disposable, Uri, window, workspace } from 'vscode'; import * as vscode from 'vscode'; import { PythonSettings } from '../common/configSettings'; import * as constants from '../common/constants'; +import { IServiceContainer } from '../ioc/types'; import { PythonSymbolProvider } from '../providers/symbolProvider'; import { UNITTEST_STOP, UNITTEST_VIEW_OUTPUT } from '../telemetry/constants'; import { sendTelemetryEvent } from '../telemetry/index'; import { activateCodeLenses } from './codeLenses/main'; -import { BaseTestManager } from './common/baseTestManager'; import { CANCELLATION_REASON, CommandSource } from './common/constants'; -import { DebugLauncher } from './common/debugLauncher'; -import { TestCollectionStorageService } from './common/storageService'; -import { TestManagerServiceFactory } from './common/testManagerServiceFactory'; -import { TestResultsService } from './common/testResultsService'; -import { selectTestWorkspace, TestsHelper } from './common/testUtils'; -import { ITestCollectionStorageService, IWorkspaceTestManagerService, TestFile, TestFunction, TestStatus, TestsToRun } from './common/types'; -import { WorkspaceTestManagerService } from './common/workspaceTestManagerService'; +import { selectTestWorkspace } from './common/testUtils'; +import { ITestCollectionStorageService, ITestManager, IWorkspaceTestManagerService, TestFile, TestFunction, TestStatus, TestsToRun } from './common/types'; import { displayTestFrameworkError } from './configuration'; import { TestResultDisplay } from './display/main'; import { TestDisplay } from './display/picker'; @@ -27,18 +22,14 @@ let outChannel: vscode.OutputChannel; const onDidChange: vscode.EventEmitter = new vscode.EventEmitter(); let testCollectionStorage: ITestCollectionStorageService; -export function activate(context: vscode.ExtensionContext, outputChannel: vscode.OutputChannel, symboldProvider: PythonSymbolProvider) { +export function activate(context: vscode.ExtensionContext, outputChannel: vscode.OutputChannel, symboldProvider: PythonSymbolProvider, serviceContainer: IServiceContainer) { context.subscriptions.push({ dispose: dispose }); outChannel = outputChannel; const disposables = registerCommands(); context.subscriptions.push(...disposables); - testCollectionStorage = new TestCollectionStorageService(); - const testResultsService = new TestResultsService(); - const testsHelper = new TestsHelper(); - const debugLauncher = new DebugLauncher(); - const testManagerServiceFactory = new TestManagerServiceFactory(outChannel, testCollectionStorage, testResultsService, testsHelper, debugLauncher); - workspaceTestManagerService = new WorkspaceTestManagerService(outChannel, testManagerServiceFactory); + testCollectionStorage = serviceContainer.get(ITestCollectionStorageService); + workspaceTestManagerService = serviceContainer.get(IWorkspaceTestManagerService); context.subscriptions.push(autoResetTests()); context.subscriptions.push(activateCodeLenses(onDidChange, symboldProvider, testCollectionStorage)); @@ -47,7 +38,7 @@ export function activate(context: vscode.ExtensionContext, outputChannel: vscode autoDiscoverTests(); } -async function getTestManager(displayTestNotConfiguredMessage: boolean, resource?: Uri): Promise { +async function getTestManager(displayTestNotConfiguredMessage: boolean, resource?: Uri): Promise { let wkspace: Uri | undefined; if (resource) { const wkspaceFolder = workspace.getWorkspaceFolder(resource); @@ -91,7 +82,7 @@ function dispose() { testCollectionStorage.dispose(); } function registerCommands(): vscode.Disposable[] { - const disposables = []; + const disposables: Disposable[] = []; disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Discover, (cmdSource: CommandSource = CommandSource.commandPalette, resource?: Uri) => { // Ignore the exceptions returned. // This command will be invoked else where in the extension. @@ -135,7 +126,7 @@ async function displayUI(cmdSource: CommandSource) { } testDisplay = testDisplay ? testDisplay : new TestDisplay(testCollectionStorage); - testDisplay.displayTestUI(cmdSource, testManager.workspace); + testDisplay.displayTestUI(cmdSource, testManager.workspaceFolder); } async function displayPickerUI(cmdSource: CommandSource, file: Uri, testFunctions: TestFunction[], debug?: boolean) { const testManager = await getTestManager(true, file); @@ -144,7 +135,7 @@ async function displayPickerUI(cmdSource: CommandSource, file: Uri, testFunction } testDisplay = testDisplay ? testDisplay : new TestDisplay(testCollectionStorage); - testDisplay.displayFunctionTestPickerUI(cmdSource, testManager.workspace, testManager.workingDirectory, file, testFunctions, debug); + testDisplay.displayFunctionTestPickerUI(cmdSource, testManager.workspaceFolder, testManager.workingDirectory, file, testFunctions, debug); } async function selectAndRunTestMethod(cmdSource: CommandSource, resource: Uri, debug?: boolean) { const testManager = await getTestManager(true, resource); @@ -157,14 +148,14 @@ async function selectAndRunTestMethod(cmdSource: CommandSource, resource: Uri, d return; } - const tests = testCollectionStorage.getTests(testManager.workspace)!; + const tests = testCollectionStorage.getTests(testManager.workspaceFolder)!; testDisplay = testDisplay ? testDisplay : new TestDisplay(testCollectionStorage); - const selectedTestFn = await testDisplay.selectTestFunction(testManager.workspace.fsPath, tests); + const selectedTestFn = await testDisplay.selectTestFunction(testManager.workspaceFolder.fsPath, tests); if (!selectedTestFn) { return; } // tslint:disable-next-line:prefer-type-cast - await runTestsImpl(cmdSource, testManager.workspace, { testFunction: [selectedTestFn.testFunction] } as TestsToRun, debug); + await runTestsImpl(cmdSource, testManager.workspaceFolder, { testFunction: [selectedTestFn.testFunction] } as TestsToRun, debug); } async function selectAndRunTestFile(cmdSource: CommandSource) { const testManager = await getTestManager(true); @@ -177,14 +168,14 @@ async function selectAndRunTestFile(cmdSource: CommandSource) { return; } - const tests = testCollectionStorage.getTests(testManager.workspace)!; + const tests = testCollectionStorage.getTests(testManager.workspaceFolder)!; testDisplay = testDisplay ? testDisplay : new TestDisplay(testCollectionStorage); - const selectedFile = await testDisplay.selectTestFile(testManager.workspace.fsPath, tests); + const selectedFile = await testDisplay.selectTestFile(testManager.workspaceFolder.fsPath, tests); if (!selectedFile) { return; } // tslint:disable-next-line:prefer-type-cast - await runTestsImpl(cmdSource, testManager.workspace, { testFile: [selectedFile] } as TestsToRun); + await runTestsImpl(cmdSource, testManager.workspaceFolder, { testFile: [selectedFile] } as TestsToRun); } async function runCurrentTestFile(cmdSource: CommandSource) { if (!window.activeTextEditor) { @@ -199,7 +190,7 @@ async function runCurrentTestFile(cmdSource: CommandSource) { } catch (ex) { return; } - const tests = testCollectionStorage.getTests(testManager.workspace)!; + const tests = testCollectionStorage.getTests(testManager.workspaceFolder)!; const testFiles = tests.testFiles.filter(testFile => { return testFile.fullPath === window.activeTextEditor!.document.uri.fsPath; }); @@ -207,7 +198,7 @@ async function runCurrentTestFile(cmdSource: CommandSource) { return; } // tslint:disable-next-line:prefer-type-cast - await runTestsImpl(cmdSource, testManager.workspace, { testFile: [testFiles[0]] } as TestsToRun); + await runTestsImpl(cmdSource, testManager.workspaceFolder, { testFile: [testFiles[0]] } as TestsToRun); } async function displayStopUI(message: string) { const testManager = await getTestManager(true); @@ -216,7 +207,7 @@ async function displayStopUI(message: string) { } testDisplay = testDisplay ? testDisplay : new TestDisplay(testCollectionStorage); - testDisplay.displayStopTestUI(testManager.workspace, message); + testDisplay.displayStopTestUI(testManager.workspaceFolder, message); } let uniTestSettingsString: string; @@ -287,7 +278,8 @@ async function discoverTests(cmdSource: CommandSource, resource?: Uri, ignoreCac if (testManager && (testManager.status !== TestStatus.Discovering && testManager.status !== TestStatus.Running)) { testResultDisplay = testResultDisplay ? testResultDisplay : new TestResultDisplay(outChannel, onDidChange); const discoveryPromise = testManager.discoverTests(cmdSource, ignoreCache, false, userInitiated); - testResultDisplay.displayDiscoverStatus(discoveryPromise); + testResultDisplay.displayDiscoverStatus(discoveryPromise) + .catch(ex => console.error('Python Extension: displayDiscoverStatus', ex)); await discoveryPromise; } } diff --git a/src/client/unittests/nosetest/collector.ts b/src/client/unittests/nosetest/collector.ts deleted file mode 100644 index 3a202654e6fd..000000000000 --- a/src/client/unittests/nosetest/collector.ts +++ /dev/null @@ -1,161 +0,0 @@ -'use strict'; -import * as os from 'os'; -import * as path from 'path'; -import { CancellationToken } from 'vscode'; -import { OutputChannel, Uri } from 'vscode'; -import { PythonSettings } from '../../common/configSettings'; -import { convertFileToPackage, extractBetweenDelimiters } from '../common/testUtils'; -import { ITestsHelper, TestFile, TestFunction, Tests, TestSuite } from '../common/types'; -import { execPythonFile } from './../../common/utils'; - -const NOSE_WANT_FILE_PREFIX = 'nose.selector: DEBUG: wantFile '; -const NOSE_WANT_FILE_SUFFIX = '.py? True'; -const NOSE_WANT_FILE_SUFFIX_WITHOUT_EXT = '? True'; - -const argsToExcludeForDiscovery = ['-v', '--verbose', - '-q', '--quiet', '-x', '--stop', - '--with-coverage', '--cover-erase', '--cover-tests', - '--cover-inclusive', '--cover-html', '--cover-branches', '--cover-xml', - '--pdb', '--pdb-failures', '--pdb-errors', - '--failed', '--process-restartworker', '--with-xunit']; -const settingsInArgsToExcludeForDiscovery = ['--verbosity']; - -export function discoverTests(rootDirectory: string, args: string[], token: CancellationToken, ignoreCache: boolean, outChannel: OutputChannel, testsHelper: ITestsHelper): Promise { - let logOutputLines: string[] = ['']; - let testFiles: TestFile[] = []; - - // Remove unwanted arguments - args = args.filter(arg => { - if (argsToExcludeForDiscovery.indexOf(arg.trim()) !== -1) { - return false; - } - if (settingsInArgsToExcludeForDiscovery.some(setting => setting.indexOf(arg.trim()) === 0)) { - return false; - } - return true; - }); - - function appendLine(line: string) { - const lastLineIndex = logOutputLines.length - 1; - logOutputLines[lastLineIndex] += line; - - // Check whether the previous line is something that we need - // What we need is a line that ends with ? True - // and starts with nose.selector: DEBUG: want - if (logOutputLines[lastLineIndex].endsWith('? True')) { - logOutputLines.push(''); - } else { - // We don't need this line - logOutputLines[lastLineIndex] = ''; - } - - } - function processOutput(output: string) { - output.split(/\r?\n/g).forEach((line, index, lines) => { - if ((line.startsWith(NOSE_WANT_FILE_PREFIX) && line.endsWith(NOSE_WANT_FILE_SUFFIX)) || - index === lines.length - 1) { - // process the previous lines - parseNoseTestModuleCollectionResult(rootDirectory, logOutputLines, testFiles); - logOutputLines = ['']; - } - - if (index === 0) { - if (output.startsWith(os.EOL) || lines.length > 1) { - appendLine(line); - return; - } - logOutputLines[logOutputLines.length - 1] += line; - return; - } - if (index === lines.length - 1) { - logOutputLines[logOutputLines.length - 1] += line; - return; - } - appendLine(line); - return; - }); - } - - return execPythonFile(rootDirectory, PythonSettings.getInstance(Uri.file(rootDirectory)).unitTest.nosetestPath, args.concat(['--collect-only', '-vvv']), rootDirectory, true) - .then(data => { - outChannel.appendLine(data); - processOutput(data); - - // Exclude tests that don't have any functions or test suites - testFiles = testFiles.filter(testFile => testFile.suites.length > 0 || testFile.functions.length > 0); - return testsHelper.flattenTestFiles(testFiles); - }); -} - -function parseNoseTestModuleCollectionResult(rootDirectory: string, lines: string[], testFiles: TestFile[]) { - let currentPackage: string = ''; - let fileName = ''; - let testFile: TestFile; - lines.forEach(line => { - if (line.startsWith(NOSE_WANT_FILE_PREFIX) && line.endsWith(NOSE_WANT_FILE_SUFFIX)) { - fileName = line.substring(NOSE_WANT_FILE_PREFIX.length); - fileName = fileName.substring(0, fileName.lastIndexOf(NOSE_WANT_FILE_SUFFIX_WITHOUT_EXT)); - - // We need to display the path relative to the current directory - fileName = fileName.substring(rootDirectory.length + 1); - // we don't care about the compiled file - if (path.extname(fileName) === '.pyc') { - fileName = fileName.substring(0, fileName.length - 1); - } - currentPackage = convertFileToPackage(fileName); - const fullyQualifiedName = path.isAbsolute(fileName) ? fileName : path.resolve(rootDirectory, fileName); - testFile = { - functions: [], suites: [], name: fileName, nameToRun: fileName, - xmlName: currentPackage, time: 0, functionsFailed: 0, functionsPassed: 0, - fullPath: fullyQualifiedName - }; - testFiles.push(testFile); - return; - } - - if (line.startsWith('nose.selector: DEBUG: wantClass ? True'); - const clsName = path.extname(name).substring(1); - const testSuite: TestSuite = { - name: clsName, nameToRun: `${fileName}:${clsName}`, - functions: [], suites: [], xmlName: name, time: 0, isUnitTest: false, - isInstance: false, functionsFailed: 0, functionsPassed: 0 - }; - testFile.suites.push(testSuite); - return; - } - if (line.startsWith('nose.selector: DEBUG: wantClass ')) { - const name = extractBetweenDelimiters(line, 'nose.selector: DEBUG: wantClass ', '? True'); - const testSuite: TestSuite = { - name: path.extname(name).substring(1), nameToRun: `${fileName}:.${name}`, - functions: [], suites: [], xmlName: name, time: 0, isUnitTest: false, - isInstance: false, functionsFailed: 0, functionsPassed: 0 - }; - testFile.suites.push(testSuite); - return; - } - if (line.startsWith('nose.selector: DEBUG: wantMethod ? True'); - const fnName = path.extname(name).substring(1); - const clsName = path.basename(name, path.extname(name)); - const fn: TestFunction = { - name: fnName, nameToRun: `${fileName}:${clsName}.${fnName}`, - time: 0, functionsFailed: 0, functionsPassed: 0 - }; - - // tslint:disable-next-line:no-non-null-assertion - const cls = testFile.suites.find(suite => suite.name === clsName)!; - cls.functions.push(fn); - return; - } - if (line.startsWith('nose.selector: DEBUG: wantFunction { + public getDiscoveryOptions(ignoreCache: boolean): TestDiscoveryOptions { const args = this.settings.unitTest.nosetestArgs.slice(0); - return discoverTests(this.rootDirectory, args, this.testDiscoveryCancellationToken, ignoreCache, this.outputChannel, this.testsHelper); + return { + workspaceFolder: this.workspaceFolder, + cwd: this.rootDirectory, args, + token: this.testDiscoveryCancellationToken!, ignoreCache, + outChannel: this.outputChannel + }; } // tslint:disable-next-line:no-any public runTestImpl(tests: Tests, testsToRun?: TestsToRun, runFailedTests?: boolean, debug?: boolean): Promise { @@ -27,6 +31,14 @@ export class TestManager extends BaseTestManager { if (!runFailedTests && args.indexOf('--with-id') === -1) { args.push('--with-id'); } - return runTest(this.testResultsService, this.debugLauncher, this.rootDirectory, tests, args, testsToRun, this.testRunnerCancellationToken, this.outputChannel, debug); + const options: TestRunOptions = { + workspaceFolder: Uri.file(this.rootDirectory), + cwd: this.rootDirectory, + tests, args, testsToRun, + token: this.testRunnerCancellationToken!, + outChannel: this.outputChannel, + debug + }; + return runTest(this.serviceContainer, this.testResultsService, options); } } diff --git a/src/client/unittests/nosetest/runner.ts b/src/client/unittests/nosetest/runner.ts index d4ab9ed8cb91..5afdb0d8e507 100644 --- a/src/client/unittests/nosetest/runner.ts +++ b/src/client/unittests/nosetest/runner.ts @@ -1,29 +1,28 @@ 'use strict'; import * as path from 'path'; -import { CancellationToken, OutputChannel, Uri } from 'vscode'; -import { PythonSettings } from '../../common/configSettings'; import { createTemporaryFile } from '../../common/helpers'; -import { run } from '../common/runner'; -import { ITestDebugLauncher, ITestResultsService, Tests, TestsToRun } from '../common/types'; +import { IServiceContainer } from '../../ioc/types'; +import { Options, run } from '../common/runner'; +import { ITestDebugLauncher, ITestResultsService, TestRunOptions, Tests } from '../common/types'; import { PassCalculationFormulae, updateResultsFromXmlLogFile } from '../common/xUnitParser'; const WITH_XUNIT = '--with-xunit'; const XUNIT_FILE = '--xunit-file'; // tslint:disable-next-line:no-any -export function runTest(testResultsService: ITestResultsService, debugLauncher: ITestDebugLauncher, rootDirectory: string, tests: Tests, args: string[], testsToRun?: TestsToRun, token?: CancellationToken, outChannel?: OutputChannel, debug?: boolean): Promise { - let testPaths = []; - if (testsToRun && testsToRun.testFolder) { - testPaths = testPaths.concat(testsToRun.testFolder.map(f => f.nameToRun)); +export function runTest(serviceContainer: IServiceContainer, testResultsService: ITestResultsService, options: TestRunOptions): Promise { + let testPaths: string[] = []; + if (options.testsToRun && options.testsToRun.testFolder) { + testPaths = testPaths.concat(options.testsToRun.testFolder.map(f => f.nameToRun)); } - if (testsToRun && testsToRun.testFile) { - testPaths = testPaths.concat(testsToRun.testFile.map(f => f.nameToRun)); + if (options.testsToRun && options.testsToRun.testFile) { + testPaths = testPaths.concat(options.testsToRun.testFile.map(f => f.nameToRun)); } - if (testsToRun && testsToRun.testSuite) { - testPaths = testPaths.concat(testsToRun.testSuite.map(f => f.nameToRun)); + if (options.testsToRun && options.testsToRun.testSuite) { + testPaths = testPaths.concat(options.testsToRun.testSuite.map(f => f.nameToRun)); } - if (testsToRun && testsToRun.testFunction) { - testPaths = testPaths.concat(testsToRun.testFunction.map(f => f.nameToRun)); + if (options.testsToRun && options.testsToRun.testFunction) { + testPaths = testPaths.concat(options.testsToRun.testFunction.map(f => f.nameToRun)); } let xmlLogFile = ''; @@ -31,7 +30,7 @@ export function runTest(testResultsService: ITestResultsService, debugLauncher: let xmlLogFileCleanup: Function = () => { }; // Check if '--with-xunit' is in args list - const noseTestArgs = args.slice(); + const noseTestArgs = options.args.slice(); if (noseTestArgs.indexOf(WITH_XUNIT) === -1) { noseTestArgs.push(WITH_XUNIT); } @@ -58,22 +57,30 @@ export function runTest(testResultsService: ITestResultsService, debugLauncher: } return promiseToGetXmlLogFile.then(() => { - if (debug === true) { - return debugLauncher.getPort(Uri.file(rootDirectory)) + if (options.debug === true) { + const debugLauncher = serviceContainer.get(ITestDebugLauncher); + return debugLauncher.getPort(options.workspaceFolder) .then(debugPort => { const testLauncherFile = path.join(__dirname, '..', '..', '..', '..', 'pythonFiles', 'PythonTools', 'testlauncher.py'); - const nosetestlauncherargs = [rootDirectory, 'my_secret', debugPort.toString(), 'nose']; + const nosetestlauncherargs = [options.cwd, 'my_secret', debugPort.toString(), 'nose']; const debuggerArgs = [testLauncherFile].concat(nosetestlauncherargs).concat(noseTestArgs.concat(testPaths)); + const launchOptions = { cwd: options.cwd, args: debuggerArgs, token: options.token, outChannel: options.outChannel, port: debugPort }; // tslint:disable-next-line:prefer-type-cast no-any - return debugLauncher.launchDebugger(rootDirectory, debuggerArgs, debugPort, token, outChannel) as Promise; + return debugLauncher.launchDebugger(launchOptions) as Promise; }); } else { - const pythonSettings = PythonSettings.getInstance(Uri.file(rootDirectory)); // tslint:disable-next-line:prefer-type-cast no-any - return run(pythonSettings.unitTest.nosetestPath, noseTestArgs.concat(testPaths), rootDirectory, token, outChannel) as Promise; + const runOptions: Options = { + args: noseTestArgs.concat(testPaths), + cwd: options.cwd, + outChannel: options.outChannel, + token: options.token, + workspaceFolder: options.workspaceFolder + }; + return run(serviceContainer, 'nosetest', runOptions); } }).then(() => { - return updateResultsFromLogFiles(tests, xmlLogFile, testResultsService); + return updateResultsFromLogFiles(options.tests, xmlLogFile, testResultsService); }).then(result => { xmlLogFileCleanup(); return result; diff --git a/src/client/unittests/nosetest/services/discoveryService.ts b/src/client/unittests/nosetest/services/discoveryService.ts new file mode 100644 index 000000000000..ebbf09a5a131 --- /dev/null +++ b/src/client/unittests/nosetest/services/discoveryService.ts @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { inject, injectable, named } from 'inversify'; +import 'reflect-metadata'; +import { CancellationTokenSource } from 'vscode'; +import { IServiceContainer } from '../../../ioc/types'; +import { NOSETEST_PROVIDER } from '../../common/constants'; +import { Options, run } from '../../common/runner'; +import { ITestDiscoveryService, ITestsParser, TestDiscoveryOptions, Tests } from '../../common/types'; + +const argsToExcludeForDiscovery = ['-v', '--verbose', + '-q', '--quiet', '-x', '--stop', + '--with-coverage', '--cover-erase', '--cover-tests', + '--cover-inclusive', '--cover-html', '--cover-branches', '--cover-xml', + '--pdb', '--pdb-failures', '--pdb-errors', + '--failed', '--process-restartworker', '--with-xunit']; +const settingsInArgsToExcludeForDiscovery = ['--verbosity']; + +@injectable() +export class TestDiscoveryService implements ITestDiscoveryService { + constructor( @inject(IServiceContainer) private serviceContainer: IServiceContainer, + @inject(ITestsParser) @named(NOSETEST_PROVIDER) private testParser: ITestsParser) { } + public async discoverTests(options: TestDiscoveryOptions): Promise { + // Remove unwanted arguments + const args = options.args.filter(arg => { + if (argsToExcludeForDiscovery.indexOf(arg.trim()) !== -1) { + return false; + } + if (settingsInArgsToExcludeForDiscovery.some(setting => setting.indexOf(arg.trim()) === 0)) { + return false; + } + return true; + }); + + const token = options.token ? options.token : new CancellationTokenSource().token; + const runOptions: Options = { + args: args.concat(['--collect-only', '-vvv']), + cwd: options.cwd, + workspaceFolder: options.workspaceFolder, + token, + outChannel: options.outChannel + }; + + const data = await run(this.serviceContainer, NOSETEST_PROVIDER, runOptions); + if (options.token && options.token.isCancellationRequested) { + return Promise.reject('cancelled'); + } + + return this.testParser.parse(data, options); + } +} diff --git a/src/client/unittests/nosetest/services/parserService.ts b/src/client/unittests/nosetest/services/parserService.ts new file mode 100644 index 000000000000..d9e824716813 --- /dev/null +++ b/src/client/unittests/nosetest/services/parserService.ts @@ -0,0 +1,141 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { inject, injectable } from 'inversify'; +import * as os from 'os'; +import * as path from 'path'; +import 'reflect-metadata'; +import { convertFileToPackage, extractBetweenDelimiters } from '../../common/testUtils'; +import { ITestsHelper, ITestsParser, ParserOptions, TestDiscoveryOptions, TestFile, TestFunction, Tests, TestStatus, TestSuite } from '../../common/types'; + +const NOSE_WANT_FILE_PREFIX = 'nose.selector: DEBUG: wantFile '; +const NOSE_WANT_FILE_SUFFIX = '.py? True'; +const NOSE_WANT_FILE_SUFFIX_WITHOUT_EXT = '? True'; + +@injectable() +export class TestsParser implements ITestsParser { + constructor( @inject(ITestsHelper) private testsHelper: ITestsHelper) { } + public parse(content: string, options: ParserOptions): Tests { + let testFiles = this.getTestFiles(content, options); + // Exclude tests that don't have any functions or test suites. + testFiles = testFiles.filter(testFile => testFile.suites.length > 0 || testFile.functions.length > 0); + return this.testsHelper.flattenTestFiles(testFiles); + } + + private getTestFiles(content: string, options: ParserOptions) { + let logOutputLines: string[] = ['']; + const testFiles: TestFile[] = []; + content.split(/\r?\n/g).forEach((line, index, lines) => { + if ((line.startsWith(NOSE_WANT_FILE_PREFIX) && line.endsWith(NOSE_WANT_FILE_SUFFIX)) || + index === lines.length - 1) { + // process the previous lines. + this.parseNoseTestModuleCollectionResult(options.cwd, logOutputLines, testFiles); + logOutputLines = ['']; + } + + if (index === 0) { + if (content.startsWith(os.EOL) || lines.length > 1) { + this.appendLine(line, logOutputLines); + return; + } + logOutputLines[logOutputLines.length - 1] += line; + return; + } + if (index === lines.length - 1) { + logOutputLines[logOutputLines.length - 1] += line; + return; + } + this.appendLine(line, logOutputLines); + return; + }); + + return testFiles; + } + private appendLine(line: string, logOutputLines: string[]) { + const lastLineIndex = logOutputLines.length - 1; + logOutputLines[lastLineIndex] += line; + + // Check whether the previous line is something that we need. + // What we need is a line that ends with ? True, + // and starts with nose.selector: DEBUG: want. + if (logOutputLines[lastLineIndex].endsWith('? True')) { + logOutputLines.push(''); + } else { + // We don't need this line + logOutputLines[lastLineIndex] = ''; + } + } + + private parseNoseTestModuleCollectionResult(rootDirectory: string, lines: string[], testFiles: TestFile[]) { + let currentPackage: string = ''; + let fileName = ''; + let testFile: TestFile; + lines.forEach(line => { + if (line.startsWith(NOSE_WANT_FILE_PREFIX) && line.endsWith(NOSE_WANT_FILE_SUFFIX)) { + fileName = line.substring(NOSE_WANT_FILE_PREFIX.length); + fileName = fileName.substring(0, fileName.lastIndexOf(NOSE_WANT_FILE_SUFFIX_WITHOUT_EXT)); + + // We need to display the path relative to the current directory. + fileName = fileName.substring(rootDirectory.length + 1); + // we don't care about the compiled file. + if (path.extname(fileName) === '.pyc' || path.extname(fileName) === '.pyo') { + fileName = fileName.substring(0, fileName.length - 1); + } + currentPackage = convertFileToPackage(fileName); + const fullyQualifiedName = path.isAbsolute(fileName) ? fileName : path.resolve(rootDirectory, fileName); + testFile = { + functions: [], suites: [], name: fileName, nameToRun: fileName, + xmlName: currentPackage, time: 0, functionsFailed: 0, functionsPassed: 0, + fullPath: fullyQualifiedName + }; + testFiles.push(testFile); + return; + } + + if (line.startsWith('nose.selector: DEBUG: wantClass ? True'); + const clsName = path.extname(name).substring(1); + const testSuite: TestSuite = { + name: clsName, nameToRun: `${fileName}:${clsName}`, + functions: [], suites: [], xmlName: name, time: 0, isUnitTest: false, + isInstance: false, functionsFailed: 0, functionsPassed: 0 + }; + testFile.suites.push(testSuite); + return; + } + if (line.startsWith('nose.selector: DEBUG: wantClass ')) { + const name = extractBetweenDelimiters(line, 'nose.selector: DEBUG: wantClass ', '? True'); + const testSuite: TestSuite = { + name: path.extname(name).substring(1), nameToRun: `${fileName}:.${name}`, + functions: [], suites: [], xmlName: name, time: 0, isUnitTest: false, + isInstance: false, functionsFailed: 0, functionsPassed: 0 + }; + testFile.suites.push(testSuite); + return; + } + if (line.startsWith('nose.selector: DEBUG: wantMethod ? True'); + const fnName = path.extname(name).substring(1); + const clsName = path.basename(name, path.extname(name)); + const fn: TestFunction = { + name: fnName, nameToRun: `${fileName}:${clsName}.${fnName}`, + time: 0, functionsFailed: 0, functionsPassed: 0 + }; + + // tslint:disable-next-line:no-non-null-assertion + const cls = testFile.suites.find(suite => suite.name === clsName)!; + cls.functions.push(fn); + return; + } + if (line.startsWith('nose.selector: DEBUG: wantFunction { - let logOutputLines: string[] = ['']; - const testFiles: TestFile[] = []; - const parentNodes: { indent: number, item: TestFile | TestSuite }[] = []; - const errorLine = /==*( *)ERRORS( *)=*/; - const errorFileLine = /__*( *)ERROR collecting (.*)/; - const lastLineWithErrors = /==*.*/; - let haveErrors = false; - - // Remove unwanted arguments - args = args.filter(arg => { - if (argsToExcludeForDiscovery.indexOf(arg.trim()) !== -1) { - return false; - } - if (settingsInArgsToExcludeForDiscovery.some(setting => setting.indexOf(arg.trim()) === 0)) { - return false; - } - return true; - }); - if (ignoreCache && args.indexOf('--cache-clear') === -1) { - args.push('--cache-clear'); - } - function processOutput(output: string) { - output.split(/\r?\n/g).forEach((line, index, lines) => { - if (token && token.isCancellationRequested) { - return; - } - if (line.trim().startsWith(' 1) { - logOutputLines[logOutputLines.length - 1] += line; - logOutputLines.push(''); - return; - } - logOutputLines[logOutputLines.length - 1] += line; - return; - } - if (index === lines.length - 1) { - logOutputLines[logOutputLines.length - 1] += line; - return; - } - logOutputLines[logOutputLines.length - 1] += line; - logOutputLines.push(''); - return; - }); - } - - return execPythonFile(rootDirectory, PythonSettings.getInstance(vscode.Uri.file(rootDirectory)).unitTest.pyTestPath, args.concat(['--collect-only']), rootDirectory, false, null, token) - .then(data => { - outChannel.appendLine(data); - processOutput(data); - if (token && token.isCancellationRequested) { - return Promise.reject('cancelled'); - } - return testsHelper.flattenTestFiles(testFiles); - }); -} - -const DELIMITER = '\''; - -function parsePyTestModuleCollectionError(rootDirectory: string, lines: string[], testFiles: TestFile[], - parentNodes: { indent: number, item: TestFile | TestSuite }[]) { - - lines = lines.filter(line => line.trim().length > 0); - if (lines.length <= 1) { - return; - } - - const errorFileLine = lines[0]; - let fileName = errorFileLine.substring(errorFileLine.indexOf('ERROR collecting') + 'ERROR collecting'.length).trim(); - fileName = fileName.substr(0, fileName.lastIndexOf(' ')); - - const currentPackage = convertFileToPackage(fileName); - const fullyQualifiedName = path.isAbsolute(fileName) ? fileName : path.resolve(rootDirectory, fileName); - const testFile = { - functions: [], suites: [], name: fileName, fullPath: fullyQualifiedName, - nameToRun: fileName, xmlName: currentPackage, time: 0, errorsWhenDiscovering: lines.join('\n') - }; - testFiles.push(testFile); - parentNodes.push({ indent: 0, item: testFile }); - - return; - -} -function parsePyTestModuleCollectionResult(rootDirectory: string, lines: string[], testFiles: TestFile[], parentNodes: { indent: number, item: TestFile | TestSuite }[]) { - let currentPackage: string = ''; - - lines.forEach(line => { - const trimmedLine = line.trim(); - const name = extractBetweenDelimiters(trimmedLine, DELIMITER, DELIMITER); - const indent = line.indexOf('<'); - - if (trimmedLine.startsWith(' 0) { - const parentNode = parentNodes[parentNodes.length - 1]; - if (parentNode.indent < indentOfCurrentItem) { - return parentNode; - } - parentNodes.pop(); - continue; - } - - return null; -} - -/* Sample output from py.test --collect-only - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ diff --git a/src/client/unittests/pytest/main.ts b/src/client/unittests/pytest/main.ts index ee53c93de207..605200b95d78 100644 --- a/src/client/unittests/pytest/main.ts +++ b/src/client/unittests/pytest/main.ts @@ -1,26 +1,37 @@ 'use strict'; -import * as vscode from 'vscode'; +import { Uri } from 'vscode'; import { Product } from '../../common/installer'; -import { BaseTestManager } from '../common/baseTestManager'; -import { ITestCollectionStorageService, ITestDebugLauncher, ITestResultsService, ITestsHelper, Tests, TestsToRun } from '../common/types'; -import { discoverTests } from './collector'; +import { IServiceContainer } from '../../ioc/types'; +import { BaseTestManager } from '../common/managers/baseTestManager'; +import { TestDiscoveryOptions, TestRunOptions, Tests, TestsToRun } from '../common/types'; import { runTest } from './runner'; export class TestManager extends BaseTestManager { - constructor(rootDirectory: string, outputChannel: vscode.OutputChannel, - testCollectionStorage: ITestCollectionStorageService, - testResultsService: ITestResultsService, testsHelper: ITestsHelper, private debugLauncher: ITestDebugLauncher) { - super('pytest', Product.pytest, rootDirectory, outputChannel, testCollectionStorage, testResultsService, testsHelper); + constructor(workspaceFolder: Uri, rootDirectory: string, + serviceContainer: IServiceContainer) { + super('pytest', Product.pytest, workspaceFolder, rootDirectory, serviceContainer); } - public discoverTestsImpl(ignoreCache: boolean): Promise { + public getDiscoveryOptions(ignoreCache: boolean): TestDiscoveryOptions { const args = this.settings.unitTest.pyTestArgs.slice(0); - return discoverTests(this.rootDirectory, args, this.testDiscoveryCancellationToken, ignoreCache, this.outputChannel, this.testsHelper); + return { + workspaceFolder: this.workspaceFolder, + cwd: this.rootDirectory, args, + token: this.testDiscoveryCancellationToken!, ignoreCache, + outChannel: this.outputChannel + }; } - public runTestImpl(tests: Tests, testsToRun?: TestsToRun, runFailedTests?: boolean, debug?: boolean): Promise<{}> { + public async runTestImpl(tests: Tests, testsToRun?: TestsToRun, runFailedTests?: boolean, debug?: boolean): Promise<{}> { const args = this.settings.unitTest.pyTestArgs.slice(0); if (runFailedTests === true && args.indexOf('--lf') === -1 && args.indexOf('--last-failed') === -1) { args.push('--last-failed'); } - return runTest(this.testResultsService, this.debugLauncher, this.rootDirectory, tests, args, testsToRun, this.testRunnerCancellationToken, this.outputChannel, debug); + const options: TestRunOptions = { + workspaceFolder: this.workspaceFolder, + cwd: this.rootDirectory, + tests, args, testsToRun, debug, + token: this.testRunnerCancellationToken!, + outChannel: this.outputChannel + }; + return runTest(this.serviceContainer, this.testResultsService, options); } } diff --git a/src/client/unittests/pytest/runner.ts b/src/client/unittests/pytest/runner.ts index 2ec37a4b8239..408e297d392d 100644 --- a/src/client/unittests/pytest/runner.ts +++ b/src/client/unittests/pytest/runner.ts @@ -1,29 +1,29 @@ 'use strict'; import * as path from 'path'; -import { CancellationToken, OutputChannel, Uri } from 'vscode'; -import { PythonSettings } from '../../common/configSettings'; import { createTemporaryFile } from '../../common/helpers'; -import { run } from '../common/runner'; -import { ITestDebugLauncher, ITestResultsService, Tests, TestsToRun } from '../common/types'; +import { IServiceContainer } from '../../ioc/types'; +import { Options, run } from '../common/runner'; +import { ITestDebugLauncher, ITestResultsService, TestRunOptions, Tests } from '../common/types'; import { PassCalculationFormulae, updateResultsFromXmlLogFile } from '../common/xUnitParser'; -export function runTest(testResultsService: ITestResultsService, debugLauncher: ITestDebugLauncher, rootDirectory: string, tests: Tests, args: string[], testsToRun?: TestsToRun, token?: CancellationToken, outChannel?: OutputChannel, debug?: boolean): Promise { - let testPaths = []; - if (testsToRun && testsToRun.testFolder) { - testPaths = testPaths.concat(testsToRun.testFolder.map(f => f.nameToRun)); +export function runTest(serviceContainer: IServiceContainer, testResultsService: ITestResultsService, options: TestRunOptions): Promise { + let testPaths: string[] = []; + if (options.testsToRun && options.testsToRun.testFolder) { + testPaths = testPaths.concat(options.testsToRun.testFolder.map(f => f.nameToRun)); } - if (testsToRun && testsToRun.testFile) { - testPaths = testPaths.concat(testsToRun.testFile.map(f => f.nameToRun)); + if (options.testsToRun && options.testsToRun.testFile) { + testPaths = testPaths.concat(options.testsToRun.testFile.map(f => f.nameToRun)); } - if (testsToRun && testsToRun.testSuite) { - testPaths = testPaths.concat(testsToRun.testSuite.map(f => f.nameToRun)); + if (options.testsToRun && options.testsToRun.testSuite) { + testPaths = testPaths.concat(options.testsToRun.testSuite.map(f => f.nameToRun)); } - if (testsToRun && testsToRun.testFunction) { - testPaths = testPaths.concat(testsToRun.testFunction.map(f => f.nameToRun)); + if (options.testsToRun && options.testsToRun.testFunction) { + testPaths = testPaths.concat(options.testsToRun.testFunction.map(f => f.nameToRun)); } let xmlLogFile = ''; - let xmlLogFileCleanup: Function = null; + let xmlLogFileCleanup: Function; + let args = options.args; return createTemporaryFile('.xml').then(xmlLogResult => { xmlLogFile = xmlLogResult.filePath; @@ -33,22 +33,29 @@ export function runTest(testResultsService: ITestResultsService, debugLauncher: args = args.filter(arg => arg.trim().startsWith('-')); } const testArgs = testPaths.concat(args, [`--junitxml=${xmlLogFile}`]); - if (debug) { - return debugLauncher.getPort(Uri.file(rootDirectory)) + if (options.debug) { + const debugLauncher = serviceContainer.get(ITestDebugLauncher); + return debugLauncher.getPort(options.workspaceFolder) .then(debugPort => { const testLauncherFile = path.join(__dirname, '..', '..', '..', '..', 'pythonFiles', 'PythonTools', 'testlauncher.py'); - const pytestlauncherargs = [rootDirectory, 'my_secret', debugPort.toString(), 'pytest']; + const pytestlauncherargs = [options.cwd, 'my_secret', debugPort.toString(), 'pytest']; const debuggerArgs = [testLauncherFile].concat(pytestlauncherargs).concat(testArgs); + const launchOptions = { cwd: options.cwd, args: debuggerArgs, token: options.token, outChannel: options.outChannel, port: debugPort }; // tslint:disable-next-line:prefer-type-cast no-any - return debugLauncher.launchDebugger(rootDirectory, debuggerArgs, debugPort, token, outChannel) as Promise; + return debugLauncher.launchDebugger(launchOptions) as Promise; }); } else { - const pythonSettings = PythonSettings.getInstance(Uri.file(rootDirectory)); - // tslint:disable-next-line:prefer-type-cast no-any - return run(pythonSettings.unitTest.pyTestPath, testArgs, rootDirectory, token, outChannel) as Promise; + const runOptions: Options = { + args: testArgs, + cwd: options.cwd, + outChannel: options.outChannel, + token: options.token, + workspaceFolder: options.workspaceFolder + }; + return run(serviceContainer, 'pytest', runOptions); } }).then(() => { - return updateResultsFromLogFiles(tests, xmlLogFile, testResultsService); + return updateResultsFromLogFiles(options.tests, xmlLogFile, testResultsService); }).then(result => { xmlLogFileCleanup(); return result; diff --git a/src/client/unittests/pytest/services/discoveryService.ts b/src/client/unittests/pytest/services/discoveryService.ts new file mode 100644 index 000000000000..8160316bb5f3 --- /dev/null +++ b/src/client/unittests/pytest/services/discoveryService.ts @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { inject, injectable, named } from 'inversify'; +import 'reflect-metadata'; +import { CancellationTokenSource } from 'vscode'; +import { IServiceContainer } from '../../../ioc/types'; +import { PYTEST_PROVIDER, UNITTEST_PROVIDER } from '../../common/constants'; +import { Options, run } from '../../common/runner'; +import { ITestDiscoveryService, ITestsParser, TestDiscoveryOptions, Tests } from '../../common/types'; + +const argsToExcludeForDiscovery = ['-x', '--exitfirst', + '--fixtures-per-test', '--pdb', '--runxfail', + '--lf', '--last-failed', '--ff', '--failed-first', + '--cache-show', '--cache-clear', + '-v', '--verbose', '-q', '-quiet', + '--disable-pytest-warnings', '-l', '--showlocals']; + +type PytestDiscoveryOptions = TestDiscoveryOptions & { + startDirectory: string; + pattern: string; +}; + +@injectable() +export class TestDiscoveryService implements ITestDiscoveryService { + constructor( @inject(IServiceContainer) private serviceContainer: IServiceContainer, + @inject(ITestsParser) @named(PYTEST_PROVIDER) private testParser: ITestsParser) { } + public async discoverTests(options: TestDiscoveryOptions): Promise { + // Remove unwanted arguments + const args = options.args.filter(arg => { + if (argsToExcludeForDiscovery.indexOf(arg.trim()) !== -1) { + return false; + } + return true; + }); + if (options.ignoreCache && args.indexOf('--cache-clear') === -1) { + args.push('--cache-clear'); + } + + const token = options.token ? options.token : new CancellationTokenSource().token; + const runOptions: Options = { + args: args.concat(['--collect-only']), + cwd: options.cwd, + workspaceFolder: options.workspaceFolder, + token, + outChannel: options.outChannel + }; + + const data = await run(this.serviceContainer, PYTEST_PROVIDER, runOptions); + if (options.token && options.token.isCancellationRequested) { + return Promise.reject('cancelled'); + } + + return this.testParser.parse(data, options); + } +} diff --git a/src/client/unittests/pytest/services/parserService.ts b/src/client/unittests/pytest/services/parserService.ts new file mode 100644 index 000000000000..f69b862f342f --- /dev/null +++ b/src/client/unittests/pytest/services/parserService.ts @@ -0,0 +1,197 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { inject, injectable } from 'inversify'; +import * as os from 'os'; +import * as path from 'path'; +import 'reflect-metadata'; +import { convertFileToPackage, extractBetweenDelimiters } from '../../common/testUtils'; +import { ITestsHelper, ITestsParser, ParserOptions, TestDiscoveryOptions, TestFile, TestFunction, Tests, TestStatus, TestSuite } from '../../common/types'; + +const DELIMITER = '\''; + +@injectable() +export class TestsParser implements ITestsParser { + constructor( @inject(ITestsHelper) private testsHelper: ITestsHelper) { } + public parse(content: string, options: ParserOptions): Tests { + const testFiles = this.getTestFiles(content, options); + return this.testsHelper.flattenTestFiles(testFiles); + } + + private getTestFiles(content: string, options: ParserOptions) { + let logOutputLines: string[] = ['']; + const testFiles: TestFile[] = []; + const parentNodes: { indent: number, item: TestFile | TestSuite }[] = []; + + const errorLine = /==*( *)ERRORS( *)=*/; + const errorFileLine = /__*( *)ERROR collecting (.*)/; + const lastLineWithErrors = /==*.*/; + + let haveErrors = false; + + content.split(/\r?\n/g).forEach((line, index, lines) => { + if (options.token && options.token.isCancellationRequested) { + return; + } + if (line.trim().startsWith(' 1) { + logOutputLines[logOutputLines.length - 1] += line; + logOutputLines.push(''); + return; + } + logOutputLines[logOutputLines.length - 1] += line; + return; + } + if (index === lines.length - 1) { + logOutputLines[logOutputLines.length - 1] += line; + return; + } + logOutputLines[logOutputLines.length - 1] += line; + logOutputLines.push(''); + return; + }); + + return testFiles; + } + + private parsePyTestModuleCollectionError(rootDirectory: string, lines: string[], testFiles: TestFile[], + parentNodes: { indent: number, item: TestFile | TestSuite }[]) { + + lines = lines.filter(line => line.trim().length > 0); + if (lines.length <= 1) { + return; + } + + const errorFileLine = lines[0]; + let fileName = errorFileLine.substring(errorFileLine.indexOf('ERROR collecting') + 'ERROR collecting'.length).trim(); + fileName = fileName.substr(0, fileName.lastIndexOf(' ')); + + const currentPackage = convertFileToPackage(fileName); + const fullyQualifiedName = path.isAbsolute(fileName) ? fileName : path.resolve(rootDirectory, fileName); + const testFile = { + functions: [], suites: [], name: fileName, fullPath: fullyQualifiedName, + nameToRun: fileName, xmlName: currentPackage, time: 0, errorsWhenDiscovering: lines.join('\n') + }; + testFiles.push(testFile); + parentNodes.push({ indent: 0, item: testFile }); + + return; + + } + private parsePyTestModuleCollectionResult(rootDirectory: string, lines: string[], testFiles: TestFile[], parentNodes: { indent: number, item: TestFile | TestSuite }[]) { + let currentPackage: string = ''; + + lines.forEach(line => { + const trimmedLine = line.trim(); + const name = extractBetweenDelimiters(trimmedLine, DELIMITER, DELIMITER); + const indent = line.indexOf('<'); + + if (trimmedLine.startsWith(' 0) { + const parentNode = parentNodes[parentNodes.length - 1]; + if (parentNode.indent < indentOfCurrentItem) { + return parentNode; + } + parentNodes.pop(); + continue; + } + + return; + } +} + + /* Sample output from py.test --collect-only + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + */ diff --git a/src/client/unittests/pytest/testConfigurationManager.ts b/src/client/unittests/pytest/testConfigurationManager.ts index 8017835d7b95..9879de96e4ca 100644 --- a/src/client/unittests/pytest/testConfigurationManager.ts +++ b/src/client/unittests/pytest/testConfigurationManager.ts @@ -3,7 +3,7 @@ import * as path from 'path'; import * as vscode from 'vscode'; import { Uri } from 'vscode'; import { Installer, Product } from '../../common/installer'; -import { TestConfigurationManager } from '../common/testConfigurationManager'; +import { TestConfigurationManager } from '../common/managers/testConfigurationManager'; import { ITestConfigSettingsService } from '../common/types'; export class ConfigurationManager extends TestConfigurationManager { @@ -22,7 +22,7 @@ export class ConfigurationManager extends TestConfigurationManager { } // tslint:disable-next-line:no-any public async configure(wkspace: Uri) { - const args = []; + const args: string[] = []; const configFileOptionLabel = 'Use existing config file'; const options: vscode.QuickPickItem[] = []; const configFiles = await ConfigurationManager.configFilesExist(wkspace.fsPath); diff --git a/src/client/unittests/serviceRegistry.ts b/src/client/unittests/serviceRegistry.ts new file mode 100644 index 000000000000..82eae9be62d1 --- /dev/null +++ b/src/client/unittests/serviceRegistry.ts @@ -0,0 +1,80 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import 'reflect-metadata'; +import { Uri } from 'vscode'; +import { IServiceContainer, IServiceManager } from '../ioc/types'; +import { NOSETEST_PROVIDER, PYTEST_PROVIDER, UNITTEST_PROVIDER } from './common/constants'; +import { DebugLauncher } from './common/debugLauncher'; +import { TestCollectionStorageService } from './common/services/storageService'; +import { TestManagerService } from './common/services/testManagerService'; +import { TestResultsService } from './common/services/testResultsService'; +import { WorkspaceTestManagerService } from './common/services/workspaceTestManagerService'; +import { TestsHelper } from './common/testUtils'; +import { TestFlatteningVisitor } from './common/testVisitors/flatteningVisitor'; +import { TestFolderGenerationVisitor } from './common/testVisitors/folderGenerationVisitor'; +import { TestResultResetVisitor } from './common/testVisitors/resultResetVisitor'; +import { ITestCollectionStorageService, ITestDebugLauncher, ITestDiscoveryService, ITestManager, ITestManagerFactory, ITestManagerService, ITestManagerServiceFactory, IUnitTestSocketServer } from './common/types'; +import { ITestResultsService, ITestsHelper, ITestsParser, ITestVisitor, IWorkspaceTestManagerService, TestProvider } from './common/types'; +import { TestManager as NoseTestManager } from './nosetest/main'; +import { TestDiscoveryService as NoseTestDiscoveryService } from './nosetest/services/discoveryService'; +import { TestsParser as NoseTestTestsParser } from './nosetest/services/parserService'; +import { TestManager as PyTestTestManager } from './pytest/main'; +import { TestDiscoveryService as PytestTestDiscoveryService } from './pytest/services/discoveryService'; +import { TestsParser as PytestTestsParser } from './pytest/services/parserService'; +import { TestManager as UnitTestTestManager } from './unittest/main'; +import { TestDiscoveryService as UnitTestTestDiscoveryService } from './unittest/services/discoveryService'; +import { TestsParser as UnitTestTestsParser } from './unittest/services/parserService'; +import { UnitTestSocketServer } from './unittest/socketServer'; + +export function registerTypes(serviceManager: IServiceManager) { + serviceManager.addSingleton(ITestDebugLauncher, DebugLauncher); + serviceManager.addSingleton(ITestCollectionStorageService, TestCollectionStorageService); + serviceManager.addSingleton(IWorkspaceTestManagerService, WorkspaceTestManagerService); + + serviceManager.add(ITestsHelper, TestsHelper); + serviceManager.add(IUnitTestSocketServer, UnitTestSocketServer); + + serviceManager.add(ITestResultsService, TestResultsService); + + serviceManager.add(ITestVisitor, TestFlatteningVisitor, 'TestFlatteningVisitor'); + serviceManager.add(ITestVisitor, TestFolderGenerationVisitor, 'TestFolderGenerationVisitor'); + serviceManager.add(ITestVisitor, TestResultResetVisitor, 'TestResultResetVisitor'); + + serviceManager.add(ITestsParser, UnitTestTestsParser, UNITTEST_PROVIDER); + serviceManager.add(ITestsParser, PytestTestsParser, PYTEST_PROVIDER); + serviceManager.add(ITestsParser, NoseTestTestsParser, NOSETEST_PROVIDER); + + serviceManager.add(ITestDiscoveryService, UnitTestTestDiscoveryService, UNITTEST_PROVIDER); + serviceManager.add(ITestDiscoveryService, PytestTestDiscoveryService, PYTEST_PROVIDER); + serviceManager.add(ITestDiscoveryService, NoseTestDiscoveryService, NOSETEST_PROVIDER); + + serviceManager.addFactory(ITestManagerFactory, (context) => { + return (testProvider: TestProvider, workspaceFolder: Uri, rootDirectory: string) => { + const serviceContainer = context.container.get(IServiceContainer); + + switch (testProvider) { + case NOSETEST_PROVIDER: { + return new NoseTestManager(workspaceFolder, rootDirectory, serviceContainer); + } + case PYTEST_PROVIDER: { + return new PyTestTestManager(workspaceFolder, rootDirectory, serviceContainer); + } + case UNITTEST_PROVIDER: { + return new UnitTestTestManager(workspaceFolder, rootDirectory, serviceContainer); + } + default: { + throw new Error(`Unrecognized test provider '${testProvider}'`); + } + } + }; + }); + + serviceManager.addFactory(ITestManagerServiceFactory, (context) => { + return (workspaceFolder: Uri) => { + const serviceContainer = context.container.get(IServiceContainer); + const testsHelper = context.container.get(ITestsHelper); + return new TestManagerService(workspaceFolder, testsHelper, serviceContainer); + }; + }); +} diff --git a/src/client/unittests/unittest/collector.ts b/src/client/unittests/unittest/collector.ts deleted file mode 100644 index 50c6edc19dec..000000000000 --- a/src/client/unittests/unittest/collector.ts +++ /dev/null @@ -1,154 +0,0 @@ -'use strict'; -import * as path from 'path'; -import * as vscode from 'vscode'; -import { OutputChannel } from 'vscode'; -import { PythonSettings } from '../../common/configSettings'; -import { ITestsHelper, TestFile, TestFunction, Tests, TestStatus, TestSuite } from '../common/types'; -import { execPythonFile } from './../../common/utils'; - -export function discoverTests(rootDirectory: string, args: string[], token: vscode.CancellationToken, ignoreCache: boolean, outChannel: OutputChannel, testsHelper: ITestsHelper): Promise { - let startDirectory = '.'; - let pattern = 'test*.py'; - const indexOfStartDir = args.findIndex(arg => arg.indexOf('-s') === 0); - if (indexOfStartDir >= 0) { - const startDir = args[indexOfStartDir].trim(); - if (startDir.trim() === '-s' && args.length >= indexOfStartDir) { - // Assume the next items is the directory - startDirectory = args[indexOfStartDir + 1]; - } else { - startDirectory = startDir.substring(2).trim(); - if (startDirectory.startsWith('=') || startDirectory.startsWith(' ')) { - startDirectory = startDirectory.substring(1); - } - } - } - const indexOfPattern = args.findIndex(arg => arg.indexOf('-p') === 0); - if (indexOfPattern >= 0) { - const patternValue = args[indexOfPattern].trim(); - if (patternValue.trim() === '-p' && args.length >= indexOfPattern) { - // Assume the next items is the directory - pattern = args[indexOfPattern + 1]; - } else { - pattern = patternValue.substring(2).trim(); - if (pattern.startsWith('=')) { - pattern = pattern.substring(1); - } - } - } - const pythonScript = `import unittest -loader = unittest.TestLoader() -suites = loader.discover("${startDirectory}", pattern="${pattern}") -print("start") #Don't remove this line -for suite in suites._tests: - for cls in suite._tests: - try: - for m in cls._tests: - print(m.id()) - except: - pass`; - - let startedCollecting = false; - const testItems: string[] = []; - function processOutput(output: string) { - output.split(/\r?\n/g).forEach((line, index, lines) => { - if (token && token.isCancellationRequested) { - return; - } - if (!startedCollecting) { - if (line === 'start') { - startedCollecting = true; - } - return; - } - line = line.trim(); - if (line.length === 0) { - return; - } - testItems.push(line); - }); - } - args = []; - return execPythonFile(rootDirectory, PythonSettings.getInstance(vscode.Uri.file(rootDirectory)).pythonPath, args.concat(['-c', pythonScript]), rootDirectory, true, null, token) - .then(data => { - outChannel.appendLine(data); - processOutput(data); - if (token && token.isCancellationRequested) { - return Promise.reject('cancelled'); - } - - let testsDirectory = rootDirectory; - if (startDirectory.length > 1) { - testsDirectory = path.isAbsolute(startDirectory) ? startDirectory : path.resolve(rootDirectory, startDirectory); - } - return parseTestIds(testsDirectory, testItems, testsHelper); - }); -} - -function parseTestIds(rootDirectory: string, testIds: string[], testsHelper: ITestsHelper): Tests { - const testFiles: TestFile[] = []; - testIds.forEach(testId => { - addTestId(rootDirectory, testId, testFiles); - }); - - return testsHelper.flattenTestFiles(testFiles); -} - -function addTestId(rootDirectory: string, testId: string, testFiles: TestFile[]) { - const testIdParts = testId.split('.'); - // We must have a file, class and function name - if (testIdParts.length <= 2) { - return null; - } - - const paths = testIdParts.slice(0, testIdParts.length - 2); - const filePath = `${path.join(rootDirectory, ...paths)}.py`; - const functionName = testIdParts.pop(); - const className = testIdParts.pop(); - - // Check if we already have this test file - let testFile = testFiles.find(test => test.fullPath === filePath); - if (!testFile) { - testFile = { - name: path.basename(filePath), - fullPath: filePath, - // tslint:disable-next-line:prefer-type-cast - functions: [] as TestFunction[], - // tslint:disable-next-line:prefer-type-cast - suites: [] as TestSuite[], - nameToRun: `${className}.${functionName}`, - xmlName: '', - status: TestStatus.Idle, - time: 0 - }; - testFiles.push(testFile); - } - - // Check if we already have this test file - const classNameToRun = className; - let testSuite = testFile.suites.find(cls => cls.nameToRun === classNameToRun); - if (!testSuite) { - testSuite = { - name: className, - // tslint:disable-next-line:prefer-type-cast - functions: [] as TestFunction[], - // tslint:disable-next-line:prefer-type-cast - suites: [] as TestSuite[], - isUnitTest: true, - isInstance: false, - nameToRun: classNameToRun, - xmlName: '', - status: TestStatus.Idle, - time: 0 - }; - testFile.suites.push(testSuite); - } - - const testFunction: TestFunction = { - name: functionName, - nameToRun: testId, - status: TestStatus.Idle, - time: 0 - }; - - testSuite.functions.push(testFunction); -} diff --git a/src/client/unittests/unittest/main.ts b/src/client/unittests/unittest/main.ts index 09e96e307fa5..4fb8ef66063f 100644 --- a/src/client/unittests/unittest/main.ts +++ b/src/client/unittests/unittest/main.ts @@ -1,23 +1,25 @@ 'use strict'; -import * as vscode from 'vscode'; +import { Uri } from 'vscode'; import { Product } from '../../common/installer'; -import { BaseTestManager } from '../common/baseTestManager'; -import { ITestCollectionStorageService, ITestDebugLauncher, ITestResultsService, ITestsHelper, Tests, TestStatus, TestsToRun } from '../common/types'; -import { discoverTests } from './collector'; +import { IServiceContainer } from '../../ioc/types'; +import { BaseTestManager } from '../common/managers/baseTestManager'; +import { TestDiscoveryOptions, TestRunOptions, Tests, TestStatus, TestsToRun } from '../common/types'; import { runTest } from './runner'; export class TestManager extends BaseTestManager { - constructor(rootDirectory: string, outputChannel: vscode.OutputChannel, - testCollectionStorage: ITestCollectionStorageService, - testResultsService: ITestResultsService, testsHelper: ITestsHelper, private debugLauncher: ITestDebugLauncher) { - super('unittest', Product.unittest, rootDirectory, outputChannel, testCollectionStorage, testResultsService, testsHelper); + constructor(workspaceFolder: Uri, rootDirectory: string, serviceContainer: IServiceContainer) { + super('unittest', Product.unittest, workspaceFolder, rootDirectory, serviceContainer); } // tslint:disable-next-line:no-empty public configure() { } - public async discoverTestsImpl(ignoreCache: boolean): Promise { + public getDiscoveryOptions(ignoreCache: boolean): TestDiscoveryOptions { const args = this.settings.unitTest.unittestArgs.slice(0); - // tslint:disable-next-line:no-non-null-assertion - return discoverTests(this.rootDirectory, args, this.testDiscoveryCancellationToken!, ignoreCache, this.outputChannel, this.testsHelper); + return { + workspaceFolder: this.workspaceFolder, + cwd: this.rootDirectory, args, + token: this.testDiscoveryCancellationToken!, ignoreCache, + outChannel: this.outputChannel + }; } public async runTestImpl(tests: Tests, testsToRun?: TestsToRun, runFailedTests?: boolean, debug?: boolean): Promise<{}> { const args = this.settings.unitTest.unittestArgs.slice(0); @@ -27,6 +29,13 @@ export class TestManager extends BaseTestManager { return fn.testFunction.status === TestStatus.Error || fn.testFunction.status === TestStatus.Fail; }).map(fn => fn.testFunction); } - return runTest(this, this.testResultsService, this.debugLauncher, this.rootDirectory, tests, args, testsToRun, this.testRunnerCancellationToken, this.outputChannel, debug); + const options: TestRunOptions = { + workspaceFolder: this.workspaceFolder, + cwd: this.rootDirectory, + tests, args, testsToRun, debug, + token: this.testRunnerCancellationToken!, + outChannel: this.outputChannel + }; + return runTest(this.serviceContainer, this, this.testResultsService, options); } } diff --git a/src/client/unittests/unittest/runner.ts b/src/client/unittests/unittest/runner.ts index c8c2eb05d00d..c848c42e0b82 100644 --- a/src/client/unittests/unittest/runner.ts +++ b/src/client/unittests/unittest/runner.ts @@ -1,14 +1,13 @@ 'use strict'; import * as path from 'path'; -import { CancellationToken, OutputChannel, Uri } from 'vscode'; -import { PythonSettings } from '../../common/configSettings'; -import { BaseTestManager } from '../common/baseTestManager'; -import { run } from '../common/runner'; -import { ITestDebugLauncher, ITestResultsService, Tests, TestStatus, TestsToRun } from '../common/types'; -import { Server } from './socketServer'; +import { IServiceContainer } from '../../ioc/types'; +import { BaseTestManager } from '../common/managers/baseTestManager'; +import { Options, run } from '../common/runner'; +import { ITestDebugLauncher, ITestResultsService, IUnitTestSocketServer, TestRunOptions, Tests, TestStatus, TestsToRun } from '../common/types'; + type TestStatusMap = { status: TestStatus; - summaryProperty: string; + summaryProperty: 'passed' | 'failures' | 'errors' | 'skipped'; }; const outcomeMapping = new Map(); @@ -29,14 +28,14 @@ interface ITestData { } // tslint:disable-next-line:max-func-body-length -export function runTest(testManager: BaseTestManager, testResultsService: ITestResultsService, debugLauncher: ITestDebugLauncher, rootDirectory: string, tests: Tests, args: string[], testsToRun?: TestsToRun, token?: CancellationToken, outChannel?: OutputChannel, debug?: boolean): Promise { - tests.summary.errors = 0; - tests.summary.failures = 0; - tests.summary.passed = 0; - tests.summary.skipped = 0; +export function runTest(serviceContainer: IServiceContainer, testManager: BaseTestManager, testResultsService: ITestResultsService, options: TestRunOptions): Promise { + options.tests.summary.errors = 0; + options.tests.summary.failures = 0; + options.tests.summary.passed = 0; + options.tests.summary.skipped = 0; let failFast = false; const testLauncherFile = path.join(__dirname, '..', '..', '..', '..', 'pythonFiles', 'PythonTools', 'visualstudio_py_testlauncher.py'); - const server = new Server(); + const server = serviceContainer.get(IUnitTestSocketServer); server.on('error', (message: string, ...data: string[]) => { // tslint:disable-next-line:no-console console.log(`${message} ${data.join(' ')}`); @@ -44,43 +43,43 @@ export function runTest(testManager: BaseTestManager, testResultsService: ITestR // tslint:disable-next-line:no-empty server.on('log', (message: string, ...data: string[]) => { }); - // tslint:disable-next-line:no-empty - server.on('connect', (data) => { + // tslint:disable-next-line:no-empty no-any + server.on('connect', (data: any) => { }); // tslint:disable-next-line:no-empty server.on('start', (data: { test: string }) => { }); server.on('result', (data: ITestData) => { - const test = tests.testFunctions.find(t => t.testFunction.nameToRun === data.test); - const statusDetails = outcomeMapping.get(data.outcome); + const test = options.tests.testFunctions.find(t => t.testFunction.nameToRun === data.test); + const statusDetails = outcomeMapping.get(data.outcome)!; if (test) { test.testFunction.status = statusDetails.status; test.testFunction.message = data.message; test.testFunction.traceback = data.traceback; - tests.summary[statusDetails.summaryProperty] += 1; + options.tests.summary[statusDetails.summaryProperty] += 1; if (failFast && (statusDetails.summaryProperty === 'failures' || statusDetails.summaryProperty === 'errors')) { testManager.stop(); } } else { if (statusDetails) { - tests.summary[statusDetails.summaryProperty] += 1; + options.tests.summary[statusDetails.summaryProperty] += 1; } } }); - // tslint:disable-next-line:no-empty - server.on('socket.disconnected', (data) => { + // tslint:disable-next-line:no-empty no-any + server.on('socket.disconnected', (data: any) => { }); return server.start().then(port => { - const testPaths: string[] = getIdsOfTestsToRun(tests, testsToRun); + const testPaths: string[] = getIdsOfTestsToRun(options.tests, options.testsToRun!); for (let counter = 0; counter < testPaths.length; counter += 1) { testPaths[counter] = `-t${testPaths[counter].trim()}`; } - const startTestDiscoveryDirectory = getStartDirectory(args); + const startTestDiscoveryDirectory = getStartDirectory(options.args); function runTestInternal(testFile: string = '', testId: string = '') { - let testArgs = buildTestArgs(args); + let testArgs = buildTestArgs(options.args); failFast = testArgs.indexOf('--uf') >= 0; testArgs = testArgs.filter(arg => arg !== '--uf'); @@ -92,16 +91,25 @@ export function runTest(testManager: BaseTestManager, testResultsService: ITestR if (testFile.length > 0) { testArgs.push(`--testFile=${testFile}`); } - if (debug === true) { - return debugLauncher.getPort(Uri.file(rootDirectory)) + if (options.debug === true) { + const debugLauncher = serviceContainer.get(ITestDebugLauncher); + return debugLauncher.getPort(options.workspaceFolder) .then(debugPort => { testArgs.push(...['--secret=my_secret', `--port=${debugPort}`]); + const launchOptions = { cwd: options.cwd, args: [testLauncherFile].concat(testArgs), token: options.token, outChannel: options.outChannel, port: debugPort }; // tslint:disable-next-line:prefer-type-cast no-any - return debugLauncher.launchDebugger(rootDirectory, [testLauncherFile].concat(testArgs), debugPort, token, outChannel); + return debugLauncher.launchDebugger(launchOptions); }); } else { // tslint:disable-next-line:prefer-type-cast no-any - return run(PythonSettings.getInstance(Uri.file(rootDirectory)).pythonPath, [testLauncherFile].concat(testArgs), rootDirectory, token, outChannel); + const runOptions: Options = { + args: [testLauncherFile].concat(testArgs), + cwd: options.cwd, + outChannel: options.outChannel, + token: options.token, + workspaceFolder: options.workspaceFolder + }; + return run(serviceContainer, 'unittest', runOptions); } } @@ -112,22 +120,22 @@ export function runTest(testManager: BaseTestManager, testResultsService: ITestR // Ok, the ptvs test runner can only work with one test at a time let promise = Promise.resolve(''); - if (Array.isArray(testsToRun.testFile)) { - testsToRun.testFile.forEach(testFile => { + if (Array.isArray(options.testsToRun!.testFile)) { + options.testsToRun!.testFile!.forEach(testFile => { // tslint:disable-next-line:prefer-type-cast no-any promise = promise.then(() => runTestInternal(testFile.fullPath, testFile.nameToRun) as Promise); }); } - if (Array.isArray(testsToRun.testSuite)) { - testsToRun.testSuite.forEach(testSuite => { - const testFileName = tests.testSuites.find(t => t.testSuite === testSuite).parentTestFile.fullPath; + if (Array.isArray(options.testsToRun!.testSuite)) { + options.testsToRun!.testSuite!.forEach(testSuite => { + const testFileName = options.tests.testSuites.find(t => t.testSuite === testSuite)!.parentTestFile.fullPath; // tslint:disable-next-line:prefer-type-cast no-any promise = promise.then(() => runTestInternal(testFileName, testSuite.nameToRun) as Promise); }); } - if (Array.isArray(testsToRun.testFunction)) { - testsToRun.testFunction.forEach(testFn => { - const testFileName = tests.testFunctions.find(t => t.testFunction === testFn).parentTestFile.fullPath; + if (Array.isArray(options.testsToRun!.testFunction)) { + options.testsToRun!.testFunction!.forEach(testFn => { + const testFileName = options.tests.testFunctions.find(t => t.testFunction === testFn)!.parentTestFile.fullPath; // tslint:disable-next-line:prefer-type-cast no-any promise = promise.then(() => runTestInternal(testFileName, testFn.nameToRun) as Promise); }); @@ -135,8 +143,8 @@ export function runTest(testManager: BaseTestManager, testResultsService: ITestR // tslint:disable-next-line:prefer-type-cast no-any return promise as Promise; }).then(() => { - testResultsService.updateResults(tests); - return tests; + testResultsService.updateResults(options.tests); + return options.tests; }).catch(reason => { return Promise.reject(reason); }); @@ -186,7 +194,7 @@ function buildTestArgs(args: string[]): string[] { return testArgs; } function getIdsOfTestsToRun(tests: Tests, testsToRun: TestsToRun): string[] { - const testIds = []; + const testIds: string[] = []; if (testsToRun && testsToRun.testFolder) { // Get test ids of files in these folders testsToRun.testFolder.map(folder => { diff --git a/src/client/unittests/unittest/services/discoveryService.ts b/src/client/unittests/unittest/services/discoveryService.ts new file mode 100644 index 000000000000..f323272cec04 --- /dev/null +++ b/src/client/unittests/unittest/services/discoveryService.ts @@ -0,0 +1,94 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { inject, injectable, named } from 'inversify'; +import 'reflect-metadata'; +import { IServiceContainer } from '../../../ioc/types'; +import { UNITTEST_PROVIDER } from '../../common/constants'; +import { Options, run } from '../../common/runner'; +import { ITestDiscoveryService, ITestsParser, TestDiscoveryOptions, Tests } from '../../common/types'; + +type UnitTestDiscoveryOptions = TestDiscoveryOptions & { + startDirectory: string; + pattern: string; +}; + +@injectable() +export class TestDiscoveryService implements ITestDiscoveryService { + constructor( @inject(IServiceContainer) private serviceContainer: IServiceContainer, + @inject(ITestsParser) @named(UNITTEST_PROVIDER) private testParser: ITestsParser) { } + public async discoverTests(options: TestDiscoveryOptions): Promise { + const pythonScript = this.getDiscoveryScript(options); + const unitTestOptions = this.translateOptions(options); + const runOptions: Options = { + args: ['-c', pythonScript], + cwd: options.cwd, + workspaceFolder: options.workspaceFolder, + token: options.token, + outChannel: options.outChannel + }; + + const data = await run(this.serviceContainer, UNITTEST_PROVIDER, runOptions); + + if (options.token && options.token.isCancellationRequested) { + return Promise.reject('cancelled'); + } + + return this.testParser.parse(data, unitTestOptions); + } + public getDiscoveryScript(options: TestDiscoveryOptions): string { + const unitTestOptions = this.translateOptions(options); + return ` +import unittest +loader = unittest.TestLoader() +suites = loader.discover("${unitTestOptions.startDirectory}", pattern="${unitTestOptions.pattern}") +print("start") #Don't remove this line +for suite in suites._tests: + for cls in suite._tests: + try: + for m in cls._tests: + print(m.id()) + except: + pass`; + } + public translateOptions(options: TestDiscoveryOptions): UnitTestDiscoveryOptions { + const unitTestOptions = { ...options } as UnitTestDiscoveryOptions; + unitTestOptions.startDirectory = this.getStartDirectory(options); + unitTestOptions.pattern = this.getTestPattern(options); + return unitTestOptions; + } + private getStartDirectory(options: TestDiscoveryOptions) { + let startDirectory = '.'; + const indexOfStartDir = options.args.findIndex(arg => arg.indexOf('-s') === 0); + if (indexOfStartDir >= 0) { + const startDir = options.args[indexOfStartDir].trim(); + if (startDir.trim() === '-s' && options.args.length >= indexOfStartDir) { + // Assume the next items is the directory + startDirectory = options.args[indexOfStartDir + 1]; + } else { + startDirectory = startDir.substring(2).trim(); + if (startDirectory.startsWith('=') || startDirectory.startsWith(' ')) { + startDirectory = startDirectory.substring(1); + } + } + } + return startDirectory; + } + private getTestPattern(options: TestDiscoveryOptions) { + let pattern = 'test*.py'; + const indexOfPattern = options.args.findIndex(arg => arg.indexOf('-p') === 0); + if (indexOfPattern >= 0) { + const patternValue = options.args[indexOfPattern].trim(); + if (patternValue.trim() === '-p' && options.args.length >= indexOfPattern) { + // Assume the next items is the directory + pattern = options.args[indexOfPattern + 1]; + } else { + pattern = patternValue.substring(2).trim(); + if (pattern.startsWith('=')) { + pattern = pattern.substring(1); + } + } + } + return pattern; + } +} diff --git a/src/client/unittests/unittest/services/parserService.ts b/src/client/unittests/unittest/services/parserService.ts new file mode 100644 index 000000000000..c9270c43fbee --- /dev/null +++ b/src/client/unittests/unittest/services/parserService.ts @@ -0,0 +1,104 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { inject, injectable } from 'inversify'; +import * as path from 'path'; +import 'reflect-metadata'; +import { ITestsHelper, ITestsParser, TestDiscoveryOptions, TestFile, TestFunction, Tests, TestStatus, TestSuite } from '../../common/types'; + +type UnitTestParserOptions = TestDiscoveryOptions & { startDirectory: string }; + +@injectable() +export class TestsParser implements ITestsParser { + constructor( @inject(ITestsHelper) private testsHelper: ITestsHelper) { } + public parse(content: string, options: UnitTestParserOptions): Tests { + const testIds = this.getTestIds(content); + let testsDirectory = options.cwd; + if (options.startDirectory.length > 1) { + testsDirectory = path.isAbsolute(options.startDirectory) ? options.startDirectory : path.resolve(options.cwd, options.startDirectory); + } + return this.parseTestIds(testsDirectory, testIds); + } + private getTestIds(content: string): string[] { + let startedCollecting = false; + return content.split(/\r?\n/g) + .map((line, index) => { + if (!startedCollecting) { + if (line === 'start') { + startedCollecting = true; + } + return ''; + } + return line.trim(); + }) + .filter(line => line.length > 0); + } + private parseTestIds(rootDirectory: string, testIds: string[]): Tests { + const testFiles: TestFile[] = []; + testIds.forEach(testId => { + this.addTestId(rootDirectory, testId, testFiles); + }); + + return this.testsHelper.flattenTestFiles(testFiles); + } + + private addTestId(rootDirectory: string, testId: string, testFiles: TestFile[]) { + const testIdParts = testId.split('.'); + // We must have a file, class and function name + if (testIdParts.length <= 2) { + return null; + } + + const paths = testIdParts.slice(0, testIdParts.length - 2); + const filePath = `${path.join(rootDirectory, ...paths)}.py`; + const functionName = testIdParts.pop()!; + const className = testIdParts.pop()!; + + // Check if we already have this test file + let testFile = testFiles.find(test => test.fullPath === filePath); + if (!testFile) { + testFile = { + name: path.basename(filePath), + fullPath: filePath, + // tslint:disable-next-line:prefer-type-cast + functions: [] as TestFunction[], + // tslint:disable-next-line:prefer-type-cast + suites: [] as TestSuite[], + nameToRun: `${className}.${functionName}`, + xmlName: '', + status: TestStatus.Idle, + time: 0 + }; + testFiles.push(testFile); + } + + // Check if we already have this test file + const classNameToRun = className; + let testSuite = testFile.suites.find(cls => cls.nameToRun === classNameToRun); + if (!testSuite) { + testSuite = { + name: className, + // tslint:disable-next-line:prefer-type-cast + functions: [] as TestFunction[], + // tslint:disable-next-line:prefer-type-cast + suites: [] as TestSuite[], + isUnitTest: true, + isInstance: false, + nameToRun: classNameToRun, + xmlName: '', + status: TestStatus.Idle, + time: 0 + }; + testFile.suites.push(testSuite!); + } + + const testFunction: TestFunction = { + name: functionName, + nameToRun: testId, + status: TestStatus.Idle, + time: 0 + }; + + testSuite!.functions.push(testFunction); + } +} diff --git a/src/client/unittests/unittest/socketServer.ts b/src/client/unittests/unittest/socketServer.ts index 334ae6b85c4e..7357ab1e6eb9 100644 --- a/src/client/unittests/unittest/socketServer.ts +++ b/src/client/unittests/unittest/socketServer.ts @@ -1,10 +1,11 @@ 'use strict'; import { EventEmitter } from 'events'; import * as fs from 'fs'; +import { injectable } from 'inversify'; import * as net from 'net'; import * as os from 'os'; -import { Disposable } from 'vscode'; import { createDeferred, Deferred } from '../../common/helpers'; +import { IUnitTestSocketServer } from '../common/types'; // tslint:disable-next-line:variable-name const MaxConnections = 100; @@ -21,9 +22,10 @@ function getIPType() { return IPType; } -export class Server extends EventEmitter implements Disposable { - private server: net.Server; - private startedDef: Deferred; +@injectable() +export class UnitTestSocketServer extends EventEmitter implements IUnitTestSocketServer { + private server?: net.Server; + private startedDef?: Deferred; private path: string; private sockets: net.Socket[] = []; private ipcBuffer: string = ''; @@ -39,30 +41,30 @@ export class Server extends EventEmitter implements Disposable { } public stop() { if (this.server) { - this.server.close(); - this.server = null; + this.server!.close(); + this.server = undefined; } } public start(): Promise { this.startedDef = createDeferred(); fs.unlink(this.path, () => { this.server = net.createServer(this.connectionListener.bind(this)); - this.server.maxConnections = MaxConnections; - this.server.on('error', (err) => { + this.server!.maxConnections = MaxConnections; + this.server!.on('error', (err) => { if (this.startedDef) { this.startedDef.reject(err); - this.startedDef = null; + this.startedDef = undefined; } this.emit('error', err); }); this.log('starting server as', 'TCP'); - this.server.listen(0, this.path, (socket: net.Socket) => { - this.startedDef.resolve(this.server.address().port); - this.startedDef = null; + this.server!.listen(0, this.path, (socket: net.Socket) => { + this.startedDef!.resolve(this.server!.address().port); + this.startedDef = undefined; this.emit('start', socket); }); }); - return this.startedDef.promise; + return this.startedDef!.promise; } private connectionListener(socket: net.Socket) { diff --git a/src/client/unittests/unittest/testConfigurationManager.ts b/src/client/unittests/unittest/testConfigurationManager.ts index 87334cd72746..2ac74641765b 100644 --- a/src/client/unittests/unittest/testConfigurationManager.ts +++ b/src/client/unittests/unittest/testConfigurationManager.ts @@ -1,7 +1,6 @@ -import * as path from 'path'; import { OutputChannel, Uri } from 'vscode'; import { Installer, Product } from '../../common/installer'; -import { TestConfigurationManager } from '../common/testConfigurationManager'; +import { TestConfigurationManager } from '../common/managers/testConfigurationManager'; import { ITestConfigSettingsService } from '../common/types'; export class ConfigurationManager extends TestConfigurationManager { diff --git a/src/test/common.ts b/src/test/common.ts index fef6a58aa34b..702bb51679a1 100644 --- a/src/test/common.ts +++ b/src/test/common.ts @@ -15,9 +15,9 @@ export type PythonSettingKeys = 'workspaceSymbols.enabled' | 'pythonPath' | 'unitTest.nosetestArgs' | 'unitTest.pyTestArgs' | 'unitTest.unittestArgs' | 'formatting.provider' | 'sortImports.args' | 'unitTest.nosetestsEnabled' | 'unitTest.pyTestEnabled' | 'unitTest.unittestEnabled' | - 'linting.enabledWithoutWorkspace'; + 'linting.enabledWithoutWorkspace' | 'envFile'; -export async function updateSetting(setting: PythonSettingKeys, value: {}, resource: Uri | undefined, configTarget: ConfigurationTarget) { +export async function updateSetting(setting: PythonSettingKeys, value: {} | undefined, resource: Uri | undefined, configTarget: ConfigurationTarget) { const settings = workspace.getConfiguration('python', resource); const currentValue = settings.inspect(setting); if (currentValue !== undefined && ((configTarget === ConfigurationTarget.Global && currentValue.globalValue === value) || @@ -52,7 +52,7 @@ export function retryAsync(wrapped: Function, retryCount: number = 2) { const makeCall = () => { // tslint:disable-next-line:no-unsafe-any no-any no-invalid-this - wrapped.call(this, ...args) + wrapped.call(this as Function, ...args) // tslint:disable-next-line:no-unsafe-any no-any .then(resolve, (reason: any) => { reasons.push(reason); diff --git a/src/test/common/configSettings.test.ts b/src/test/common/configSettings.test.ts index 616c29d5afab..7cb37ac57d65 100644 --- a/src/test/common/configSettings.test.ts +++ b/src/test/common/configSettings.test.ts @@ -1,25 +1,15 @@ -// -// Note: This example test is leveraging the Mocha test framework. -// Please refer to their documentation on https://mochajs.org/ for help. -// - -// The module 'assert' provides assertion methods from node import * as assert from 'assert'; - -// You can import and use all API from the 'vscode' module -// as well as import your extension to test it -import * as vscode from 'vscode'; import * as path from 'path'; -import { initialize, IS_MULTI_ROOT_TEST, IS_TRAVIS } from './../initialize'; +import * as vscode from 'vscode'; import { PythonSettings } from '../../client/common/configSettings'; -import { SystemVariables } from '../../client/common/systemVariables'; -import { rootWorkspaceUri } from '../common'; +import { SystemVariables } from '../../client/common/variables/systemVariables'; +import { initialize, IS_MULTI_ROOT_TEST } from './../initialize'; const workspaceRoot = path.join(__dirname, '..', '..', '..', 'src', 'test'); // Defines a Mocha test suite to group tests of similar kind together suite('Configuration Settings', () => { - setup(() => initialize()); + setup(initialize); if (!IS_MULTI_ROOT_TEST) { test('Check Values', done => { @@ -34,6 +24,7 @@ suite('Configuration Settings', () => { if (settingValue) { settingValue = systemVariables.resolve(settingValue); } + // tslint:disable-next-line:no-any assert.deepEqual(settingValue, (pythonSettings as any)[key], `Setting ${key} not the same`); }); diff --git a/src/test/common/process/decoder.test.ts b/src/test/common/process/decoder.test.ts new file mode 100644 index 000000000000..91a4dc21034a --- /dev/null +++ b/src/test/common/process/decoder.test.ts @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { expect } from 'chai'; +import { encode, encodingExists } from 'iconv-lite'; +import { BufferDecoder } from '../../../client/common/process/decoder'; +import { initialize } from './../../initialize'; + +suite('Decoder', () => { + setup(initialize); + teardown(initialize); + + test('Test decoding utf8 strings', () => { + const value = 'Sample input string Сделать это'; + const buffer = encode(value, 'utf8'); + const decoder = new BufferDecoder(); + const decodedValue = decoder.decode([buffer]); + expect(decodedValue).equal(value, 'Decoded string is incorrect'); + }); + + test('Test decoding cp932 strings', function () { + if (!encodingExists('cp866')) { + // tslint:disable-next-line:no-invalid-this + this.skip(); + } + const value = 'Sample input string Сделать это'; + const buffer = encode(value, 'cp866'); + const decoder = new BufferDecoder(); + let decodedValue = decoder.decode([buffer]); + expect(decodedValue).not.equal(value, 'Decoded string is the same'); + + decodedValue = decoder.decode([buffer], 'cp866'); + expect(decodedValue).equal(value, 'Decoded string is incorrect'); + }); + +}); diff --git a/src/test/common/process/proc.exec.test.ts b/src/test/common/process/proc.exec.test.ts new file mode 100644 index 000000000000..1a1ae6b0723c --- /dev/null +++ b/src/test/common/process/proc.exec.test.ts @@ -0,0 +1,151 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { expect, use } from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import { CancellationTokenSource } from 'vscode'; +import { PythonSettings } from '../../../client/common/configSettings'; +import { BufferDecoder } from '../../../client/common/process/decoder'; +import { ProcessService } from '../../../client/common/process/proc'; +import { StdErrError } from '../../../client/common/process/types'; +import { initialize } from './../../initialize'; + +use(chaiAsPromised); + +// tslint:disable-next-line:max-func-body-length +suite('ProcessService', () => { + let pythonPath: string; + suiteSetup(() => { + pythonPath = PythonSettings.getInstance().pythonPath; + return initialize(); + }); + setup(initialize); + teardown(initialize); + + test('exec should output print statements', async () => { + const procService = new ProcessService(new BufferDecoder()); + const printOutput = '1234'; + const result = await procService.exec(pythonPath, ['-c', `print("${printOutput}")`]); + + expect(result).not.to.be.an('undefined', 'result is undefined'); + expect(result.stdout.trim()).to.be.equal(printOutput, 'Invalid output'); + expect(result.stderr).to.equal(undefined, 'stderr not undefined'); + }); + + test('exec should wait for completion of program with new lines', async function () { + // tslint:disable-next-line:no-invalid-this + this.timeout(5000); + const procService = new ProcessService(new BufferDecoder()); + const pythonCode = ['import sys', 'import time', + 'print("1")', 'sys.stdout.flush()', 'time.sleep(1)', + 'print("2")', 'sys.stdout.flush()', 'time.sleep(1)', + 'print("3")']; + const result = await procService.exec(pythonPath, ['-c', pythonCode.join(';')]); + const outputs = ['1', '2', '3']; + + expect(result).not.to.be.an('undefined', 'result is undefined'); + const values = result.stdout.split(/\r?\n/g).map(line => line.trim()).filter(line => line.length > 0); + expect(values).to.deep.equal(outputs, 'Output values are incorrect'); + expect(result.stderr).to.equal(undefined, 'stderr not undefined'); + }); + + test('exec should wait for completion of program without new lines', async function () { + // tslint:disable-next-line:no-invalid-this + this.timeout(5000); + const procService = new ProcessService(new BufferDecoder()); + const pythonCode = ['import sys', 'import time', + 'sys.stdout.write("1")', 'sys.stdout.flush()', 'time.sleep(1)', + 'sys.stdout.write("2")', 'sys.stdout.flush()', 'time.sleep(1)', + 'sys.stdout.write("3")']; + const result = await procService.exec(pythonPath, ['-c', pythonCode.join(';')]); + const outputs = ['123']; + + expect(result).not.to.be.an('undefined', 'result is undefined'); + const values = result.stdout.split(/\r?\n/g).map(line => line.trim()).filter(line => line.length > 0); + expect(values).to.deep.equal(outputs, 'Output values are incorrect'); + expect(result.stderr).to.equal(undefined, 'stderr not undefined'); + }); + + test('exec should end when cancellationToken is cancelled', async function () { + // tslint:disable-next-line:no-invalid-this + this.timeout(15000); + const procService = new ProcessService(new BufferDecoder()); + const pythonCode = ['import sys', 'import time', + 'print("1")', 'sys.stdout.flush()', 'time.sleep(10)', + 'print("2")', 'sys.stdout.flush()']; + const cancellationToken = new CancellationTokenSource(); + setTimeout(() => cancellationToken.cancel(), 3000); + + const result = await procService.exec(pythonPath, ['-c', pythonCode.join(';')], { token: cancellationToken.token }); + + expect(result).not.to.be.an('undefined', 'result is undefined'); + const values = result.stdout.split(/\r?\n/g).map(line => line.trim()).filter(line => line.length > 0); + expect(values).to.deep.equal(['1'], 'Output values are incorrect'); + expect(result.stderr).to.equal(undefined, 'stderr not undefined'); + }); + + test('exec should stream stdout and stderr separately', async function () { + // tslint:disable-next-line:no-invalid-this + this.timeout(7000); + const procService = new ProcessService(new BufferDecoder()); + const pythonCode = ['import sys', 'import time', + 'print("1")', 'sys.stdout.flush()', 'time.sleep(1)', + 'sys.stderr.write("a")', 'sys.stderr.flush()', 'time.sleep(1)', + 'print("2")', 'sys.stdout.flush()', 'time.sleep(1)', + 'sys.stderr.write("b")', 'sys.stderr.flush()', 'time.sleep(1)', + 'print("3")', 'sys.stdout.flush()', 'time.sleep(1)', + 'sys.stderr.write("c")', 'sys.stderr.flush()']; + const result = await procService.exec(pythonPath, ['-c', pythonCode.join(';')]); + const expectedStdout = ['1', '2', '3']; + const expectedStderr = ['abc']; + + expect(result).not.to.be.an('undefined', 'result is undefined'); + const stdouts = result.stdout.split(/\r?\n/g).map(line => line.trim()).filter(line => line.length > 0); + expect(stdouts).to.deep.equal(expectedStdout, 'stdout values are incorrect'); + const stderrs = result.stderr!.split(/\r?\n/g).map(line => line.trim()).filter(line => line.length > 0); + expect(stderrs).to.deep.equal(expectedStderr, 'stderr values are incorrect'); + }); + + test('exec should merge stdout and stderr streams', async function () { + // tslint:disable-next-line:no-invalid-this + this.timeout(7000); + const procService = new ProcessService(new BufferDecoder()); + const pythonCode = ['import sys', 'import time', + 'sys.stdout.write("1")', 'sys.stdout.flush()', 'time.sleep(1)', + 'sys.stderr.write("a")', 'sys.stderr.flush()', 'time.sleep(1)', + 'sys.stdout.write("2")', 'sys.stdout.flush()', 'time.sleep(1)', + 'sys.stderr.write("b")', 'sys.stderr.flush()', 'time.sleep(1)', + 'sys.stdout.write("3")', 'sys.stdout.flush()', 'time.sleep(1)', + 'sys.stderr.write("c")', 'sys.stderr.flush()']; + const result = await procService.exec(pythonPath, ['-c', pythonCode.join(';')], { mergeStdOutErr: true }); + const expectedOutput = ['1a2b3c']; + + expect(result).not.to.be.an('undefined', 'result is undefined'); + expect(result.stderr).to.equal(undefined, 'stderr not undefined'); + const outputs = result.stdout.split(/\r?\n/g).map(line => line.trim()).filter(line => line.length > 0); + expect(outputs).to.deep.equal(expectedOutput, 'Output values are incorrect'); + }); + + test('exec should throw an error with stderr output', async () => { + const procService = new ProcessService(new BufferDecoder()); + const pythonCode = ['import sys', 'sys.stderr.write("a")', 'sys.stderr.flush()']; + const result = procService.exec(pythonPath, ['-c', pythonCode.join(';')], { throwOnStdErr: true }); + + await expect(result).to.eventually.be.rejectedWith(StdErrError, 'a', 'Expected error to be thrown'); + }); + + test('exec should throw an error when spawn file not found', async () => { + const procService = new ProcessService(new BufferDecoder()); + const result = procService.exec(Date.now().toString(), []); + + await expect(result).to.eventually.be.rejected.and.to.have.property('code', 'ENOENT', 'Invalid error code'); + }); + + test('exec should exit without no output', async () => { + const procService = new ProcessService(new BufferDecoder()); + const result = await procService.exec(pythonPath, ['-c', 'import sys', 'sys.exit()']); + + expect(result.stdout).equals('', 'stdout is invalid'); + expect(result.stderr).equals(undefined, 'stderr is invalid'); + }); +}); diff --git a/src/test/common/process/proc.observable.test.ts b/src/test/common/process/proc.observable.test.ts new file mode 100644 index 000000000000..f67c322d75cc --- /dev/null +++ b/src/test/common/process/proc.observable.test.ts @@ -0,0 +1,227 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { expect, use } from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import { CancellationTokenSource } from 'vscode'; +import { PythonSettings } from '../../../client/common/configSettings'; +import { BufferDecoder } from '../../../client/common/process/decoder'; +import { ProcessService } from '../../../client/common/process/proc'; +import { initialize } from './../../initialize'; + +use(chaiAsPromised); + +// tslint:disable-next-line:max-func-body-length +suite('ProcessService', () => { + let pythonPath: string; + suiteSetup(() => { + pythonPath = PythonSettings.getInstance().pythonPath; + return initialize(); + }); + setup(initialize); + teardown(initialize); + + test('execObservable should output print statements', async () => { + const procService = new ProcessService(new BufferDecoder()); + const printOutput = '1234'; + const result = procService.execObservable(pythonPath, ['-c', `print("${printOutput}")`]); + + expect(result).not.to.be.an('undefined', 'result is undefined'); + const output = await result.out.toPromise(); + expect(output.source).to.be.equal('stdout', 'Source is incorrect'); + expect(output.out).to.have.length.greaterThan(0, 'Invalid output length'); + const stdOut = output.out.trim(); + expect(stdOut).to.equal(printOutput, 'Output is incorrect'); + }); + + test('execObservable should stream output with new lines', function (done) { + // tslint:disable-next-line:no-invalid-this + this.timeout(5000); + const procService = new ProcessService(new BufferDecoder()); + const pythonCode = ['import sys', 'import time', + 'print("1")', 'sys.stdout.flush()', 'time.sleep(1)', + 'print("2")', 'sys.stdout.flush()', 'time.sleep(1)', + 'print("3")']; + const result = procService.execObservable(pythonPath, ['-c', pythonCode.join(';')]); + const outputs = ['1', '2', '3']; + + expect(result).not.to.be.an('undefined', 'result is undefined'); + result.out.subscribe(output => { + const expectedValue = outputs.shift(); + if (expectedValue !== output.out.trim() || expectedValue === output.out) { + done(`Received value ${output.out} is not same as the expectd value ${expectedValue}`); + } + if (output.source !== 'stdout') { + done(`Source is not stdout. Value received is ${output.source}`); + } + }, done, done); + }); + + test('execObservable should stream output without new lines', function (done) { + // tslint:disable-next-line:no-invalid-this + this.timeout(5000); + const procService = new ProcessService(new BufferDecoder()); + const pythonCode = ['import sys', 'import time', + 'sys.stdout.write("1")', 'sys.stdout.flush()', 'time.sleep(1)', + 'sys.stdout.write("2")', 'sys.stdout.flush()', 'time.sleep(1)', + 'sys.stdout.write("3")']; + const result = procService.execObservable(pythonPath, ['-c', pythonCode.join(';')]); + const outputs = ['1', '2', '3']; + + expect(result).not.to.be.an('undefined', 'result is undefined'); + result.out.subscribe(output => { + const expectedValue = outputs.shift(); + if (expectedValue !== output.out) { + done(`Received value ${output.out} is not same as the expectd value ${expectedValue}`); + } + if (output.source !== 'stdout') { + done(`Source is not stdout. Value received is ${output.source}`); + } + }, done, done); + }); + + test('execObservable should end when cancellationToken is cancelled', function (done) { + // tslint:disable-next-line:no-invalid-this + this.timeout(15000); + const procService = new ProcessService(new BufferDecoder()); + const pythonCode = ['import sys', 'import time', + 'print("1")', 'sys.stdout.flush()', 'time.sleep(10)', + 'print("2")', 'sys.stdout.flush()']; + const cancellationToken = new CancellationTokenSource(); + const result = procService.execObservable(pythonPath, ['-c', pythonCode.join(';')], { token: cancellationToken.token }); + + expect(result).not.to.be.an('undefined', 'result is undefined'); + result.out.subscribe(output => { + const value = output.out.trim(); + if (value === '1') { + cancellationToken.cancel(); + } else { + done('Output received when we shouldn\'t have.'); + } + }, done, () => { + const errorMsg = cancellationToken.token.isCancellationRequested ? undefined : 'Program terminated even before cancelling it.'; + done(errorMsg); + }); + }); + + test('execObservable should end when process is killed', function (done) { + // tslint:disable-next-line:no-invalid-this + this.timeout(15000); + const procService = new ProcessService(new BufferDecoder()); + const pythonCode = ['import sys', 'import time', + 'print("1")', 'sys.stdout.flush()', 'time.sleep(10)', + 'print("2")', 'sys.stdout.flush()']; + const cancellationToken = new CancellationTokenSource(); + const result = procService.execObservable(pythonPath, ['-c', pythonCode.join(';')], { token: cancellationToken.token }); + let procKilled = false; + + expect(result).not.to.be.an('undefined', 'result is undefined'); + result.out.subscribe(output => { + const value = output.out.trim(); + if (value === '1') { + procKilled = true; + result.proc.kill(); + } else { + done('Output received when we shouldn\'t have.'); + } + }, done, () => { + const errorMsg = procKilled ? undefined : 'Program terminated even before killing it.'; + done(errorMsg); + }); + }); + + test('execObservable should stream stdout and stderr separately', function (done) { + // tslint:disable-next-line:no-invalid-this + this.timeout(7000); + const procService = new ProcessService(new BufferDecoder()); + const pythonCode = ['import sys', 'import time', + 'print("1")', 'sys.stdout.flush()', 'time.sleep(1)', + 'sys.stderr.write("a")', 'sys.stderr.flush()', 'time.sleep(1)', + 'print("2")', 'sys.stdout.flush()', 'time.sleep(1)', + 'sys.stderr.write("b")', 'sys.stderr.flush()', 'time.sleep(1)', + 'print("3")', 'sys.stdout.flush()', 'time.sleep(1)', + 'sys.stderr.write("c")', 'sys.stderr.flush()']; + const result = procService.execObservable(pythonPath, ['-c', pythonCode.join(';')]); + const outputs = [ + { out: '1', source: 'stdout' }, { out: 'a', source: 'stderr' }, + { out: '2', source: 'stdout' }, { out: 'b', source: 'stderr' }, + { out: '3', source: 'stdout' }, { out: 'c', source: 'stderr' }]; + + expect(result).not.to.be.an('undefined', 'result is undefined'); + result.out.subscribe(output => { + const value = output.out.trim(); + const expectedOutput = outputs.shift()!; + + expect(value).to.be.equal(expectedOutput.out, 'Expected output is incorrect'); + expect(output.source).to.be.equal(expectedOutput.source, 'Expected sopurce is incorrect'); + }, done, done); + }); + + test('execObservable should merge stdout and stderr streams', function (done) { + // tslint:disable-next-line:no-invalid-this + this.timeout(7000); + const procService = new ProcessService(new BufferDecoder()); + const pythonCode = ['import sys', 'import time', + 'print("1")', 'sys.stdout.flush()', 'time.sleep(1)', + 'sys.stderr.write("a")', 'sys.stderr.flush()', 'time.sleep(1)', + 'print("2")', 'sys.stdout.flush()', 'time.sleep(1)', + 'sys.stderr.write("b")', 'sys.stderr.flush()', 'time.sleep(1)', + 'print("3")', 'sys.stdout.flush()', 'time.sleep(1)', + 'sys.stderr.write("c")', 'sys.stderr.flush()']; + const result = procService.execObservable(pythonPath, ['-c', pythonCode.join(';')], { mergeStdOutErr: true }); + const outputs = [ + { out: '1', source: 'stdout' }, { out: 'a', source: 'stdout' }, + { out: '2', source: 'stdout' }, { out: 'b', source: 'stdout' }, + { out: '3', source: 'stdout' }, { out: 'c', source: 'stdout' }]; + + expect(result).not.to.be.an('undefined', 'result is undefined'); + result.out.subscribe(output => { + const value = output.out.trim(); + const expectedOutput = outputs.shift()!; + + expect(value).to.be.equal(expectedOutput.out, 'Expected output is incorrect'); + expect(output.source).to.be.equal(expectedOutput.source, 'Expected sopurce is incorrect'); + }, done, done); + }); + + test('execObservable should throw an error with stderr output', (done) => { + const procService = new ProcessService(new BufferDecoder()); + const pythonCode = ['import sys', 'sys.stderr.write("a")', 'sys.stderr.flush()']; + const result = procService.execObservable(pythonPath, ['-c', pythonCode.join(';')], { throwOnStdErr: true }); + + expect(result).not.to.be.an('undefined', 'result is undefined.'); + result.out.subscribe(output => { + done('Output received, when we\'re expecting an error to be thrown.'); + }, (ex: Error) => { + expect(ex).to.have.property('message', 'a', 'Invalid error thrown'); + done(); + }, () => { + done('Completed, when we\'re expecting an error to be thrown.'); + }); + }); + + test('execObservable should throw an error when spawn file not found', (done) => { + const procService = new ProcessService(new BufferDecoder()); + const result = procService.execObservable(Date.now().toString(), []); + + expect(result).not.to.be.an('undefined', 'result is undefined.'); + result.out.subscribe(output => { + done('Output received, when we\'re expecting an error to be thrown.'); + }, ex => { + expect(ex).to.have.property('code', 'ENOENT', 'Invalid error code'); + done(); + }, () => { + done('Completed, when we\'re expecting an error to be thrown.'); + }); + }); + + test('execObservable should exit without no output', (done) => { + const procService = new ProcessService(new BufferDecoder()); + const result = procService.execObservable(pythonPath, ['-c', 'import sys', 'sys.exit()']); + + expect(result).not.to.be.an('undefined', 'result is undefined.'); + result.out.subscribe(output => { + done(`Output received, when we\'re not expecting any, ${JSON.stringify(output)}`); + }, done, done); + }); +}); diff --git a/src/test/common/process/pythonProc.simple.multiroot.test.ts b/src/test/common/process/pythonProc.simple.multiroot.test.ts new file mode 100644 index 000000000000..c094732c0b94 --- /dev/null +++ b/src/test/common/process/pythonProc.simple.multiroot.test.ts @@ -0,0 +1,120 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { expect, use } from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import { execFile } from 'child_process'; +import { Container } from 'inversify'; +import { EOL } from 'os'; +import * as path from 'path'; +import { ConfigurationTarget, Disposable, Uri } from 'vscode'; +import { PythonSettings } from '../../../client/common/configSettings'; +import { registerTypes as processRegisterTypes } from '../../../client/common/process/serviceRegistry'; +import { IPythonExecutionFactory, StdErrError } from '../../../client/common/process/types'; +import { IDiposableRegistry, IsWindows } from '../../../client/common/types'; +import { IS_WINDOWS } from '../../../client/common/utils'; +import { registerTypes as variablesRegisterTypes } from '../../../client/common/variables/serviceRegistry'; +import { ServiceManager } from '../../../client/ioc/serviceManager'; +import { clearPythonPathInWorkspaceFolder, updateSetting } from '../../common'; +import { closeActiveWindows, initialize, initializeTest, IS_MULTI_ROOT_TEST } from './../../initialize'; + +use(chaiAsPromised); + +const multirootPath = path.join(__dirname, '..', '..', '..', '..', 'src', 'testMultiRootWkspc'); +const workspace4Path = Uri.file(path.join(multirootPath, 'workspace4')); +const workspace4PyFile = Uri.file(path.join(workspace4Path.fsPath, 'one.py')); + +// tslint:disable-next-line:max-func-body-length +suite('PythonExecutableService', () => { + let cont: Container; + let serviceManager: ServiceManager; + suiteSetup(async function () { + if (!IS_MULTI_ROOT_TEST) { + // tslint:disable-next-line:no-invalid-this + this.skip(); + } + await clearPythonPathInWorkspaceFolder(workspace4Path); + await updateSetting('envFile', undefined, workspace4PyFile, ConfigurationTarget.WorkspaceFolder); + await initialize(); + }); + setup(() => { + cont = new Container(); + serviceManager = new ServiceManager(cont); + serviceManager.addSingletonInstance(IDiposableRegistry, []); + serviceManager.addSingletonInstance(IsWindows, IS_WINDOWS); + processRegisterTypes(serviceManager); + variablesRegisterTypes(serviceManager); + return initializeTest(); + }); + suiteTeardown(closeActiveWindows); + teardown(async () => { + cont.unbindAll(); + cont.unload(); + await closeActiveWindows(); + await clearPythonPathInWorkspaceFolder(workspace4Path); + await updateSetting('envFile', undefined, workspace4PyFile, ConfigurationTarget.WorkspaceFolder); + await initializeTest(); + }); + + test('Importing without a valid PYTHONPATH should fail', async () => { + await updateSetting('envFile', 'someInvalidFile.env', workspace4PyFile, ConfigurationTarget.WorkspaceFolder); + const pythonExecFactory = serviceManager.get(IPythonExecutionFactory); + const pythonExecService = await pythonExecFactory.create(workspace4PyFile); + const promise = pythonExecService.exec([workspace4PyFile.fsPath], { cwd: path.dirname(workspace4PyFile.fsPath), throwOnStdErr: true }); + + await expect(promise).to.eventually.be.rejectedWith(StdErrError); + }); + + test('Importing with a valid PYTHONPATH from .env file should succeed', async () => { + await updateSetting('envFile', undefined, workspace4PyFile, ConfigurationTarget.WorkspaceFolder); + const pythonExecFactory = serviceManager.get(IPythonExecutionFactory); + const pythonExecService = await pythonExecFactory.create(workspace4PyFile); + const promise = pythonExecService.exec([workspace4PyFile.fsPath], { cwd: path.dirname(workspace4PyFile.fsPath), throwOnStdErr: true }); + + await expect(promise).to.eventually.have.property('stdout', `Hello${EOL}`); + }); + + test('Known modules such as \'os\' and \'sys\' should be deemed \'installed\'', async () => { + const pythonExecFactory = serviceManager.get(IPythonExecutionFactory); + const pythonExecService = await pythonExecFactory.create(workspace4PyFile); + const osModuleIsInstalled = pythonExecService.isModuleInstalled('os'); + const sysModuleIsInstalled = pythonExecService.isModuleInstalled('sys'); + await expect(osModuleIsInstalled).to.eventually.equal(true, 'os module is not installed'); + await expect(sysModuleIsInstalled).to.eventually.equal(true, 'sys module is not installed'); + }); + + test('Unknown modules such as \'xyzabc123\' be deemed \'not installed\'', async () => { + const pythonExecFactory = serviceManager.get(IPythonExecutionFactory); + const pythonExecService = await pythonExecFactory.create(workspace4PyFile); + const randomModuleName = `xyz123${new Date().getSeconds()}`; + const randomModuleIsInstalled = pythonExecService.isModuleInstalled(randomModuleName); + await expect(randomModuleIsInstalled).to.eventually.equal(false, `Random module '${randomModuleName}' is installed`); + }); + + test('Value for \'python --version\' should be returned as version information', async () => { + const pythonPath = PythonSettings.getInstance(workspace4Path).pythonPath; + const expectedVersion = await new Promise(resolve => { + execFile(pythonPath, ['--version'], (error, stdout, stdErr) => { + const out = (typeof stdErr === 'string' ? stdErr : '') + EOL + (typeof stdout === 'string' ? stdout : ''); + resolve(out.trim()); + }); + }); + const pythonExecFactory = serviceManager.get(IPythonExecutionFactory); + const pythonExecService = await pythonExecFactory.create(workspace4PyFile); + const version = await pythonExecService.getVersion(); + expect(version).to.equal(expectedVersion, 'Versions are not the same'); + }); + + test('Ensure correct path to executable is returned', async () => { + const pythonPath = PythonSettings.getInstance(workspace4Path).pythonPath; + const expectedExecutablePath = await new Promise(resolve => { + execFile(pythonPath, ['-c', 'import sys;print(sys.executable)'], (_error, stdout, _stdErr) => { + resolve(stdout.trim()); + }); + }); + const pythonExecFactory = serviceManager.get(IPythonExecutionFactory); + const pythonExecService = await pythonExecFactory.create(workspace4PyFile); + const executablePath = await pythonExecService.getExecutablePath(); + expect(executablePath).to.equal(expectedExecutablePath, 'Executable paths are not the same'); + }); +}); diff --git a/src/test/common/variables/envVarsProvider.multiroot.test.ts b/src/test/common/variables/envVarsProvider.multiroot.test.ts new file mode 100644 index 000000000000..1cd0a2045604 --- /dev/null +++ b/src/test/common/variables/envVarsProvider.multiroot.test.ts @@ -0,0 +1,174 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { expect, use } from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import * as fs from 'fs-extra'; +import { Container } from 'inversify'; +import { EOL } from 'os'; +import * as path from 'path'; +import { ConfigurationTarget, Disposable, Uri, workspace } from 'vscode'; +import { IS_WINDOWS } from '../../../client/common/configSettings'; +import { registerTypes as processRegisterTypes } from '../../../client/common/process/serviceRegistry'; +import { IDiposableRegistry } from '../../../client/common/types'; +import { IsWindows } from '../../../client/common/types'; +import { registerTypes as variablesRegisterTypes } from '../../../client/common/variables/serviceRegistry'; +import { IEnvironmentVariablesProvider } from '../../../client/common/variables/types'; +import { ServiceManager } from '../../../client/ioc/serviceManager'; +import { clearPythonPathInWorkspaceFolder, updateSetting } from '../../common'; +import { closeActiveWindows, initialize, initializeTest, IS_MULTI_ROOT_TEST } from '../../initialize'; + +use(chaiAsPromised); + +const multirootPath = path.join(__dirname, '..', '..', '..', '..', 'src', 'testMultiRootWkspc'); +const workspace4Path = Uri.file(path.join(multirootPath, 'workspace4')); +const workspace4PyFile = Uri.file(path.join(workspace4Path.fsPath, 'one.py')); + +// tslint:disable-next-line:max-func-body-length +suite('Multiroot Environment Variables Provider', () => { + let cont: Container; + let serviceManager: ServiceManager; + suiteSetup(async function () { + if (!IS_MULTI_ROOT_TEST) { + // tslint:disable-next-line:no-invalid-this + this.skip(); + } + await clearPythonPathInWorkspaceFolder(workspace4Path); + await updateSetting('envFile', undefined, workspace4PyFile, ConfigurationTarget.WorkspaceFolder); + await initialize(); + }); + setup(() => { + cont = new Container(); + serviceManager = new ServiceManager(cont); + serviceManager.addSingletonInstance(IDiposableRegistry, []); + serviceManager.addSingletonInstance(IsWindows, IS_WINDOWS); + processRegisterTypes(serviceManager); + variablesRegisterTypes(serviceManager); + return initializeTest(); + }); + suiteTeardown(closeActiveWindows); + teardown(async () => { + cont.unbindAll(); + cont.unload(); + await closeActiveWindows(); + await clearPythonPathInWorkspaceFolder(workspace4Path); + await updateSetting('envFile', undefined, workspace4PyFile, ConfigurationTarget.WorkspaceFolder); + await initializeTest(); + }); + + test('Custom variables should be undefined without an env file', async () => { + await updateSetting('envFile', 'someInvalidFile.env', workspace4PyFile, ConfigurationTarget.WorkspaceFolder); + const envProvider = serviceManager.get(IEnvironmentVariablesProvider); + const vars = envProvider.getEnvironmentVariables(false, workspace4PyFile); + await expect(vars).to.eventually.equal(undefined, 'Variables is not undefiend'); + }); + + test('Custom variables should be parsed from env file', async () => { + // tslint:disable-next-line:no-invalid-template-strings + await updateSetting('envFile', '${workspaceRoot}/.env', workspace4PyFile, ConfigurationTarget.WorkspaceFolder); + const envProvider = serviceManager.get(IEnvironmentVariablesProvider); + const vars = await envProvider.getEnvironmentVariables(false, workspace4PyFile); + + expect(vars).to.not.equal(undefined, 'Variables is is undefiend'); + expect(vars).to.to.have.property('X1234PYEXTUNITTESTVAR', '1234', 'X1234PYEXTUNITTESTVAR value is invalid'); + expect(vars).to.to.have.property('PYTHONPATH', '../workspace5', 'PYTHONPATH value is invalid'); + }); + + test('Custom variables should not be merged with process environment varaibles', async () => { + const randomEnvVariable = `UNIT_TEST_PYTHON_EXT_RANDOM_VARIABLE_${new Date().getSeconds()}`; + process.env[randomEnvVariable] = '1234'; + // tslint:disable-next-line:no-invalid-template-strings + await updateSetting('envFile', '${workspaceRoot}/.env', workspace4PyFile, ConfigurationTarget.WorkspaceFolder); + const envProvider = serviceManager.get(IEnvironmentVariablesProvider); + const vars = await envProvider.getEnvironmentVariables(false, workspace4PyFile); + + expect(vars).to.not.equal(undefined, 'Variables is is undefiend'); + expect(vars).to.to.have.property('X1234PYEXTUNITTESTVAR', '1234', 'X1234PYEXTUNITTESTVAR value is invalid'); + expect(vars).to.to.have.property('PYTHONPATH', '../workspace5', 'PYTHONPATH value is invalid'); + expect(vars).to.not.to.have.property(randomEnvVariable, undefined, 'Yikes process variable has leaked'); + }); + + test('Custom variables should be merged with process environment varaibles', async () => { + const randomEnvVariable = `UNIT_TEST_PYTHON_EXT_RANDOM_VARIABLE_${new Date().getSeconds()}`; + process.env[randomEnvVariable] = '1234'; + // tslint:disable-next-line:no-invalid-template-strings + await updateSetting('envFile', '${workspaceRoot}/.env', workspace4PyFile, ConfigurationTarget.WorkspaceFolder); + const envProvider = serviceManager.get(IEnvironmentVariablesProvider); + const vars = await envProvider.getEnvironmentVariables(true, workspace4PyFile); + + expect(vars).to.not.equal(undefined, 'Variables is is undefiend'); + expect(vars).to.to.have.property('X1234PYEXTUNITTESTVAR', '1234', 'X1234PYEXTUNITTESTVAR value is invalid'); + expect(vars).to.to.have.property('PYTHONPATH', '../workspace5', 'PYTHONPATH value is invalid'); + expect(vars).to.to.have.property(randomEnvVariable, '1234', 'Yikes process variable has leaked'); + }); + + test('Custom variables will be refreshed when settings points to a different env file', async () => { + // tslint:disable-next-line:no-invalid-template-strings + await updateSetting('envFile', '${workspaceRoot}/.env', workspace4PyFile, ConfigurationTarget.WorkspaceFolder); + const envProvider = serviceManager.get(IEnvironmentVariablesProvider); + const vars = await envProvider.getEnvironmentVariables(false, workspace4PyFile); + expect(vars).to.not.equal(undefined, 'Variables is is undefiend'); + expect(vars).to.to.have.property('X1234PYEXTUNITTESTVAR', '1234', 'X1234PYEXTUNITTESTVAR value is invalid'); + expect(vars).to.to.have.property('PYTHONPATH', '../workspace5', 'PYTHONPATH value is invalid'); + + const settings = workspace.getConfiguration('python', workspace4PyFile); + // tslint:disable-next-line:no-invalid-template-strings + await settings.update('envFile', '${workspaceRoot}/.env2', ConfigurationTarget.WorkspaceFolder); + + // Wait for settings to get refreshed. + await new Promise(resolve => setTimeout(resolve, 5000)); + + const newVars = await envProvider.getEnvironmentVariables(false, workspace4PyFile); + expect(newVars).to.not.equal(undefined, 'Variables is is undefiend'); + expect(newVars).to.have.property('X12345PYEXTUNITTESTVAR', '12345', 'X12345PYEXTUNITTESTVAR value is invalid'); + expect(newVars).to.not.to.have.property('PYTHONPATH', '../workspace5', 'PYTHONPATH value is invalid'); + }); + + test('Custom variables will be refreshed when .env file is created, modified and deleted', async function () { + // tslint:disable-next-line:no-invalid-this + this.timeout(20000); + const env3 = path.join(workspace4Path.fsPath, '.env3'); + const fileExists = await fs.pathExists(env3); + if (fileExists) { + await fs.remove(env3); + } + // tslint:disable-next-line:no-invalid-template-strings + await updateSetting('envFile', '${workspaceRoot}/.env3', workspace4PyFile, ConfigurationTarget.WorkspaceFolder); + const envProvider = serviceManager.get(IEnvironmentVariablesProvider); + const vars = envProvider.getEnvironmentVariables(false, workspace4PyFile); + await expect(vars).to.eventually.equal(undefined, 'Variables is is undefiend'); + + // Create env3. + const contents = fs.readFileSync(path.join(workspace4Path.fsPath, '.env2')); + fs.writeFileSync(env3, contents); + + // Wait for settings to get refreshed. + await new Promise(resolve => setTimeout(resolve, 5000)); + + const newVars = await envProvider.getEnvironmentVariables(false, workspace4PyFile); + expect(newVars).to.not.equal(undefined, 'Variables is is undefiend after creating'); + expect(newVars).to.to.have.property('X12345PYEXTUNITTESTVAR', '12345', 'X12345PYEXTUNITTESTVAR value is invalid after creating'); + expect(newVars).to.not.to.have.property('PYTHONPATH', '../workspace5', 'PYTHONPATH value is invalid after creating'); + + // Modify env3. + fs.writeFileSync(env3, `${contents}${EOL}X123456PYEXTUNITTESTVAR=123456`); + + // Wait for settings to get refreshed. + await new Promise(resolve => setTimeout(resolve, 5000)); + + const updatedVars = await envProvider.getEnvironmentVariables(false, workspace4PyFile); + expect(updatedVars).to.not.equal(undefined, 'Variables is is undefiend after modifying'); + expect(updatedVars).to.to.have.property('X12345PYEXTUNITTESTVAR', '12345', 'X12345PYEXTUNITTESTVAR value is invalid after modifying'); + expect(updatedVars).to.not.to.have.property('PYTHONPATH', '../workspace5', 'PYTHONPATH value is invalid after modifying'); + expect(updatedVars).to.to.have.property('X123456PYEXTUNITTESTVAR', '123456', 'X123456PYEXTUNITTESTVAR value is invalid after modifying'); + + // Now remove env3. + await fs.remove(env3); + + // Wait for settings to get refreshed. + await new Promise(resolve => setTimeout(resolve, 5000)); + + const varsAfterDeleting = await envProvider.getEnvironmentVariables(false, workspace4PyFile); + expect(varsAfterDeleting).to.equal(undefined, 'Variables is not undefiend after deleting'); + }); +}); diff --git a/src/test/format/extension.format.test.ts b/src/test/format/extension.format.test.ts index b7c650b2e5dd..2c0d5e07456b 100644 --- a/src/test/format/extension.format.test.ts +++ b/src/test/format/extension.format.test.ts @@ -3,25 +3,30 @@ import * as fs from 'fs-extra'; import * as path from 'path'; import * as vscode from 'vscode'; import { CancellationTokenSource } from 'vscode'; +import { IProcessService } from '../../client/common/process/types'; import { execPythonFile } from '../../client/common/utils'; import { AutoPep8Formatter } from '../../client/formatters/autoPep8Formatter'; import { YapfFormatter } from '../../client/formatters/yapfFormatter'; import { closeActiveWindows, initialize, initializeTest } from '../initialize'; +import { MockProcessService } from '../mocks/proc'; +import { UnitTestIocContainer } from '../unittests/serviceRegistry'; const ch = vscode.window.createOutputChannel('Tests'); -const pythoFilesPath = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'formatting'); +const formatFilesPath = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'formatting'); const workspaceRootPath = path.join(__dirname, '..', '..', '..', 'src', 'test'); -const originalUnformattedFile = path.join(pythoFilesPath, 'fileToFormat.py'); +const originalUnformattedFile = path.join(formatFilesPath, 'fileToFormat.py'); -const autoPep8FileToFormat = path.join(pythoFilesPath, 'autoPep8FileToFormat.py'); -const autoPep8FileToAutoFormat = path.join(pythoFilesPath, 'autoPep8FileToAutoFormat.py'); -const yapfFileToFormat = path.join(pythoFilesPath, 'yapfFileToFormat.py'); -const yapfFileToAutoFormat = path.join(pythoFilesPath, 'yapfFileToAutoFormat.py'); +const autoPep8FileToFormat = path.join(formatFilesPath, 'autoPep8FileToFormat.py'); +const autoPep8FileToAutoFormat = path.join(formatFilesPath, 'autoPep8FileToAutoFormat.py'); +const yapfFileToFormat = path.join(formatFilesPath, 'yapfFileToFormat.py'); +const yapfFileToAutoFormat = path.join(formatFilesPath, 'yapfFileToAutoFormat.py'); let formattedYapf = ''; let formattedAutoPep8 = ''; suite('Formatting', () => { + let ioc: UnitTestIocContainer; + suiteSetup(async () => { await initialize(); [autoPep8FileToFormat, autoPep8FileToAutoFormat, yapfFileToFormat, yapfFileToAutoFormat].forEach(file => { @@ -35,7 +40,10 @@ suite('Formatting', () => { formattedAutoPep8 = formattedResults[1]; }); }); - setup(initializeTest); + setup(async () => { + await initializeTest(); + initializeDI(); + }); suiteTeardown(async () => { [autoPep8FileToFormat, autoPep8FileToAutoFormat, yapfFileToFormat, yapfFileToAutoFormat].forEach(file => { if (fs.existsSync(file)) { @@ -44,19 +52,47 @@ suite('Formatting', () => { }); await closeActiveWindows(); }); - teardown(closeActiveWindows); + teardown(async () => { + ioc.dispose(); + await closeActiveWindows(); + }); + + function initializeDI() { + ioc = new UnitTestIocContainer(); + ioc.registerCommonTypes(); + ioc.registerVariableTypes(); + ioc.registerUnitTestTypes(); + + // Mocks. + ioc.registerMockProcessTypes(); + } - async function testFormatting(formatter: AutoPep8Formatter | YapfFormatter, formattedContents: string, fileToFormat: string) { + function injectFormatOutput(outputFileName: string) { + const procService = ioc.serviceContainer.get(IProcessService); + procService.onExecObservable((file, args, options, callback) => { + if (args.indexOf('--diff') >= 0) { + callback({ + out: fs.readFileSync(path.join(formatFilesPath, outputFileName), 'utf8'), + source: 'stdout' + }); + } + }); + } + + async function testFormatting(formatter: AutoPep8Formatter | YapfFormatter, formattedContents: string, fileToFormat: string, outputFileName: string) { const textDocument = await vscode.workspace.openTextDocument(fileToFormat); const textEditor = await vscode.window.showTextDocument(textDocument); const options = { insertSpaces: textEditor.options.insertSpaces! as boolean, tabSize: textEditor.options.tabSize! as number }; + + injectFormatOutput(outputFileName); + const edits = await formatter.formatDocument(textDocument, options, new CancellationTokenSource().token); await textEditor.edit(editBuilder => { edits.forEach(edit => editBuilder.replace(edit.range, edit.newText)); }); assert.equal(textEditor.document.getText(), formattedContents, 'Formatted text is not the same'); } - test('AutoPep8', () => testFormatting(new AutoPep8Formatter(ch), formattedAutoPep8, autoPep8FileToFormat)); + test('AutoPep8', () => testFormatting(new AutoPep8Formatter(ch), formattedAutoPep8, autoPep8FileToFormat, 'autopep8.output')); - test('Yapf', () => testFormatting(new YapfFormatter(ch), formattedYapf, yapfFileToFormat)); + test('Yapf', () => testFormatting(new YapfFormatter(ch), formattedYapf, yapfFileToFormat, 'yapf.output')); }); diff --git a/src/test/index.ts b/src/test/index.ts index 0202b4e2dc43..4d3b12a351ca 100644 --- a/src/test/index.ts +++ b/src/test/index.ts @@ -1,13 +1,18 @@ import * as testRunner from 'vscode/lib/testrunner'; -import { initializePython, IS_MULTI_ROOT_TEST } from './initialize'; +import { MochaSetupOptions } from 'vscode/lib/testrunner'; +import { IS_MULTI_ROOT_TEST } from './initialize'; process.env.VSC_PYTHON_CI_TEST = '1'; +process.env.IS_MULTI_ROOT_TEST = IS_MULTI_ROOT_TEST; // You can directly control Mocha options by uncommenting the following lines. // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info. -testRunner.configure({ +// Hack, as retries is not supported as setting in tsd. +// tslint:disable-next-line:no-any +const options: MochaSetupOptions & { retries: number } = { ui: 'tdd', useColors: true, timeout: 25000, retries: 3 -} as {}); +}; +testRunner.configure(options); module.exports = testRunner; diff --git a/src/test/initialize.ts b/src/test/initialize.ts index 67193c2da0bd..1c0518399614 100644 --- a/src/test/initialize.ts +++ b/src/test/initialize.ts @@ -60,6 +60,7 @@ export async function closeActiveWindows(): Promise { return resolve(); } + // tslint:disable-next-line:no-suspicious-comment // TODO: the visibleTextEditors variable doesn't seem to be // up to date after a onDidChangeActiveTextEditor event, not // even using a setTimeout 0... so we MUST poll :( diff --git a/src/test/linters/lint.test.ts b/src/test/linters/lint.test.ts index 80bbf8be4578..035884948aa1 100644 --- a/src/test/linters/lint.test.ts +++ b/src/test/linters/lint.test.ts @@ -239,15 +239,16 @@ suite('Linting', () => { const linter = new pydocstyle.Linter(ch); await testLinterMessages(linter, ch, fileToLint, pydocstyleMessagseToBeReturned); }); - // tslint:disable-next-line:no-floating-promises - isPython3.then(value => { - const messagesToBeReturned = value ? filteredPylint3MessagesToBeReturned : filteredPylintMessagesToBeReturned; - test('PyLint with config in root', async () => { - const ch = new MockOutputChannel('Lint'); - const linter = new pyLint.Linter(ch); - await testLinterMessages(linter, ch, path.join(pylintConfigPath, 'file.py'), messagesToBeReturned); - }); - }); + isPython3 + .then(value => { + const messagesToBeReturned = value ? filteredPylint3MessagesToBeReturned : filteredPylintMessagesToBeReturned; + test('PyLint with config in root', async () => { + const ch = new MockOutputChannel('Lint'); + const linter = new pyLint.Linter(ch); + await testLinterMessages(linter, ch, path.join(pylintConfigPath, 'file.py'), messagesToBeReturned); + }); + }) + .catch(ex => console.error('Python Extension Tests: isPython3', ex)); test('Flake8 with config in root', async () => { const ch = new MockOutputChannel('Lint'); const linter = new flake8.Linter(ch); @@ -258,13 +259,14 @@ suite('Linting', () => { const linter = new pep8.Linter(ch); await testLinterMessages(linter, ch, path.join(pep8ConfigPath, 'file.py'), filteredPep88MessagesToBeReturned); }); - // tslint:disable-next-line:no-floating-promises - isPython3.then(value => { - const messagesToBeReturned = value ? [] : fiteredPydocstyleMessagseToBeReturned; - test('Pydocstyle with config in root', async () => { - const ch = new MockOutputChannel('Lint'); - const linter = new pydocstyle.Linter(ch); - await testLinterMessages(linter, ch, path.join(pydocstyleConfigPath27, 'file.py'), messagesToBeReturned); - }); - }); + isPython3 + .then(value => { + const messagesToBeReturned = value ? [] : fiteredPydocstyleMessagseToBeReturned; + test('Pydocstyle with config in root', async () => { + const ch = new MockOutputChannel('Lint'); + const linter = new pydocstyle.Linter(ch); + await testLinterMessages(linter, ch, path.join(pydocstyleConfigPath27, 'file.py'), messagesToBeReturned); + }); + }) + .catch(ex => console.error('Python Extension Tests: isPython3', ex)); }); diff --git a/src/test/mockClasses.ts b/src/test/mockClasses.ts index d2fc17c44043..3cbae4ddfc55 100644 --- a/src/test/mockClasses.ts +++ b/src/test/mockClasses.ts @@ -1,27 +1,30 @@ import * as vscode from 'vscode'; export class MockOutputChannel implements vscode.OutputChannel { + public name: string; + public output: string; + public isShown: boolean; constructor(name: string) { this.name = name; this.output = ''; } - name: string; - output: string; - isShown: boolean; - append(value: string) { + public append(value: string) { this.output += value; } - appendLine(value: string) { this.append(value); this.append('\n'); } - clear() { } - show(preservceFocus?: boolean): void; - show(column?: vscode.ViewColumn, preserveFocus?: boolean): void; - show(x?: any, y?: any): void { + public appendLine(value: string) { this.append(value); this.append('\n'); } + // tslint:disable-next-line:no-empty + public clear() { } + public show(preservceFocus?: boolean): void; + public show(column?: vscode.ViewColumn, preserveFocus?: boolean): void; + // tslint:disable-next-line:no-any + public show(x?: any, y?: any): void { this.isShown = true; } - hide() { + public hide() { this.isShown = false; } - dispose() { } + // tslint:disable-next-line:no-empty + public dispose() { } } export class MockStatusBarItem implements vscode.StatusBarItem { @@ -31,13 +34,13 @@ export class MockStatusBarItem implements vscode.StatusBarItem { public tooltip: string; public color: string; public command: string; - show(): void { - + // tslint:disable-next-line:no-empty + public show(): void { } - hide(): void { - + // tslint:disable-next-line:no-empty + public hide(): void { } - dispose(): void { - + // tslint:disable-next-line:no-empty + public dispose(): void { } -} \ No newline at end of file +} diff --git a/src/test/mocks/mementos.ts b/src/test/mocks/mementos.ts new file mode 100644 index 000000000000..cc77f8944ed0 --- /dev/null +++ b/src/test/mocks/mementos.ts @@ -0,0 +1,17 @@ +import { Memento } from 'vscode'; + +export class MockMemento implements Memento { + private map: Map = new Map(); + // tslint:disable-next-line:no-any + public get(key: any, defaultValue?: any); + public get(key: string, defaultValue?: T): T { + const exists = this.map.has(key); + // tslint:disable-next-line:no-any + return exists ? this.map.get(key) : defaultValue! as any; + } + // tslint:disable-next-line:no-any + public update(key: string, value: any): Thenable { + this.map.set(key, value); + return Promise.resolve(); + } +} diff --git a/src/test/mocks/proc.ts b/src/test/mocks/proc.ts new file mode 100644 index 000000000000..ce6489556151 --- /dev/null +++ b/src/test/mocks/proc.ts @@ -0,0 +1,57 @@ +import { spawn } from 'child_process'; +import { EventEmitter } from 'events'; +import { decorate, inject, injectable } from 'inversify'; +import 'reflect-metadata'; +import * as Rx from 'rxjs'; +import { Disposable } from 'vscode'; +import { ExecutionResult, IBufferDecoder, IProcessService, ObservableExecutionResult, Output, SpawnOptions } from '../../client/common/process/types'; + +type ExecObservableCallback = (result: Rx.Observable> | Output) => void; +type ExecCallback = (result: ExecutionResult) => void; + +export const IOriginalProcessService = Symbol('IProcessService'); + +@injectable() +export class MockProcessService extends EventEmitter implements IProcessService { + private observableResults: (Rx.Observable> | Output)[] = []; + constructor( @inject(IOriginalProcessService) private procService: IProcessService) { + super(); + } + public onExecObservable(handler: (file: string, args: string[], options: SpawnOptions, callback: ExecObservableCallback) => void) { + this.on('execObservable', handler); + } + public execObservable(file: string, args: string[], options: SpawnOptions = {}): ObservableExecutionResult { + let value: Rx.Observable> | Output | undefined; + let valueReturned = false; + this.emit('execObservable', file, args, options, (result: Rx.Observable> | Output) => { value = result; valueReturned = true; }); + + if (valueReturned) { + const output = value as Output; + if (['stderr', 'stdout'].some(source => source === output.source)) { + return { + // tslint:disable-next-line:no-any + proc: {} as any, + out: Rx.Observable.of(output) + }; + } else { + return { + // tslint:disable-next-line:no-any + proc: {} as any, + out: value as Rx.Observable> + }; + } + } else { + return this.procService.execObservable(file, args, options); + } + } + public onExec(handler: (file: string, args: string[], options: SpawnOptions, callback: ExecCallback) => void) { + this.on('exec', handler); + } + public async exec(file: string, args: string[], options: SpawnOptions = {}): Promise> { + let value: ExecutionResult | undefined; + let valueReturned = false; + this.emit('exec', file, args, options, (result: ExecutionResult) => { value = result; valueReturned = true; }); + + return valueReturned ? value : this.procService.exec(file, args, options); + } +} diff --git a/src/test/multiRootTest.ts b/src/test/multiRootTest.ts index 57bf5368ccb7..75d40bce3e1e 100644 --- a/src/test/multiRootTest.ts +++ b/src/test/multiRootTest.ts @@ -3,6 +3,7 @@ import * as path from 'path'; process.env.CODE_TESTS_WORKSPACE = path.join(__dirname, '..', '..', 'src', 'testMultiRootWkspc', 'multi.code-workspace'); function start() { + // tslint:disable-next-line:no-console console.log('start Multiroot tests'); require('../../node_modules/vscode/bin/test'); } diff --git a/src/test/pythonFiles/formatting/autopep8.output b/src/test/pythonFiles/formatting/autopep8.output new file mode 100644 index 000000000000..9050345d0575 --- /dev/null +++ b/src/test/pythonFiles/formatting/autopep8.output @@ -0,0 +1,49 @@ +--- original//Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/formatting/autoPep8FileToFormat.py ++++ fixed//Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/formatting/autoPep8FileToFormat.py +@@ -1,21 +1,31 @@ +-import math, sys; ++import math ++import sys ++ + + def example1(): +- ####This is a long comment. This should be wrapped to fit within 72 characters. +- some_tuple=( 1,2, 3,'a' ); +- some_variable={'long':'Long code lines should be wrapped within 79 characters.', +- 'other':[math.pi, 100,200,300,9876543210,'This is a long string that goes on'], +- 'more':{'inner':'This whole logical line should be wrapped.',some_tuple:[1, +- 20,300,40000,500000000,60000000000000000]}} ++ # This is a long comment. This should be wrapped to fit within 72 characters. ++ some_tuple = (1, 2, 3, 'a') ++ some_variable = {'long': 'Long code lines should be wrapped within 79 characters.', ++ 'other': [math.pi, 100, 200, 300, 9876543210, 'This is a long string that goes on'], ++ 'more': {'inner': 'This whole logical line should be wrapped.', some_tuple: [1, ++ 20, 300, 40000, 500000000, 60000000000000000]}} + return (some_tuple, some_variable) +-def example2(): return {'has_key() is deprecated':True}.has_key({'f':2}.has_key('')); +-class Example3( object ): +- def __init__ ( self, bar ): +- #Comments should have a space after the hash. +- if bar : bar+=1; bar=bar* bar ; return bar +- else: +- some_string = """ ++ ++ ++def example2(): return {'has_key() is deprecated': True}.has_key( ++ {'f': 2}.has_key('')); ++ ++ ++class Example3(object): ++ def __init__(self, bar): ++ # Comments should have a space after the hash. ++ if bar: ++ bar += 1 ++ bar = bar * bar ++ return bar ++ else: ++ some_string = """ + Indentation in multiline strings should not be touched. + Only actual code should be reindented. + """ +- return (sys.path, some_string) ++ return (sys.path, some_string) diff --git a/src/test/pythonFiles/formatting/yapf.output b/src/test/pythonFiles/formatting/yapf.output new file mode 100644 index 000000000000..0e2ce688a3d6 --- /dev/null +++ b/src/test/pythonFiles/formatting/yapf.output @@ -0,0 +1,59 @@ +--- /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/formatting/yapfFileToFormat.py (original) ++++ /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/formatting/yapfFileToFormat.py (reformatted) +@@ -1,21 +1,42 @@ +-import math, sys; ++import math, sys ++ + + def example1(): + ####This is a long comment. This should be wrapped to fit within 72 characters. +- some_tuple=( 1,2, 3,'a' ); +- some_variable={'long':'Long code lines should be wrapped within 79 characters.', +- 'other':[math.pi, 100,200,300,9876543210,'This is a long string that goes on'], +- 'more':{'inner':'This whole logical line should be wrapped.',some_tuple:[1, +- 20,300,40000,500000000,60000000000000000]}} ++ some_tuple = (1, 2, 3, 'a') ++ some_variable = { ++ 'long': ++ 'Long code lines should be wrapped within 79 characters.', ++ 'other': [ ++ math.pi, 100, 200, 300, 9876543210, ++ 'This is a long string that goes on' ++ ], ++ 'more': { ++ 'inner': 'This whole logical line should be wrapped.', ++ some_tuple: [1, 20, 300, 40000, 500000000, 60000000000000000] ++ } ++ } + return (some_tuple, some_variable) +-def example2(): return {'has_key() is deprecated':True}.has_key({'f':2}.has_key('')); +-class Example3( object ): +- def __init__ ( self, bar ): +- #Comments should have a space after the hash. +- if bar : bar+=1; bar=bar* bar ; return bar +- else: +- some_string = """ ++ ++ ++def example2(): ++ return { ++ 'has_key() is deprecated': True ++ }.has_key({ ++ 'f': 2 ++ }.has_key('')) ++ ++ ++class Example3(object): ++ def __init__(self, bar): ++ #Comments should have a space after the hash. ++ if bar: ++ bar += 1 ++ bar = bar * bar ++ return bar ++ else: ++ some_string = """ + Indentation in multiline strings should not be touched. + Only actual code should be reindented. + """ +- return (sys.path, some_string) ++ return (sys.path, some_string) diff --git a/src/test/pythonFiles/testFiles/noseFiles/five.output b/src/test/pythonFiles/testFiles/noseFiles/five.output new file mode 100644 index 000000000000..8b0d557303f7 --- /dev/null +++ b/src/test/pythonFiles/testFiles/noseFiles/five.output @@ -0,0 +1,121 @@ +nose.config: INFO: Ignoring files matching ['^\\.', '^_', '^setup\\.py$'] +nose.plugins.manager: DEBUG: Configuring plugins +nose.plugins.manager: DEBUG: Plugins enabled: [, , , , ] +nose.core: DEBUG: configured Config(addPaths=True, args=(), configSection='nosetests', debug=None, debugLog=None, env={}, exclude=None, files=[], firstPackageWins=False, getTestCaseNamesCompat=False, ignoreFiles=[re.compile('^\\.'), re.compile('^_'), re.compile('^setup\\.py$')], ignoreFilesDefaultStrings=['^\\.', '^_', '^setup\\.py$'], include=None, includeExe=False, logStream=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, loggingConfig=None, options=, parser=, parserClass=, plugins=, py3where=(), runOnInit=True, srcDirs=('lib', 'src'), stopOnError=False, stream=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, testMatch=re.compile('test_'), testMatchPat='(?:^|[\\b_\\./-])[Tt]est', testNames=[], traverseNamespace=False, verbosity=4, where=(), worker=False, workingDir='/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles') +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: insert /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles into sys.path +nose.plugins.collect: DEBUG: Preparing test loader +nose.core: DEBUG: test loader is +nose.core: DEBUG: defaultTest . +nose.core: DEBUG: Test names are ['.'] +nose.core: DEBUG: createTests called with None +nose.loader: DEBUG: load from . (None) +nose.selector: DEBUG: Test name . resolved to file ., module None, call None +nose.selector: DEBUG: Final resolution of test name .: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles module None call None +nose.plugins.collect: DEBUG: TestSuite([]) +nose.plugins.collect: DEBUG: Add test +nose.core: DEBUG: runTests called +nose.suite: DEBUG: precache is [] +nose.loader: DEBUG: load from dir /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/four.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/one.output? False +nose.selector: DEBUG: wantDirectory /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific? False +nose.selector: DEBUG: wantDirectory /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/three.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/two.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py module test_root call None +nose.importer: DEBUG: Import test_root from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: find module part test_root (test_root) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_Root_A (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: Add test test_Root_B (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: Add test test_Root_c (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]> +nose.plugins.collect: DEBUG: Preparing test case test_Root_A (test_root.Test_Root_test1) +test_Root_A (test_root.Test_Root_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_Root_B (test_root.Test_Root_test1) +test_Root_B (test_root.Test_Root_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_Root_c (test_root.Test_Root_test1) +test_Root_c (test_root.Test_Root_test1) ... ok +nose.suite: DEBUG: precache is [] + +---------------------------------------------------------------------- +Ran 3 tests in 0.022s + +OK diff --git a/src/test/pythonFiles/testFiles/noseFiles/four.output b/src/test/pythonFiles/testFiles/noseFiles/four.output new file mode 100644 index 000000000000..511f0b1c863c --- /dev/null +++ b/src/test/pythonFiles/testFiles/noseFiles/four.output @@ -0,0 +1,205 @@ +nose.config: INFO: Set working dir to /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific +nose.config: INFO: Ignoring files matching ['^\\.', '^_', '^setup\\.py$'] +nose.plugins.manager: DEBUG: Configuring plugins +nose.plugins.manager: DEBUG: Plugins enabled: [, , , , ] +nose.core: DEBUG: configured Config(addPaths=True, args=(), configSection='nosetests', debug=None, debugLog=None, env={}, exclude=None, files=[], firstPackageWins=False, getTestCaseNamesCompat=False, ignoreFiles=[re.compile('^\\.'), re.compile('^_'), re.compile('^setup\\.py$')], ignoreFilesDefaultStrings=['^\\.', '^_', '^setup\\.py$'], include=None, includeExe=False, logStream=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, loggingConfig=None, options=, parser=, parserClass=, plugins=, py3where=(), runOnInit=True, srcDirs=('lib', 'src'), stopOnError=False, stream=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, testMatch=re.compile('tst'), testMatchPat='(?:^|[\\b_\\./-])[Tt]est', testNames=[], traverseNamespace=False, verbosity=4, where=(), worker=False, workingDir='/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific') +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific +nose.importer: DEBUG: insert /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific into sys.path +nose.plugins.collect: DEBUG: Preparing test loader +nose.core: DEBUG: test loader is +nose.core: DEBUG: defaultTest . +nose.core: DEBUG: Test names are ['.'] +nose.core: DEBUG: createTests called with None +nose.loader: DEBUG: load from . (None) +nose.selector: DEBUG: Test name . resolved to file ., module None, call None +nose.selector: DEBUG: Final resolution of test name .: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific module None call None +nose.plugins.collect: DEBUG: TestSuite([]) +nose.plugins.collect: DEBUG: Add test +nose.core: DEBUG: runTests called +nose.suite: DEBUG: precache is [] +nose.loader: DEBUG: load from dir /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific/tst_unittest_one.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific/tst_unittest_one.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific/tst_unittest_one.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific/tst_unittest_one.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific/tst_unittest_one.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific/tst_unittest_one.py module tst_unittest_one call None +nose.importer: DEBUG: Import tst_unittest_one from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific +nose.importer: DEBUG: find module part tst_unittest_one (tst_unittest_one) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test tst_A (tst_unittest_one.Test_test1) +nose.plugins.collect: DEBUG: Add test tst_B (tst_unittest_one.Test_test1) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test()]> +nose.plugins.collect: DEBUG: Preparing test case tst_A (tst_unittest_one.Test_test1) +tst_A (tst_unittest_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case tst_B (tst_unittest_one.Test_test1) +tst_B (tst_unittest_one.Test_test1) ... ok +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific/tst_unittest_two.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific/tst_unittest_two.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific/tst_unittest_two.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific/tst_unittest_two.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific/tst_unittest_two.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific/tst_unittest_two.py module tst_unittest_two call None +nose.importer: DEBUG: Import tst_unittest_two from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific +nose.importer: DEBUG: find module part tst_unittest_two (tst_unittest_two) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test tst_A2 (tst_unittest_two.Tst_test2) +nose.plugins.collect: DEBUG: Add test tst_B2 (tst_unittest_two.Tst_test2) +nose.plugins.collect: DEBUG: Add test tst_C2 (tst_unittest_two.Tst_test2) +nose.plugins.collect: DEBUG: Add test tst_D2 (tst_unittest_two.Tst_test2) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test(), Test()]> +nose.plugins.collect: DEBUG: Preparing test case tst_A2 (tst_unittest_two.Tst_test2) +tst_A2 (tst_unittest_two.Tst_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case tst_B2 (tst_unittest_two.Tst_test2) +tst_B2 (tst_unittest_two.Tst_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case tst_C2 (tst_unittest_two.Tst_test2) +tst_C2 (tst_unittest_two.Tst_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case tst_D2 (tst_unittest_two.Tst_test2) +tst_D2 (tst_unittest_two.Tst_test2) ... ok +nose.suite: DEBUG: precache is [] + +---------------------------------------------------------------------- +Ran 6 tests in 0.033s + +OK diff --git a/src/test/pythonFiles/testFiles/noseFiles/one.output b/src/test/pythonFiles/testFiles/noseFiles/one.output new file mode 100644 index 000000000000..cafdaf5b906a --- /dev/null +++ b/src/test/pythonFiles/testFiles/noseFiles/one.output @@ -0,0 +1,211 @@ +nose.config: INFO: Ignoring files matching ['^\\.', '^_', '^setup\\.py$'] +nose.plugins.manager: DEBUG: Configuring plugins +nose.plugins.manager: DEBUG: Plugins enabled: [, , , , ] +nose.core: DEBUG: configured Config(addPaths=True, args=(), configSection='nosetests', debug=None, debugLog=None, env={}, exclude=None, files=[], firstPackageWins=False, getTestCaseNamesCompat=False, ignoreFiles=[re.compile('^\\.'), re.compile('^_'), re.compile('^setup\\.py$')], ignoreFilesDefaultStrings=['^\\.', '^_', '^setup\\.py$'], include=None, includeExe=False, logStream=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, loggingConfig=None, options=, parser=, parserClass=, plugins=, py3where=(), runOnInit=True, srcDirs=('lib', 'src'), stopOnError=False, stream=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, testMatch=re.compile('(?:^|[\\b_\\./-])[Tt]est'), testMatchPat='(?:^|[\\b_\\./-])[Tt]est', testNames=[], traverseNamespace=False, verbosity=4, where=(), worker=False, workingDir='/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single') +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single +nose.importer: DEBUG: insert /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single into sys.path +nose.plugins.collect: DEBUG: Preparing test loader +nose.core: DEBUG: test loader is +nose.core: DEBUG: defaultTest . +nose.core: DEBUG: Test names are ['.'] +nose.core: DEBUG: createTests called with None +nose.loader: DEBUG: load from . (None) +nose.selector: DEBUG: Test name . resolved to file ., module None, call None +nose.selector: DEBUG: Final resolution of test name .: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single module None call None +nose.plugins.collect: DEBUG: TestSuite([]) +nose.plugins.collect: DEBUG: Add test +nose.core: DEBUG: runTests called +nose.suite: DEBUG: precache is [] +nose.loader: DEBUG: load from dir /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/test_root.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/test_root.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/test_root.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/test_root.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/test_root.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/test_root.py module test_root call None +nose.importer: DEBUG: Import test_root from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single +nose.importer: DEBUG: find module part test_root (test_root) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_Root_A (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: Add test test_Root_B (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: Add test test_Root_c (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]> +nose.plugins.collect: DEBUG: Preparing test case test_Root_A (test_root.Test_Root_test1) +test_Root_A (test_root.Test_Root_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_Root_B (test_root.Test_Root_test1) +test_Root_B (test_root.Test_Root_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_Root_c (test_root.Test_Root_test1) +test_Root_c (test_root.Test_Root_test1) ... ok +nose.selector: DEBUG: wantDirectory /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests? True +nose.plugins.collect: DEBUG: TestSuite() +nose.loader: DEBUG: load from dir /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests +nose.importer: DEBUG: insert /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests into sys.path +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests/test_one.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests/test_one.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests/test_one.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests/test_one.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests/test_one.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests/test_one.py module test_one call None +nose.importer: DEBUG: Import test_one from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests +nose.importer: DEBUG: find module part test_one (test_one) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_A (test_one.Test_test1) +nose.plugins.collect: DEBUG: Add test test_B (test_one.Test_test1) +nose.plugins.collect: DEBUG: Add test test_c (test_one.Test_test1) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]>]> +nose.importer: DEBUG: Remove path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests +nose.plugins.collect: DEBUG: Preparing test case test_A (test_one.Test_test1) +test_A (test_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_B (test_one.Test_test1) +test_B (test_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_c (test_one.Test_test1) +test_c (test_one.Test_test1) ... ok +nose.suite: DEBUG: precache is [] + +---------------------------------------------------------------------- +Ran 6 tests in 0.023s + +OK diff --git a/src/test/pythonFiles/testFiles/noseFiles/run.five.output b/src/test/pythonFiles/testFiles/noseFiles/run.five.output new file mode 100644 index 000000000000..640132ffe72e --- /dev/null +++ b/src/test/pythonFiles/testFiles/noseFiles/run.five.output @@ -0,0 +1,567 @@ +nose.config: INFO: Ignoring files matching ['^\\.', '^_', '^setup\\.py$'] +nose.plugins.manager: DEBUG: Configuring plugins +nose.plugins.manager: DEBUG: Plugins enabled: [, , , , ] +nose.core: DEBUG: configured Config(addPaths=True, args=(), configSection='nosetests', debug=None, debugLog=None, env={}, exclude=None, files=[], firstPackageWins=False, getTestCaseNamesCompat=False, ignoreFiles=[re.compile('^\\.'), re.compile('^_'), re.compile('^setup\\.py$')], ignoreFilesDefaultStrings=['^\\.', '^_', '^setup\\.py$'], include=None, includeExe=False, logStream=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, loggingConfig=None, options=, parser=, parserClass=, plugins=, py3where=(), runOnInit=True, srcDirs=('lib', 'src'), stopOnError=False, stream=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, testMatch=re.compile('test'), testMatchPat='(?:^|[\\b_\\./-])[Tt]est', testNames=[], traverseNamespace=False, verbosity=4, where=(), worker=False, workingDir='/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles') +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: insert /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles into sys.path +nose.plugins.collect: DEBUG: Preparing test loader +nose.core: DEBUG: test loader is +nose.core: DEBUG: defaultTest . +nose.core: DEBUG: Test names are ['.'] +nose.core: DEBUG: createTests called with None +nose.loader: DEBUG: load from . (None) +nose.selector: DEBUG: Test name . resolved to file ., module None, call None +nose.selector: DEBUG: Final resolution of test name .: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles module None call None +nose.plugins.collect: DEBUG: TestSuite([]) +nose.plugins.collect: DEBUG: Add test +nose.core: DEBUG: runTests called +nose.suite: DEBUG: precache is [] +nose.loader: DEBUG: load from dir /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/five.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/four.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/one.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.four.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.four.result? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.one.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.one.result? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.three.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.three.result? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.two.again.result? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.two.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.two.result? False +nose.selector: DEBUG: wantDirectory /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/three.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/two.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py module test_root call None +nose.importer: DEBUG: Import test_root from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: find module part test_root (test_root) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_Root_A (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: Add test test_Root_B (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: Add test test_Root_c (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]> +nose.plugins.collect: DEBUG: Preparing test case test_Root_A (test_root.Test_Root_test1) +test_Root_A (test_root.Test_Root_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_Root_B (test_root.Test_Root_test1) +test_Root_B (test_root.Test_Root_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_Root_c (test_root.Test_Root_test1) +test_Root_c (test_root.Test_Root_test1) ... ok +nose.selector: DEBUG: wantDirectory /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests? True +nose.plugins.collect: DEBUG: TestSuite() +nose.loader: DEBUG: load from dir /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: insert /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests into sys.path +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py module test4 call None +nose.importer: DEBUG: Import test4 from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part test4 (test4) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test4A (test4.Test_test3) +nose.plugins.collect: DEBUG: Add test test4B (test4.Test_test3) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test()]>]> +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py module test_unittest_one call None +nose.importer: DEBUG: Import test_unittest_one from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part test_unittest_one (test_unittest_one) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_A (test_unittest_one.Test_test1) +nose.plugins.collect: DEBUG: Add test test_B (test_unittest_one.Test_test1) +nose.plugins.collect: DEBUG: Add test test_c (test_unittest_one.Test_test1) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]>]> +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py module test_unittest_two call None +nose.importer: DEBUG: Import test_unittest_two from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part test_unittest_two (test_unittest_two) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_A2 (test_unittest_two.Test_test2) +nose.plugins.collect: DEBUG: Add test test_B2 (test_unittest_two.Test_test2) +nose.plugins.collect: DEBUG: Add test test_C2 (test_unittest_two.Test_test2) +nose.plugins.collect: DEBUG: Add test test_D2 (test_unittest_two.Test_test2) +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_222A2 (test_unittest_two.Test_test2a) +nose.plugins.collect: DEBUG: Add test test_222B2 (test_unittest_two.Test_test2a) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test(), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test(), Test(), Test()]>, ), Test()]>]> +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py module unittest_three_test call None +nose.importer: DEBUG: Import unittest_three_test from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part unittest_three_test (unittest_three_test) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_A (unittest_three_test.Test_test3) +nose.plugins.collect: DEBUG: Add test test_B (unittest_three_test.Test_test3) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test()]>]> +nose.importer: DEBUG: Remove path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.plugins.collect: DEBUG: Preparing test case test4A (test4.Test_test3) +test4A (test4.Test_test3) ... ok +nose.plugins.collect: DEBUG: Preparing test case test4B (test4.Test_test3) +test4B (test4.Test_test3) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_A (test_unittest_one.Test_test1) +test_A (test_unittest_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_B (test_unittest_one.Test_test1) +test_B (test_unittest_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_c (test_unittest_one.Test_test1) +test_c (test_unittest_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_A2 (test_unittest_two.Test_test2) +test_A2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_B2 (test_unittest_two.Test_test2) +test_B2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_C2 (test_unittest_two.Test_test2) +test_C2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_D2 (test_unittest_two.Test_test2) +test_D2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_222A2 (test_unittest_two.Test_test2a) +test_222A2 (test_unittest_two.Test_test2a) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_222B2 (test_unittest_two.Test_test2a) +test_222B2 (test_unittest_two.Test_test2a) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_A (unittest_three_test.Test_test3) +test_A (unittest_three_test.Test_test3) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_B (unittest_three_test.Test_test3) +test_B (unittest_three_test.Test_test3) ... ok +nose.suite: DEBUG: precache is [] + +---------------------------------------------------------------------- +Ran 16 tests in 0.048s + +OK diff --git a/src/test/pythonFiles/testFiles/noseFiles/run.five.result b/src/test/pythonFiles/testFiles/noseFiles/run.five.result new file mode 100644 index 000000000000..97c7e0e0216f --- /dev/null +++ b/src/test/pythonFiles/testFiles/noseFiles/run.five.result @@ -0,0 +1,11 @@ + diff --git a/src/test/pythonFiles/testFiles/noseFiles/run.four.output b/src/test/pythonFiles/testFiles/noseFiles/run.four.output new file mode 100644 index 000000000000..aa01067d7925 --- /dev/null +++ b/src/test/pythonFiles/testFiles/noseFiles/run.four.output @@ -0,0 +1,565 @@ +nose.config: INFO: Ignoring files matching ['^\\.', '^_', '^setup\\.py$'] +nose.plugins.manager: DEBUG: Configuring plugins +nose.plugins.manager: DEBUG: Plugins enabled: [, , , , ] +nose.core: DEBUG: configured Config(addPaths=True, args=(), configSection='nosetests', debug=None, debugLog=None, env={}, exclude=None, files=[], firstPackageWins=False, getTestCaseNamesCompat=False, ignoreFiles=[re.compile('^\\.'), re.compile('^_'), re.compile('^setup\\.py$')], ignoreFilesDefaultStrings=['^\\.', '^_', '^setup\\.py$'], include=None, includeExe=False, logStream=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, loggingConfig=None, options=, parser=, parserClass=, plugins=, py3where=(), runOnInit=True, srcDirs=('lib', 'src'), stopOnError=False, stream=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, testMatch=re.compile('test'), testMatchPat='(?:^|[\\b_\\./-])[Tt]est', testNames=[], traverseNamespace=False, verbosity=4, where=(), worker=False, workingDir='/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles') +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: insert /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles into sys.path +nose.plugins.collect: DEBUG: Preparing test loader +nose.core: DEBUG: test loader is +nose.core: DEBUG: defaultTest . +nose.core: DEBUG: Test names are ['.'] +nose.core: DEBUG: createTests called with None +nose.loader: DEBUG: load from . (None) +nose.selector: DEBUG: Test name . resolved to file ., module None, call None +nose.selector: DEBUG: Final resolution of test name .: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles module None call None +nose.plugins.collect: DEBUG: TestSuite([]) +nose.plugins.collect: DEBUG: Add test +nose.core: DEBUG: runTests called +nose.suite: DEBUG: precache is [] +nose.loader: DEBUG: load from dir /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/five.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/four.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/one.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.one.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.one.result? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.three.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.three.result? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.two.again.result? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.two.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.two.result? False +nose.selector: DEBUG: wantDirectory /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/three.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/two.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py module test_root call None +nose.importer: DEBUG: Import test_root from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: find module part test_root (test_root) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_Root_A (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: Add test test_Root_B (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: Add test test_Root_c (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]> +nose.plugins.collect: DEBUG: Preparing test case test_Root_A (test_root.Test_Root_test1) +test_Root_A (test_root.Test_Root_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_Root_B (test_root.Test_Root_test1) +test_Root_B (test_root.Test_Root_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_Root_c (test_root.Test_Root_test1) +test_Root_c (test_root.Test_Root_test1) ... ok +nose.selector: DEBUG: wantDirectory /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests? True +nose.plugins.collect: DEBUG: TestSuite() +nose.loader: DEBUG: load from dir /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: insert /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests into sys.path +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py module test4 call None +nose.importer: DEBUG: Import test4 from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part test4 (test4) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test4A (test4.Test_test3) +nose.plugins.collect: DEBUG: Add test test4B (test4.Test_test3) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test()]>]> +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py module test_unittest_one call None +nose.importer: DEBUG: Import test_unittest_one from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part test_unittest_one (test_unittest_one) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_A (test_unittest_one.Test_test1) +nose.plugins.collect: DEBUG: Add test test_B (test_unittest_one.Test_test1) +nose.plugins.collect: DEBUG: Add test test_c (test_unittest_one.Test_test1) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]>]> +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py module test_unittest_two call None +nose.importer: DEBUG: Import test_unittest_two from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part test_unittest_two (test_unittest_two) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_A2 (test_unittest_two.Test_test2) +nose.plugins.collect: DEBUG: Add test test_B2 (test_unittest_two.Test_test2) +nose.plugins.collect: DEBUG: Add test test_C2 (test_unittest_two.Test_test2) +nose.plugins.collect: DEBUG: Add test test_D2 (test_unittest_two.Test_test2) +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_222A2 (test_unittest_two.Test_test2a) +nose.plugins.collect: DEBUG: Add test test_222B2 (test_unittest_two.Test_test2a) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test(), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test(), Test(), Test()]>, ), Test()]>]> +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py module unittest_three_test call None +nose.importer: DEBUG: Import unittest_three_test from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part unittest_three_test (unittest_three_test) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_A (unittest_three_test.Test_test3) +nose.plugins.collect: DEBUG: Add test test_B (unittest_three_test.Test_test3) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test()]>]> +nose.importer: DEBUG: Remove path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.plugins.collect: DEBUG: Preparing test case test4A (test4.Test_test3) +test4A (test4.Test_test3) ... ok +nose.plugins.collect: DEBUG: Preparing test case test4B (test4.Test_test3) +test4B (test4.Test_test3) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_A (test_unittest_one.Test_test1) +test_A (test_unittest_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_B (test_unittest_one.Test_test1) +test_B (test_unittest_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_c (test_unittest_one.Test_test1) +test_c (test_unittest_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_A2 (test_unittest_two.Test_test2) +test_A2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_B2 (test_unittest_two.Test_test2) +test_B2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_C2 (test_unittest_two.Test_test2) +test_C2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_D2 (test_unittest_two.Test_test2) +test_D2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_222A2 (test_unittest_two.Test_test2a) +test_222A2 (test_unittest_two.Test_test2a) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_222B2 (test_unittest_two.Test_test2a) +test_222B2 (test_unittest_two.Test_test2a) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_A (unittest_three_test.Test_test3) +test_A (unittest_three_test.Test_test3) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_B (unittest_three_test.Test_test3) +test_B (unittest_three_test.Test_test3) ... ok +nose.suite: DEBUG: precache is [] + +---------------------------------------------------------------------- +Ran 16 tests in 0.061s + +OK diff --git a/src/test/pythonFiles/testFiles/noseFiles/run.four.result b/src/test/pythonFiles/testFiles/noseFiles/run.four.result new file mode 100644 index 000000000000..828e4a74b06a --- /dev/null +++ b/src/test/pythonFiles/testFiles/noseFiles/run.four.result @@ -0,0 +1,12 @@ + diff --git a/src/test/pythonFiles/testFiles/noseFiles/run.one.output b/src/test/pythonFiles/testFiles/noseFiles/run.one.output new file mode 100644 index 000000000000..475ac92d3bb4 --- /dev/null +++ b/src/test/pythonFiles/testFiles/noseFiles/run.one.output @@ -0,0 +1,558 @@ +nose.config: INFO: Ignoring files matching ['^\\.', '^_', '^setup\\.py$'] +nose.plugins.manager: DEBUG: Configuring plugins +nose.plugins.manager: DEBUG: Plugins enabled: [, , , , ] +nose.core: DEBUG: configured Config(addPaths=True, args=(), configSection='nosetests', debug=None, debugLog=None, env={}, exclude=None, files=[], firstPackageWins=False, getTestCaseNamesCompat=False, ignoreFiles=[re.compile('^\\.'), re.compile('^_'), re.compile('^setup\\.py$')], ignoreFilesDefaultStrings=['^\\.', '^_', '^setup\\.py$'], include=None, includeExe=False, logStream=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, loggingConfig=None, options=, parser=, parserClass=, plugins=, py3where=(), runOnInit=True, srcDirs=('lib', 'src'), stopOnError=False, stream=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, testMatch=re.compile('test'), testMatchPat='(?:^|[\\b_\\./-])[Tt]est', testNames=[], traverseNamespace=False, verbosity=4, where=(), worker=False, workingDir='/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles') +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: insert /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles into sys.path +nose.plugins.collect: DEBUG: Preparing test loader +nose.core: DEBUG: test loader is +nose.core: DEBUG: defaultTest . +nose.core: DEBUG: Test names are ['.'] +nose.core: DEBUG: createTests called with None +nose.loader: DEBUG: load from . (None) +nose.selector: DEBUG: Test name . resolved to file ., module None, call None +nose.selector: DEBUG: Final resolution of test name .: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles module None call None +nose.plugins.collect: DEBUG: TestSuite([]) +nose.plugins.collect: DEBUG: Add test +nose.core: DEBUG: runTests called +nose.suite: DEBUG: precache is [] +nose.loader: DEBUG: load from dir /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/five.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/four.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/one.output? False +nose.selector: DEBUG: wantDirectory /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/three.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/two.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py module test_root call None +nose.importer: DEBUG: Import test_root from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: find module part test_root (test_root) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_Root_A (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: Add test test_Root_B (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: Add test test_Root_c (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]> +nose.plugins.collect: DEBUG: Preparing test case test_Root_A (test_root.Test_Root_test1) +test_Root_A (test_root.Test_Root_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_Root_B (test_root.Test_Root_test1) +test_Root_B (test_root.Test_Root_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_Root_c (test_root.Test_Root_test1) +test_Root_c (test_root.Test_Root_test1) ... ok +nose.selector: DEBUG: wantDirectory /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests? True +nose.plugins.collect: DEBUG: TestSuite() +nose.loader: DEBUG: load from dir /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: insert /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests into sys.path +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py module test4 call None +nose.importer: DEBUG: Import test4 from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part test4 (test4) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test4A (test4.Test_test3) +nose.plugins.collect: DEBUG: Add test test4B (test4.Test_test3) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test()]>]> +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py module test_unittest_one call None +nose.importer: DEBUG: Import test_unittest_one from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part test_unittest_one (test_unittest_one) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_A (test_unittest_one.Test_test1) +nose.plugins.collect: DEBUG: Add test test_B (test_unittest_one.Test_test1) +nose.plugins.collect: DEBUG: Add test test_c (test_unittest_one.Test_test1) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]>]> +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py module test_unittest_two call None +nose.importer: DEBUG: Import test_unittest_two from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part test_unittest_two (test_unittest_two) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_A2 (test_unittest_two.Test_test2) +nose.plugins.collect: DEBUG: Add test test_B2 (test_unittest_two.Test_test2) +nose.plugins.collect: DEBUG: Add test test_C2 (test_unittest_two.Test_test2) +nose.plugins.collect: DEBUG: Add test test_D2 (test_unittest_two.Test_test2) +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_222A2 (test_unittest_two.Test_test2a) +nose.plugins.collect: DEBUG: Add test test_222B2 (test_unittest_two.Test_test2a) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test(), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test(), Test(), Test()]>, ), Test()]>]> +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py module unittest_three_test call None +nose.importer: DEBUG: Import unittest_three_test from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part unittest_three_test (unittest_three_test) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_A (unittest_three_test.Test_test3) +nose.plugins.collect: DEBUG: Add test test_B (unittest_three_test.Test_test3) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test()]>]> +nose.importer: DEBUG: Remove path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.plugins.collect: DEBUG: Preparing test case test4A (test4.Test_test3) +test4A (test4.Test_test3) ... ok +nose.plugins.collect: DEBUG: Preparing test case test4B (test4.Test_test3) +test4B (test4.Test_test3) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_A (test_unittest_one.Test_test1) +test_A (test_unittest_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_B (test_unittest_one.Test_test1) +test_B (test_unittest_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_c (test_unittest_one.Test_test1) +test_c (test_unittest_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_A2 (test_unittest_two.Test_test2) +test_A2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_B2 (test_unittest_two.Test_test2) +test_B2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_C2 (test_unittest_two.Test_test2) +test_C2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_D2 (test_unittest_two.Test_test2) +test_D2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_222A2 (test_unittest_two.Test_test2a) +test_222A2 (test_unittest_two.Test_test2a) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_222B2 (test_unittest_two.Test_test2a) +test_222B2 (test_unittest_two.Test_test2a) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_A (unittest_three_test.Test_test3) +test_A (unittest_three_test.Test_test3) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_B (unittest_three_test.Test_test3) +test_B (unittest_three_test.Test_test3) ... ok +nose.suite: DEBUG: precache is [] + +---------------------------------------------------------------------- +Ran 16 tests in 0.048s + +OK diff --git a/src/test/pythonFiles/testFiles/noseFiles/run.one.result b/src/test/pythonFiles/testFiles/noseFiles/run.one.result new file mode 100644 index 000000000000..59de2cfcdcc8 --- /dev/null +++ b/src/test/pythonFiles/testFiles/noseFiles/run.one.result @@ -0,0 +1,83 @@ + diff --git a/src/test/pythonFiles/testFiles/noseFiles/run.three.output b/src/test/pythonFiles/testFiles/noseFiles/run.three.output new file mode 100644 index 000000000000..da1ec6bc25c9 --- /dev/null +++ b/src/test/pythonFiles/testFiles/noseFiles/run.three.output @@ -0,0 +1,563 @@ +nose.config: INFO: Ignoring files matching ['^\\.', '^_', '^setup\\.py$'] +nose.plugins.manager: DEBUG: Configuring plugins +nose.plugins.manager: DEBUG: Plugins enabled: [, , , , ] +nose.core: DEBUG: configured Config(addPaths=True, args=(), configSection='nosetests', debug=None, debugLog=None, env={}, exclude=None, files=[], firstPackageWins=False, getTestCaseNamesCompat=False, ignoreFiles=[re.compile('^\\.'), re.compile('^_'), re.compile('^setup\\.py$')], ignoreFilesDefaultStrings=['^\\.', '^_', '^setup\\.py$'], include=None, includeExe=False, logStream=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, loggingConfig=None, options=, parser=, parserClass=, plugins=, py3where=(), runOnInit=True, srcDirs=('lib', 'src'), stopOnError=False, stream=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, testMatch=re.compile('test'), testMatchPat='(?:^|[\\b_\\./-])[Tt]est', testNames=[], traverseNamespace=False, verbosity=4, where=(), worker=False, workingDir='/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles') +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: insert /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles into sys.path +nose.plugins.collect: DEBUG: Preparing test loader +nose.core: DEBUG: test loader is +nose.core: DEBUG: defaultTest . +nose.core: DEBUG: Test names are ['.'] +nose.core: DEBUG: createTests called with None +nose.loader: DEBUG: load from . (None) +nose.selector: DEBUG: Test name . resolved to file ., module None, call None +nose.selector: DEBUG: Final resolution of test name .: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles module None call None +nose.plugins.collect: DEBUG: TestSuite([]) +nose.plugins.collect: DEBUG: Add test +nose.core: DEBUG: runTests called +nose.suite: DEBUG: precache is [] +nose.loader: DEBUG: load from dir /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/five.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/four.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/one.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.one.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.one.result? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.two.again.result? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.two.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.two.result? False +nose.selector: DEBUG: wantDirectory /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/three.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/two.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py module test_root call None +nose.importer: DEBUG: Import test_root from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: find module part test_root (test_root) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_Root_A (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: Add test test_Root_B (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: Add test test_Root_c (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]> +nose.plugins.collect: DEBUG: Preparing test case test_Root_A (test_root.Test_Root_test1) +test_Root_A (test_root.Test_Root_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_Root_B (test_root.Test_Root_test1) +test_Root_B (test_root.Test_Root_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_Root_c (test_root.Test_Root_test1) +test_Root_c (test_root.Test_Root_test1) ... ok +nose.selector: DEBUG: wantDirectory /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests? True +nose.plugins.collect: DEBUG: TestSuite() +nose.loader: DEBUG: load from dir /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: insert /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests into sys.path +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py module test4 call None +nose.importer: DEBUG: Import test4 from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part test4 (test4) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test4A (test4.Test_test3) +nose.plugins.collect: DEBUG: Add test test4B (test4.Test_test3) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test()]>]> +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py module test_unittest_one call None +nose.importer: DEBUG: Import test_unittest_one from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part test_unittest_one (test_unittest_one) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_A (test_unittest_one.Test_test1) +nose.plugins.collect: DEBUG: Add test test_B (test_unittest_one.Test_test1) +nose.plugins.collect: DEBUG: Add test test_c (test_unittest_one.Test_test1) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]>]> +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py module test_unittest_two call None +nose.importer: DEBUG: Import test_unittest_two from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part test_unittest_two (test_unittest_two) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_A2 (test_unittest_two.Test_test2) +nose.plugins.collect: DEBUG: Add test test_B2 (test_unittest_two.Test_test2) +nose.plugins.collect: DEBUG: Add test test_C2 (test_unittest_two.Test_test2) +nose.plugins.collect: DEBUG: Add test test_D2 (test_unittest_two.Test_test2) +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_222A2 (test_unittest_two.Test_test2a) +nose.plugins.collect: DEBUG: Add test test_222B2 (test_unittest_two.Test_test2a) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test(), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test(), Test(), Test()]>, ), Test()]>]> +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py module unittest_three_test call None +nose.importer: DEBUG: Import unittest_three_test from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part unittest_three_test (unittest_three_test) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_A (unittest_three_test.Test_test3) +nose.plugins.collect: DEBUG: Add test test_B (unittest_three_test.Test_test3) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test()]>]> +nose.importer: DEBUG: Remove path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.plugins.collect: DEBUG: Preparing test case test4A (test4.Test_test3) +test4A (test4.Test_test3) ... ok +nose.plugins.collect: DEBUG: Preparing test case test4B (test4.Test_test3) +test4B (test4.Test_test3) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_A (test_unittest_one.Test_test1) +test_A (test_unittest_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_B (test_unittest_one.Test_test1) +test_B (test_unittest_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_c (test_unittest_one.Test_test1) +test_c (test_unittest_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_A2 (test_unittest_two.Test_test2) +test_A2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_B2 (test_unittest_two.Test_test2) +test_B2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_C2 (test_unittest_two.Test_test2) +test_C2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_D2 (test_unittest_two.Test_test2) +test_D2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_222A2 (test_unittest_two.Test_test2a) +test_222A2 (test_unittest_two.Test_test2a) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_222B2 (test_unittest_two.Test_test2a) +test_222B2 (test_unittest_two.Test_test2a) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_A (unittest_three_test.Test_test3) +test_A (unittest_three_test.Test_test3) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_B (unittest_three_test.Test_test3) +test_B (unittest_three_test.Test_test3) ... ok +nose.suite: DEBUG: precache is [] + +---------------------------------------------------------------------- +Ran 16 tests in 0.047s + +OK diff --git a/src/test/pythonFiles/testFiles/noseFiles/run.three.result b/src/test/pythonFiles/testFiles/noseFiles/run.three.result new file mode 100644 index 000000000000..828e4a74b06a --- /dev/null +++ b/src/test/pythonFiles/testFiles/noseFiles/run.three.result @@ -0,0 +1,12 @@ + diff --git a/src/test/pythonFiles/testFiles/noseFiles/run.two.again.result b/src/test/pythonFiles/testFiles/noseFiles/run.two.again.result new file mode 100644 index 000000000000..b60e8229c55d --- /dev/null +++ b/src/test/pythonFiles/testFiles/noseFiles/run.two.again.result @@ -0,0 +1,81 @@ + diff --git a/src/test/pythonFiles/testFiles/noseFiles/run.two.output b/src/test/pythonFiles/testFiles/noseFiles/run.two.output new file mode 100644 index 000000000000..31a5a5e9c34b --- /dev/null +++ b/src/test/pythonFiles/testFiles/noseFiles/run.two.output @@ -0,0 +1,560 @@ +nose.config: INFO: Ignoring files matching ['^\\.', '^_', '^setup\\.py$'] +nose.plugins.manager: DEBUG: Configuring plugins +nose.plugins.manager: DEBUG: Plugins enabled: [, , , , ] +nose.core: DEBUG: configured Config(addPaths=True, args=(), configSection='nosetests', debug=None, debugLog=None, env={}, exclude=None, files=[], firstPackageWins=False, getTestCaseNamesCompat=False, ignoreFiles=[re.compile('^\\.'), re.compile('^_'), re.compile('^setup\\.py$')], ignoreFilesDefaultStrings=['^\\.', '^_', '^setup\\.py$'], include=None, includeExe=False, logStream=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, loggingConfig=None, options=, parser=, parserClass=, plugins=, py3where=(), runOnInit=True, srcDirs=('lib', 'src'), stopOnError=False, stream=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, testMatch=re.compile('test'), testMatchPat='(?:^|[\\b_\\./-])[Tt]est', testNames=[], traverseNamespace=False, verbosity=4, where=(), worker=False, workingDir='/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles') +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: insert /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles into sys.path +nose.plugins.collect: DEBUG: Preparing test loader +nose.core: DEBUG: test loader is +nose.core: DEBUG: defaultTest . +nose.core: DEBUG: Test names are ['.'] +nose.core: DEBUG: createTests called with None +nose.loader: DEBUG: load from . (None) +nose.selector: DEBUG: Test name . resolved to file ., module None, call None +nose.selector: DEBUG: Final resolution of test name .: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles module None call None +nose.plugins.collect: DEBUG: TestSuite([]) +nose.plugins.collect: DEBUG: Add test +nose.core: DEBUG: runTests called +nose.suite: DEBUG: precache is [] +nose.loader: DEBUG: load from dir /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/five.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/four.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/one.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.one.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/run.one.result? False +nose.selector: DEBUG: wantDirectory /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/three.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/two.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py module test_root call None +nose.importer: DEBUG: Import test_root from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: find module part test_root (test_root) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_Root_A (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: Add test test_Root_B (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: Add test test_Root_c (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]> +nose.plugins.collect: DEBUG: Preparing test case test_Root_A (test_root.Test_Root_test1) +test_Root_A (test_root.Test_Root_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_Root_B (test_root.Test_Root_test1) +test_Root_B (test_root.Test_Root_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_Root_c (test_root.Test_Root_test1) +test_Root_c (test_root.Test_Root_test1) ... ok +nose.selector: DEBUG: wantDirectory /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests? True +nose.plugins.collect: DEBUG: TestSuite() +nose.loader: DEBUG: load from dir /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: insert /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests into sys.path +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py module test4 call None +nose.importer: DEBUG: Import test4 from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part test4 (test4) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test4A (test4.Test_test3) +nose.plugins.collect: DEBUG: Add test test4B (test4.Test_test3) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test()]>]> +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py module test_unittest_one call None +nose.importer: DEBUG: Import test_unittest_one from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part test_unittest_one (test_unittest_one) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_A (test_unittest_one.Test_test1) +nose.plugins.collect: DEBUG: Add test test_B (test_unittest_one.Test_test1) +nose.plugins.collect: DEBUG: Add test test_c (test_unittest_one.Test_test1) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]>]> +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py module test_unittest_two call None +nose.importer: DEBUG: Import test_unittest_two from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part test_unittest_two (test_unittest_two) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_A2 (test_unittest_two.Test_test2) +nose.plugins.collect: DEBUG: Add test test_B2 (test_unittest_two.Test_test2) +nose.plugins.collect: DEBUG: Add test test_C2 (test_unittest_two.Test_test2) +nose.plugins.collect: DEBUG: Add test test_D2 (test_unittest_two.Test_test2) +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_222A2 (test_unittest_two.Test_test2a) +nose.plugins.collect: DEBUG: Add test test_222B2 (test_unittest_two.Test_test2a) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test(), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test(), Test(), Test()]>, ), Test()]>]> +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py module unittest_three_test call None +nose.importer: DEBUG: Import unittest_three_test from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part unittest_three_test (unittest_three_test) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_A (unittest_three_test.Test_test3) +nose.plugins.collect: DEBUG: Add test test_B (unittest_three_test.Test_test3) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test()]>]> +nose.importer: DEBUG: Remove path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.plugins.collect: DEBUG: Preparing test case test4A (test4.Test_test3) +test4A (test4.Test_test3) ... ok +nose.plugins.collect: DEBUG: Preparing test case test4B (test4.Test_test3) +test4B (test4.Test_test3) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_A (test_unittest_one.Test_test1) +test_A (test_unittest_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_B (test_unittest_one.Test_test1) +test_B (test_unittest_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_c (test_unittest_one.Test_test1) +test_c (test_unittest_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_A2 (test_unittest_two.Test_test2) +test_A2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_B2 (test_unittest_two.Test_test2) +test_B2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_C2 (test_unittest_two.Test_test2) +test_C2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_D2 (test_unittest_two.Test_test2) +test_D2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_222A2 (test_unittest_two.Test_test2a) +test_222A2 (test_unittest_two.Test_test2a) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_222B2 (test_unittest_two.Test_test2a) +test_222B2 (test_unittest_two.Test_test2a) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_A (unittest_three_test.Test_test3) +test_A (unittest_three_test.Test_test3) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_B (unittest_three_test.Test_test3) +test_B (unittest_three_test.Test_test3) ... ok +nose.suite: DEBUG: precache is [] + +---------------------------------------------------------------------- +Ran 16 tests in 0.137s + +OK diff --git a/src/test/pythonFiles/testFiles/noseFiles/run.two.result b/src/test/pythonFiles/testFiles/noseFiles/run.two.result new file mode 100644 index 000000000000..59de2cfcdcc8 --- /dev/null +++ b/src/test/pythonFiles/testFiles/noseFiles/run.two.result @@ -0,0 +1,83 @@ + diff --git a/src/test/pythonFiles/testFiles/noseFiles/three.output b/src/test/pythonFiles/testFiles/noseFiles/three.output new file mode 100644 index 000000000000..a57dae74d180 --- /dev/null +++ b/src/test/pythonFiles/testFiles/noseFiles/three.output @@ -0,0 +1,555 @@ +nose.config: INFO: Ignoring files matching ['^\\.', '^_', '^setup\\.py$'] +nose.plugins.manager: DEBUG: Configuring plugins +nose.plugins.manager: DEBUG: Plugins enabled: [, , , , ] +nose.core: DEBUG: configured Config(addPaths=True, args=(), configSection='nosetests', debug=None, debugLog=None, env={}, exclude=None, files=[], firstPackageWins=False, getTestCaseNamesCompat=False, ignoreFiles=[re.compile('^\\.'), re.compile('^_'), re.compile('^setup\\.py$')], ignoreFilesDefaultStrings=['^\\.', '^_', '^setup\\.py$'], include=None, includeExe=False, logStream=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, loggingConfig=None, options=, parser=, parserClass=, plugins=, py3where=(), runOnInit=True, srcDirs=('lib', 'src'), stopOnError=False, stream=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, testMatch=re.compile('test'), testMatchPat='(?:^|[\\b_\\./-])[Tt]est', testNames=[], traverseNamespace=False, verbosity=4, where=(), worker=False, workingDir='/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles') +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: insert /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles into sys.path +nose.plugins.collect: DEBUG: Preparing test loader +nose.core: DEBUG: test loader is +nose.core: DEBUG: defaultTest . +nose.core: DEBUG: Test names are ['.'] +nose.core: DEBUG: createTests called with None +nose.loader: DEBUG: load from . (None) +nose.selector: DEBUG: Test name . resolved to file ., module None, call None +nose.selector: DEBUG: Final resolution of test name .: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles module None call None +nose.plugins.collect: DEBUG: TestSuite([]) +nose.plugins.collect: DEBUG: Add test +nose.core: DEBUG: runTests called +nose.suite: DEBUG: precache is [] +nose.loader: DEBUG: load from dir /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/one.output? False +nose.selector: DEBUG: wantDirectory /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/specific? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/two.output? False +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/test_root.py module test_root call None +nose.importer: DEBUG: Import test_root from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles +nose.importer: DEBUG: find module part test_root (test_root) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_Root_A (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: Add test test_Root_B (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: Add test test_Root_c (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]> +nose.plugins.collect: DEBUG: Preparing test case test_Root_A (test_root.Test_Root_test1) +test_Root_A (test_root.Test_Root_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_Root_B (test_root.Test_Root_test1) +test_Root_B (test_root.Test_Root_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_Root_c (test_root.Test_Root_test1) +test_Root_c (test_root.Test_Root_test1) ... ok +nose.selector: DEBUG: wantDirectory /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests? True +nose.plugins.collect: DEBUG: TestSuite() +nose.loader: DEBUG: load from dir /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: insert /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests into sys.path +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test4.py module test4 call None +nose.importer: DEBUG: Import test4 from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part test4 (test4) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test4A (test4.Test_test3) +nose.plugins.collect: DEBUG: Add test test4B (test4.Test_test3) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test()]>]> +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_one.py module test_unittest_one call None +nose.importer: DEBUG: Import test_unittest_one from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part test_unittest_one (test_unittest_one) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_A (test_unittest_one.Test_test1) +nose.plugins.collect: DEBUG: Add test test_B (test_unittest_one.Test_test1) +nose.plugins.collect: DEBUG: Add test test_c (test_unittest_one.Test_test1) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]>]> +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/test_unittest_two.py module test_unittest_two call None +nose.importer: DEBUG: Import test_unittest_two from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part test_unittest_two (test_unittest_two) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_A2 (test_unittest_two.Test_test2) +nose.plugins.collect: DEBUG: Add test test_B2 (test_unittest_two.Test_test2) +nose.plugins.collect: DEBUG: Add test test_C2 (test_unittest_two.Test_test2) +nose.plugins.collect: DEBUG: Add test test_D2 (test_unittest_two.Test_test2) +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_222A2 (test_unittest_two.Test_test2a) +nose.plugins.collect: DEBUG: Add test test_222B2 (test_unittest_two.Test_test2a) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test(), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test(), Test(), Test()]>, ), Test()]>]> +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests/unittest_three_test.py module unittest_three_test call None +nose.importer: DEBUG: Import unittest_three_test from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.importer: DEBUG: find module part unittest_three_test (unittest_three_test) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_A (unittest_three_test.Test_test3) +nose.plugins.collect: DEBUG: Add test test_B (unittest_three_test.Test_test3) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test()]>]> +nose.importer: DEBUG: Remove path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/noseFiles/tests +nose.plugins.collect: DEBUG: Preparing test case test4A (test4.Test_test3) +test4A (test4.Test_test3) ... ok +nose.plugins.collect: DEBUG: Preparing test case test4B (test4.Test_test3) +test4B (test4.Test_test3) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_A (test_unittest_one.Test_test1) +test_A (test_unittest_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_B (test_unittest_one.Test_test1) +test_B (test_unittest_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_c (test_unittest_one.Test_test1) +test_c (test_unittest_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_A2 (test_unittest_two.Test_test2) +test_A2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_B2 (test_unittest_two.Test_test2) +test_B2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_C2 (test_unittest_two.Test_test2) +test_C2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_D2 (test_unittest_two.Test_test2) +test_D2 (test_unittest_two.Test_test2) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_222A2 (test_unittest_two.Test_test2a) +test_222A2 (test_unittest_two.Test_test2a) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_222B2 (test_unittest_two.Test_test2a) +test_222B2 (test_unittest_two.Test_test2a) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_A (unittest_three_test.Test_test3) +test_A (unittest_three_test.Test_test3) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_B (unittest_three_test.Test_test3) +test_B (unittest_three_test.Test_test3) ... ok +nose.suite: DEBUG: precache is [] + +---------------------------------------------------------------------- +Ran 16 tests in 0.052s + +OK diff --git a/src/test/pythonFiles/testFiles/noseFiles/two.output b/src/test/pythonFiles/testFiles/noseFiles/two.output new file mode 100644 index 000000000000..25fcf10c93d5 --- /dev/null +++ b/src/test/pythonFiles/testFiles/noseFiles/two.output @@ -0,0 +1,211 @@ +nose.config: INFO: Ignoring files matching ['^\\.', '^_', '^setup\\.py$'] +nose.plugins.manager: DEBUG: Configuring plugins +nose.plugins.manager: DEBUG: Plugins enabled: [, , , , ] +nose.core: DEBUG: configured Config(addPaths=True, args=(), configSection='nosetests', debug=None, debugLog=None, env={}, exclude=None, files=[], firstPackageWins=False, getTestCaseNamesCompat=False, ignoreFiles=[re.compile('^\\.'), re.compile('^_'), re.compile('^setup\\.py$')], ignoreFilesDefaultStrings=['^\\.', '^_', '^setup\\.py$'], include=None, includeExe=False, logStream=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, loggingConfig=None, options=, parser=, parserClass=, plugins=, py3where=(), runOnInit=True, srcDirs=('lib', 'src'), stopOnError=False, stream=<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, testMatch=re.compile('(?:^|[\\b_\\./-])[Tt]est'), testMatchPat='(?:^|[\\b_\\./-])[Tt]est', testNames=[], traverseNamespace=False, verbosity=4, where=(), worker=False, workingDir='/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single') +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single +nose.importer: DEBUG: insert /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single into sys.path +nose.plugins.collect: DEBUG: Preparing test loader +nose.core: DEBUG: test loader is +nose.core: DEBUG: defaultTest . +nose.core: DEBUG: Test names are ['.'] +nose.core: DEBUG: createTests called with None +nose.loader: DEBUG: load from . (None) +nose.selector: DEBUG: Test name . resolved to file ., module None, call None +nose.selector: DEBUG: Final resolution of test name .: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single module None call None +nose.plugins.collect: DEBUG: TestSuite([]) +nose.plugins.collect: DEBUG: Add test +nose.core: DEBUG: runTests called +nose.suite: DEBUG: precache is [] +nose.loader: DEBUG: load from dir /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/test_root.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/test_root.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/test_root.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/test_root.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/test_root.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/test_root.py module test_root call None +nose.importer: DEBUG: Import test_root from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single +nose.importer: DEBUG: find module part test_root (test_root) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_Root_A (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: Add test test_Root_B (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: Add test test_Root_c (test_root.Test_Root_test1) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]> +nose.plugins.collect: DEBUG: Preparing test case test_Root_A (test_root.Test_Root_test1) +test_Root_A (test_root.Test_Root_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_Root_B (test_root.Test_Root_test1) +test_Root_B (test_root.Test_Root_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_Root_c (test_root.Test_Root_test1) +test_Root_c (test_root.Test_Root_test1) ... ok +nose.selector: DEBUG: wantDirectory /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests? True +nose.plugins.collect: DEBUG: TestSuite() +nose.loader: DEBUG: load from dir /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests +nose.importer: DEBUG: insert /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests into sys.path +nose.selector: DEBUG: wantFile /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests/test_one.py? True +nose.loader: DEBUG: load from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests/test_one.py (None) +nose.selector: DEBUG: Test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests/test_one.py resolved to file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests/test_one.py, module None, call None +nose.selector: DEBUG: Final resolution of test name /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests/test_one.py: file /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests/test_one.py module test_one call None +nose.importer: DEBUG: Import test_one from /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests +nose.importer: DEBUG: Add path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests +nose.importer: DEBUG: find module part test_one (test_one) in ['/Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests'] +nose.loader: DEBUG: Load from module +nose.selector: DEBUG: wantModule ? True +nose.selector: DEBUG: wantClass ? True +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod ? None +nose.selector: DEBUG: wantMethod >? None +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.selector: DEBUG: wantMethod ? True +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test test_A (test_one.Test_test1) +nose.plugins.collect: DEBUG: Add test test_B (test_one.Test_test1) +nose.plugins.collect: DEBUG: Add test test_c (test_one.Test_test1) +nose.plugins.collect: DEBUG: TestSuite() +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]> +nose.plugins.collect: DEBUG: Add test ), Test(), Test()]>]> +nose.importer: DEBUG: Remove path /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single/tests +nose.plugins.collect: DEBUG: Preparing test case test_A (test_one.Test_test1) +test_A (test_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_B (test_one.Test_test1) +test_B (test_one.Test_test1) ... ok +nose.plugins.collect: DEBUG: Preparing test case test_c (test_one.Test_test1) +test_c (test_one.Test_test1) ... ok +nose.suite: DEBUG: precache is [] + +---------------------------------------------------------------------- +Ran 6 tests in 0.188s + +OK diff --git a/src/test/pythonFiles/testFiles/pytestFiles/results/five.output b/src/test/pythonFiles/testFiles/pytestFiles/results/five.output new file mode 100644 index 000000000000..e03b01dab403 --- /dev/null +++ b/src/test/pythonFiles/testFiles/pytestFiles/results/five.output @@ -0,0 +1,53 @@ +============================= test session starts ============================== +platform darwin -- Python 3.6.2, pytest-3.3.0, py-1.5.2, pluggy-0.6.0 +rootdir: /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/standard, inifile: +plugins: pylama-7.4.3 +collected 29 items + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +========================= no tests ran in 0.07 seconds ========================= diff --git a/src/test/pythonFiles/testFiles/pytestFiles/results/five.xml b/src/test/pythonFiles/testFiles/pytestFiles/results/five.xml new file mode 100644 index 000000000000..87d7abeb58ce --- /dev/null +++ b/src/test/pythonFiles/testFiles/pytestFiles/results/five.xml @@ -0,0 +1,7 @@ +self = <test_root.Test_Root_test1 testMethod=test_Root_A> + + def test_Root_A(self): +> self.fail("Not implemented") +E AssertionError: Not implemented + +test_root.py:8: AssertionError diff --git a/src/test/pythonFiles/testFiles/pytestFiles/results/four.output b/src/test/pythonFiles/testFiles/pytestFiles/results/four.output new file mode 100644 index 000000000000..c7d46fd0124e --- /dev/null +++ b/src/test/pythonFiles/testFiles/pytestFiles/results/four.output @@ -0,0 +1,53 @@ +============================= test session starts ============================== +platform darwin -- Python 3.6.2, pytest-3.3.0, py-1.5.2, pluggy-0.6.0 +rootdir: /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/standard, inifile: +plugins: pylama-7.4.3 +collected 29 items + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +========================= no tests ran in 0.05 seconds ========================= diff --git a/src/test/pythonFiles/testFiles/pytestFiles/results/four.xml b/src/test/pythonFiles/testFiles/pytestFiles/results/four.xml new file mode 100644 index 000000000000..b13d0a4c1fc3 --- /dev/null +++ b/src/test/pythonFiles/testFiles/pytestFiles/results/four.xml @@ -0,0 +1,7 @@ +self = <test_root.Test_Root_test1 testMethod=test_Root_A> + + def test_Root_A(self): +> self.fail("Not implemented") +E AssertionError: Not implemented + +test_root.py:8: AssertionErrortest_root.py:12: <py._xmlgen.raw object at 0x10a139048> diff --git a/src/test/pythonFiles/testFiles/pytestFiles/results/one.output b/src/test/pythonFiles/testFiles/pytestFiles/results/one.output new file mode 100644 index 000000000000..10fecc32623f --- /dev/null +++ b/src/test/pythonFiles/testFiles/pytestFiles/results/one.output @@ -0,0 +1,53 @@ +============================= test session starts ============================== +platform darwin -- Python 3.6.2, pytest-3.3.0, py-1.5.2, pluggy-0.6.0 +rootdir: /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/standard, inifile: +plugins: pylama-7.4.3 +collected 29 items + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +========================= no tests ran in 0.06 seconds ========================= diff --git a/src/test/pythonFiles/testFiles/pytestFiles/results/one.xml b/src/test/pythonFiles/testFiles/pytestFiles/results/one.xml new file mode 100644 index 000000000000..9601fe884054 --- /dev/null +++ b/src/test/pythonFiles/testFiles/pytestFiles/results/one.xml @@ -0,0 +1,55 @@ +self = <test_root.Test_Root_test1 testMethod=test_Root_A> + + def test_Root_A(self): +> self.fail("Not implemented") +E AssertionError: Not implemented + +test_root.py:8: AssertionErrortest_root.py:12: <py._xmlgen.raw object at 0x1024cf048>non_parametrized_username = 'three' + + def test_parametrized_username(non_parametrized_username): +> assert non_parametrized_username in ['one', 'two', 'threes'] +E AssertionError: assert 'three' in ['one', 'two', 'threes'] + +tests/test_another_pytest.py:17: AssertionError/Users/donjayamanne/anaconda3/lib/python3.6/site-packages/_pytest/nose.py:23: <py._xmlgen.raw object at 0x1024fb518>non_parametrized_username = 'three' + + def test_parametrized_username(non_parametrized_username): +> assert non_parametrized_username in ['one', 'two', 'threes'] +E AssertionError: assert 'three' in ['one', 'two', 'threes'] + +tests/test_pytest.py:40: AssertionErrorself = <test_unittest_one.Test_test1 testMethod=test_A> + + def test_A(self): +> self.fail("Not implemented") +E AssertionError: Not implemented + +tests/test_unittest_one.py:8: AssertionErrortests/test_unittest_one.py:12: <py._xmlgen.raw object at 0x102504cc0>self = <test_unittest_two.Test_test2 testMethod=test_A2> + + def test_A2(self): +> self.fail("Not implemented") +E AssertionError: Not implemented + +tests/test_unittest_two.py:5: AssertionErrorself = <test_unittest_two.Test_test2 testMethod=test_C2> + + def test_C2(self): +> self.assertEqual(1,2,'Not equal') +E AssertionError: 1 != 2 : Not equal + +tests/test_unittest_two.py:11: AssertionErrorself = <test_unittest_two.Test_test2 testMethod=test_D2> + + def test_D2(self): +> raise ArithmeticError() +E ArithmeticError + +tests/test_unittest_two.py:14: ArithmeticErrorself = <test_unittest_two.Test_test2a testMethod=test_222A2> + + def test_222A2(self): +> self.fail("Not implemented") +E AssertionError: Not implemented + +tests/test_unittest_two.py:19: AssertionErrorself = <unittest_three_test.Test_test3 testMethod=test_A> + + def test_A(self): +> self.fail("Not implemented") +E AssertionError: Not implemented + +tests/unittest_three_test.py:6: AssertionError diff --git a/src/test/pythonFiles/testFiles/pytestFiles/results/three.output b/src/test/pythonFiles/testFiles/pytestFiles/results/three.output new file mode 100644 index 000000000000..2d7f12f87c68 --- /dev/null +++ b/src/test/pythonFiles/testFiles/pytestFiles/results/three.output @@ -0,0 +1,54 @@ +============================= test session starts ============================== +platform darwin -- Python 3.6.2, pytest-3.3.0, py-1.5.2, pluggy-0.6.0 +rootdir: /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/standard, inifile: +plugins: pylama-7.4.3 +collected 29 items + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +========================= no tests ran in 0.04 seconds ========================= + diff --git a/src/test/pythonFiles/testFiles/pytestFiles/results/three.xml b/src/test/pythonFiles/testFiles/pytestFiles/results/three.xml new file mode 100644 index 000000000000..0d1e912f656c --- /dev/null +++ b/src/test/pythonFiles/testFiles/pytestFiles/results/three.xml @@ -0,0 +1,7 @@ +non_parametrized_username = 'three' + + def test_parametrized_username(non_parametrized_username): +> assert non_parametrized_username in ['one', 'two', 'threes'] +E AssertionError: assert 'three' in ['one', 'two', 'threes'] + +tests/test_another_pytest.py:17: AssertionError diff --git a/src/test/pythonFiles/testFiles/pytestFiles/results/two.again.xml b/src/test/pythonFiles/testFiles/pytestFiles/results/two.again.xml new file mode 100644 index 000000000000..cbb200446dab --- /dev/null +++ b/src/test/pythonFiles/testFiles/pytestFiles/results/two.again.xml @@ -0,0 +1,55 @@ +self = <test_root.Test_Root_test1 testMethod=test_Root_A> + + def test_Root_A(self): +> self.fail("Not implemented") +E AssertionError: Not implemented + +test_root.py:8: AssertionErrornon_parametrized_username = 'three' + + def test_parametrized_username(non_parametrized_username): +> assert non_parametrized_username in ['one', 'two', 'threes'] +E AssertionError: assert 'three' in ['one', 'two', 'threes'] + +tests/test_another_pytest.py:17: AssertionErrornon_parametrized_username = 'three' + + def test_parametrized_username(non_parametrized_username): +> assert non_parametrized_username in ['one', 'two', 'threes'] +E AssertionError: assert 'three' in ['one', 'two', 'threes'] + +tests/test_pytest.py:40: AssertionErrorself = <test_unittest_one.Test_test1 testMethod=test_A> + + def test_A(self): +> self.fail("Not implemented") +E AssertionError: Not implemented + +tests/test_unittest_one.py:8: AssertionErrorself = <test_unittest_two.Test_test2 testMethod=test_A2> + + def test_A2(self): +> self.fail("Not implemented") +E AssertionError: Not implemented + +tests/test_unittest_two.py:5: AssertionErrorself = <test_unittest_two.Test_test2 testMethod=test_C2> + + def test_C2(self): +> self.assertEqual(1,2,'Not equal') +E AssertionError: 1 != 2 : Not equal + +tests/test_unittest_two.py:11: AssertionErrorself = <test_unittest_two.Test_test2 testMethod=test_D2> + + def test_D2(self): +> raise ArithmeticError() +E ArithmeticError + +tests/test_unittest_two.py:14: ArithmeticErrorself = <test_unittest_two.Test_test2a testMethod=test_222A2> + + def test_222A2(self): +> self.fail("Not implemented") +E AssertionError: Not implemented + +tests/test_unittest_two.py:19: AssertionErrorself = <unittest_three_test.Test_test3 testMethod=test_A> + + def test_A(self): +> self.fail("Not implemented") +E AssertionError: Not implemented + +tests/unittest_three_test.py:6: AssertionError diff --git a/src/test/pythonFiles/testFiles/pytestFiles/results/two.output b/src/test/pythonFiles/testFiles/pytestFiles/results/two.output new file mode 100644 index 000000000000..e7755b879bac --- /dev/null +++ b/src/test/pythonFiles/testFiles/pytestFiles/results/two.output @@ -0,0 +1,54 @@ +============================= test session starts ============================== +platform darwin -- Python 3.6.2, pytest-3.3.0, py-1.5.2, pluggy-0.6.0 +rootdir: /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/standard, inifile: +plugins: pylama-7.4.3 +collected 29 items + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +========================= no tests ran in 0.05 seconds ========================= + diff --git a/src/test/pythonFiles/testFiles/pytestFiles/results/two.xml b/src/test/pythonFiles/testFiles/pytestFiles/results/two.xml new file mode 100644 index 000000000000..7a570d780eff --- /dev/null +++ b/src/test/pythonFiles/testFiles/pytestFiles/results/two.xml @@ -0,0 +1,55 @@ +self = <test_root.Test_Root_test1 testMethod=test_Root_A> + + def test_Root_A(self): +> self.fail("Not implemented") +E AssertionError: Not implemented + +test_root.py:8: AssertionErrortest_root.py:12: <py._xmlgen.raw object at 0x10a5a4048>non_parametrized_username = 'three' + + def test_parametrized_username(non_parametrized_username): +> assert non_parametrized_username in ['one', 'two', 'threes'] +E AssertionError: assert 'three' in ['one', 'two', 'threes'] + +tests/test_another_pytest.py:17: AssertionError/Users/donjayamanne/anaconda3/lib/python3.6/site-packages/_pytest/nose.py:23: <py._xmlgen.raw object at 0x10a5d04a8>non_parametrized_username = 'three' + + def test_parametrized_username(non_parametrized_username): +> assert non_parametrized_username in ['one', 'two', 'threes'] +E AssertionError: assert 'three' in ['one', 'two', 'threes'] + +tests/test_pytest.py:40: AssertionErrorself = <test_unittest_one.Test_test1 testMethod=test_A> + + def test_A(self): +> self.fail("Not implemented") +E AssertionError: Not implemented + +tests/test_unittest_one.py:8: AssertionErrortests/test_unittest_one.py:12: <py._xmlgen.raw object at 0x10a5d8c50>self = <test_unittest_two.Test_test2 testMethod=test_A2> + + def test_A2(self): +> self.fail("Not implemented") +E AssertionError: Not implemented + +tests/test_unittest_two.py:5: AssertionErrorself = <test_unittest_two.Test_test2 testMethod=test_C2> + + def test_C2(self): +> self.assertEqual(1,2,'Not equal') +E AssertionError: 1 != 2 : Not equal + +tests/test_unittest_two.py:11: AssertionErrorself = <test_unittest_two.Test_test2 testMethod=test_D2> + + def test_D2(self): +> raise ArithmeticError() +E ArithmeticError + +tests/test_unittest_two.py:14: ArithmeticErrorself = <test_unittest_two.Test_test2a testMethod=test_222A2> + + def test_222A2(self): +> self.fail("Not implemented") +E AssertionError: Not implemented + +tests/test_unittest_two.py:19: AssertionErrorself = <unittest_three_test.Test_test3 testMethod=test_A> + + def test_A(self): +> self.fail("Not implemented") +E AssertionError: Not implemented + +tests/unittest_three_test.py:6: AssertionError diff --git a/src/test/serviceRegistry.ts b/src/test/serviceRegistry.ts new file mode 100644 index 000000000000..c536a188c0ea --- /dev/null +++ b/src/test/serviceRegistry.ts @@ -0,0 +1,66 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { Container } from 'inversify'; +import 'reflect-metadata'; +import { Disposable, Memento, OutputChannel } from 'vscode'; +import { BufferDecoder } from '../client/common/process/decoder'; +import { ProcessService } from '../client/common/process/proc'; +import { PythonExecutionFactory } from '../client/common/process/pythonExecutionFactory'; +import { registerTypes as processRegisterTypes } from '../client/common/process/serviceRegistry'; +import { IBufferDecoder, IProcessService, IPythonExecutionFactory } from '../client/common/process/types'; +import { registerTypes as commonRegisterTypes } from '../client/common/serviceRegistry'; +import { GLOBAL_MEMENTO, IDiposableRegistry, IMemento, IOutputChannel, WORKSPACE_MEMENTO } from '../client/common/types'; +import { registerTypes as variableRegisterTypes } from '../client/common/variables/serviceRegistry'; +import { ServiceContainer } from '../client/ioc/container'; +import { ServiceManager } from '../client/ioc/serviceManager'; +import { IServiceContainer, IServiceManager } from '../client/ioc/types'; +import { TEST_OUTPUT_CHANNEL } from '../client/unittests/common/constants'; +import { registerTypes as unittestsRegisterTypes } from '../client/unittests/serviceRegistry'; +import { MockOutputChannel } from './mockClasses'; +import { MockMemento } from './mocks/mementos'; +import { IOriginalProcessService, MockProcessService } from './mocks/proc'; + +export class IocContainer { + public readonly serviceManager: IServiceManager; + public readonly serviceContainer: IServiceContainer; + + private disposables: Disposable[] = []; + + constructor() { + const cont = new Container(); + this.serviceManager = new ServiceManager(cont); + this.serviceContainer = new ServiceContainer(cont); + + this.serviceManager.addSingletonInstance(IServiceContainer, this.serviceContainer); + this.serviceManager.addSingletonInstance(IDiposableRegistry, this.disposables); + this.serviceManager.addSingleton(IMemento, MockMemento, GLOBAL_MEMENTO); + this.serviceManager.addSingleton(IMemento, MockMemento, WORKSPACE_MEMENTO); + + this.serviceManager.addSingletonInstance(IOutputChannel, new MockOutputChannel('Python Test - UnitTests'), TEST_OUTPUT_CHANNEL); + } + + public dispose() { + this.disposables.forEach(disposable => disposable.dispose()); + } + + public registerCommonTypes() { + commonRegisterTypes(this.serviceManager); + } + public registerProcessTypes() { + processRegisterTypes(this.serviceManager); + } + public registerVariableTypes() { + variableRegisterTypes(this.serviceManager); + } + public registerUnitTestTypes() { + unittestsRegisterTypes(this.serviceManager); + } + + public registerMockProcessTypes() { + this.serviceManager.addSingleton(IBufferDecoder, BufferDecoder); + this.serviceManager.addSingleton(IOriginalProcessService, ProcessService); + this.serviceManager.addSingleton(IProcessService, MockProcessService); + this.serviceManager.addSingleton(IPythonExecutionFactory, PythonExecutionFactory); + } +} diff --git a/src/test/textUtils.ts b/src/test/textUtils.ts index d83034e73045..b5d31b6e43f1 100644 --- a/src/test/textUtils.ts +++ b/src/test/textUtils.ts @@ -2,4 +2,4 @@ import { MarkedString } from 'vscode'; export function normalizeMarkedString(content: MarkedString): string { return typeof content === 'string' ? content : content.value; -} \ No newline at end of file +} diff --git a/src/test/unittests/debugger.test.ts b/src/test/unittests/debugger.test.ts index e02fd63422e1..2daba9a848e1 100644 --- a/src/test/unittests/debugger.test.ts +++ b/src/test/unittests/debugger.test.ts @@ -3,20 +3,12 @@ import * as chaiAsPromised from 'chai-as-promised'; import * as path from 'path'; import { ConfigurationTarget } from 'vscode'; import { createDeferred } from '../../client/common/helpers'; -import { BaseTestManager } from '../../client/unittests/common/baseTestManager'; import { CANCELLATION_REASON, CommandSource } from '../../client/unittests/common/constants'; -import { TestCollectionStorageService } from '../../client/unittests/common/storageService'; -import { TestResultsService } from '../../client/unittests/common/testResultsService'; -import { TestsHelper } from '../../client/unittests/common/testUtils'; -import { ITestCollectionStorageService, ITestResultsService, ITestsHelper } from '../../client/unittests/common/types'; -import { TestResultDisplay } from '../../client/unittests/display/main'; -import { TestManager as NosetestManager } from '../../client/unittests/nosetest/main'; -import { TestManager as PytestManager } from '../../client/unittests/pytest/main'; -import { TestManager as UnitTestManager } from '../../client/unittests/unittest/main'; +import { ITestDebugLauncher, ITestManagerFactory, TestProvider } from '../../client/unittests/common/types'; import { deleteDirectory, rootWorkspaceUri, updateSetting } from '../common'; import { initialize, initializeTest, IS_MULTI_ROOT_TEST } from './../initialize'; -import { MockOutputChannel } from './../mockClasses'; import { MockDebugLauncher } from './mocks'; +import { UnitTestIocContainer } from './serviceRegistry'; use(chaiAsPromised); @@ -30,14 +22,8 @@ const defaultUnitTestArgs = [ ]; // tslint:disable-next-line:max-func-body-length -suite('Unit Tests Debugging', () => { - let testManager: BaseTestManager; - let testResultDisplay: TestResultDisplay; - let outChannel: MockOutputChannel; - let storageService: ITestCollectionStorageService; - let resultsService: ITestResultsService; - let mockDebugLauncher: MockDebugLauncher; - let testsHelper: ITestsHelper; +suite('Unit Tests - debugging', () => { + let ioc: UnitTestIocContainer; const configTarget = IS_MULTI_ROOT_TEST ? ConfigurationTarget.WorkspaceFolder : ConfigurationTarget.Workspace; suiteSetup(async function () { // Test disvovery is where the delay is, hence give 10 seconds (as we discover tests at least twice in each test). @@ -49,38 +35,43 @@ suite('Unit Tests Debugging', () => { await updateSetting('unitTest.pyTestArgs', [], rootWorkspaceUri, configTarget); }); setup(async () => { - outChannel = new MockOutputChannel('Python Test Log'); - testResultDisplay = new TestResultDisplay(outChannel); await deleteDirectory(path.join(testFilesPath, '.cache')); await initializeTest(); + initializeDI(); }); teardown(async () => { + ioc.dispose(); await updateSetting('unitTest.unittestArgs', defaultUnitTestArgs, rootWorkspaceUri, configTarget); await updateSetting('unitTest.nosetestArgs', [], rootWorkspaceUri, configTarget); await updateSetting('unitTest.pyTestArgs', [], rootWorkspaceUri, configTarget); - outChannel.dispose(); - mockDebugLauncher.dispose(); - if (testManager) { - testManager.dispose(); - } - testResultDisplay.dispose(); }); - function createTestManagerDepedencies() { - storageService = new TestCollectionStorageService(); - resultsService = new TestResultsService(); - testsHelper = new TestsHelper(); - mockDebugLauncher = new MockDebugLauncher(); + function initializeDI() { + ioc = new UnitTestIocContainer(); + ioc.registerCommonTypes(); + ioc.registerProcessTypes(); + ioc.registerVariableTypes(); + + ioc.registerTestParsers(); + ioc.registerTestVisitors(); + ioc.registerTestDiscoveryServices(); + ioc.registerTestResultsHelper(); + ioc.registerTestStorage(); + ioc.registerTestsHelper(); + ioc.registerTestManagers(); + ioc.registerMockUnitTestSocketServer(); + ioc.serviceManager.addSingleton(ITestDebugLauncher, MockDebugLauncher); } - async function testStartingDebugger() { + async function testStartingDebugger(testProvider: TestProvider) { + const testManager = ioc.serviceContainer.get(ITestManagerFactory)(testProvider, rootWorkspaceUri, testFilesPath); + const mockDebugLauncher = ioc.serviceContainer.get(ITestDebugLauncher); const tests = await testManager.discoverTests(CommandSource.commandPalette, true, true); assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 2, 'Incorrect number of test functions'); assert.equal(tests.testSuites.length, 2, 'Incorrect number of test suites'); const testFunction = [tests.testFunctions[0].testFunction]; - // tslint:disable-next-line:no-floating-promises testManager.runTest(CommandSource.commandPalette, { testFunction }, false, true); const launched = await mockDebugLauncher.launched; assert.isTrue(launched, 'Debugger not launched'); @@ -88,26 +79,22 @@ suite('Unit Tests Debugging', () => { test('Debugger should start (unittest)', async () => { await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_*.py'], rootWorkspaceUri, configTarget); - createTestManagerDepedencies(); - testManager = new UnitTestManager(testFilesPath, outChannel, storageService, resultsService, testsHelper, mockDebugLauncher); - await testStartingDebugger(); + await testStartingDebugger('unittest'); }); test('Debugger should start (pytest)', async () => { await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); - createTestManagerDepedencies(); - testManager = new PytestManager(testFilesPath, outChannel, storageService, resultsService, testsHelper, mockDebugLauncher); - await testStartingDebugger(); + await testStartingDebugger('pytest'); }); test('Debugger should start (nosetest)', async () => { await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); - createTestManagerDepedencies(); - testManager = new NosetestManager(testFilesPath, outChannel, storageService, resultsService, testsHelper, mockDebugLauncher); - await testStartingDebugger(); + await testStartingDebugger('nosetest'); }); - async function testStoppingDebugger() { + async function testStoppingDebugger(testProvider: TestProvider) { + const testManager = ioc.serviceContainer.get(ITestManagerFactory)(testProvider, rootWorkspaceUri, testFilesPath); + const mockDebugLauncher = ioc.serviceContainer.get(ITestDebugLauncher); const tests = await testManager.discoverTests(CommandSource.commandPalette, true, true); assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 2, 'Incorrect number of test functions'); @@ -118,7 +105,6 @@ suite('Unit Tests Debugging', () => { const launched = await mockDebugLauncher.launched; assert.isTrue(launched, 'Debugger not launched'); - // tslint:disable-next-line:no-floating-promises testManager.discoverTests(CommandSource.commandPalette, true, true, true); await expect(runningPromise).to.be.rejectedWith(CANCELLATION_REASON, 'Incorrect reason for ending the debugger'); @@ -126,26 +112,22 @@ suite('Unit Tests Debugging', () => { test('Debugger should stop when user invokes a test discovery (unittest)', async () => { await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_*.py'], rootWorkspaceUri, configTarget); - createTestManagerDepedencies(); - testManager = new UnitTestManager(testFilesPath, outChannel, storageService, resultsService, testsHelper, mockDebugLauncher); - await testStoppingDebugger(); + await testStoppingDebugger('unittest'); }); test('Debugger should stop when user invokes a test discovery (pytest)', async () => { await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); - createTestManagerDepedencies(); - testManager = new PytestManager(testFilesPath, outChannel, storageService, resultsService, testsHelper, mockDebugLauncher); - await testStoppingDebugger(); + await testStoppingDebugger('pytest'); }); test('Debugger should stop when user invokes a test discovery (nosetest)', async () => { await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); - createTestManagerDepedencies(); - testManager = new NosetestManager(testFilesPath, outChannel, storageService, resultsService, testsHelper, mockDebugLauncher); - await testStoppingDebugger(); + await testStoppingDebugger('nosetest'); }); - async function testDebuggerWhenRediscoveringTests() { + async function testDebuggerWhenRediscoveringTests(testProvider: TestProvider) { + const testManager = ioc.serviceContainer.get(ITestManagerFactory)(testProvider, rootWorkspaceUri, testFilesPath); + const mockDebugLauncher = ioc.serviceContainer.get(ITestDebugLauncher); const tests = await testManager.discoverTests(CommandSource.commandPalette, true, true); assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 2, 'Incorrect number of test functions'); @@ -159,7 +141,6 @@ suite('Unit Tests Debugging', () => { const discoveryPromise = testManager.discoverTests(CommandSource.commandPalette, false, true); const deferred = createDeferred(); - // tslint:disable-next-line:no-floating-promises discoveryPromise // tslint:disable-next-line:no-unsafe-any .then(() => deferred.resolve('')) @@ -167,7 +148,6 @@ suite('Unit Tests Debugging', () => { .catch(ex => deferred.reject(ex)); // This promise should never resolve nor reject. - // tslint:disable-next-line:no-floating-promises runningPromise .then(() => 'Debugger stopped when it shouldn\'t have') .catch(() => 'Debugger crashed when it shouldn\'t have') @@ -181,22 +161,16 @@ suite('Unit Tests Debugging', () => { test('Debugger should not stop when test discovery is invoked automatically by extension (unittest)', async () => { await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_*.py'], rootWorkspaceUri, configTarget); - createTestManagerDepedencies(); - testManager = new UnitTestManager(testFilesPath, outChannel, storageService, resultsService, testsHelper, mockDebugLauncher); - await testDebuggerWhenRediscoveringTests(); + await testDebuggerWhenRediscoveringTests('unittest'); }); test('Debugger should not stop when test discovery is invoked automatically by extension (pytest)', async () => { await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); - createTestManagerDepedencies(); - testManager = new PytestManager(testFilesPath, outChannel, storageService, resultsService, testsHelper, mockDebugLauncher); - await testDebuggerWhenRediscoveringTests(); + await testDebuggerWhenRediscoveringTests('pytest'); }); test('Debugger should not stop when test discovery is invoked automatically by extension (nosetest)', async () => { await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); - createTestManagerDepedencies(); - testManager = new NosetestManager(testFilesPath, outChannel, storageService, resultsService, testsHelper, mockDebugLauncher); - await testDebuggerWhenRediscoveringTests(); + await testDebuggerWhenRediscoveringTests('nosetest'); }); }); diff --git a/src/test/unittests/mocks.ts b/src/test/unittests/mocks.ts index 5982f5b94c2b..f724f9174bd2 100644 --- a/src/test/unittests/mocks.ts +++ b/src/test/unittests/mocks.ts @@ -1,10 +1,15 @@ -import { CancellationToken, Disposable, OutputChannel, Uri } from 'vscode'; +import { EventEmitter } from 'events'; +import { injectable } from 'inversify'; +import 'reflect-metadata'; +import { CancellationToken, Disposable, Uri } from 'vscode'; import { createDeferred, Deferred } from '../../client/common/helpers'; import { Product } from '../../client/common/installer'; -import { BaseTestManager } from '../../client/unittests/common/baseTestManager'; +import { IServiceContainer } from '../../client/ioc/types'; import { CANCELLATION_REASON } from '../../client/unittests/common/constants'; -import { ITestCollectionStorageService, ITestDebugLauncher, ITestResultsService, ITestsHelper, Tests, TestsToRun } from '../../client/unittests/common/types'; +import { BaseTestManager } from '../../client/unittests/common/managers/baseTestManager'; +import { ITestDebugLauncher, ITestDiscoveryService, IUnitTestSocketServer, launchOptions, TestDiscoveryOptions, TestProvider, Tests, TestsToRun } from '../../client/unittests/common/types'; +@injectable() export class MockDebugLauncher implements ITestDebugLauncher, Disposable { public get launched(): Promise { return this._launched.promise; @@ -28,32 +33,36 @@ export class MockDebugLauncher implements ITestDebugLauncher, Disposable { public async getPort(resource?: Uri): Promise { return 0; } - public async launchDebugger(rootDirectory: string, testArgs: string[], debugPort: number, token?: CancellationToken, outChannel?: OutputChannel): Promise { + public async launchDebugger(options: launchOptions): Promise { this._launched.resolve(true); // tslint:disable-next-line:no-non-null-assertion - this._token = token!; + this._token = options.token!; this._promise = createDeferred(); // tslint:disable-next-line:no-non-null-assertion - token!.onCancellationRequested(() => { + options.token!.onCancellationRequested(() => { if (this._promise) { this._promise.reject('Mock-User Cancelled'); } }); - return this._promise.promise; + return this._promise.promise as {} as Promise; } public dispose() { this._promise = undefined; } } +@injectable() export class MockTestManagerWithRunningTests extends BaseTestManager { // tslint:disable-next-line:no-any public readonly runnerDeferred = createDeferred(); // tslint:disable-next-line:no-any public readonly discoveryDeferred = createDeferred(); - constructor(testRunnerId: 'nosetest' | 'pytest' | 'unittest', product: Product, rootDirectory: string, - outputChannel: OutputChannel, storageService: ITestCollectionStorageService, resultsService: ITestResultsService, testsHelper: ITestsHelper) { - super('nosetest', product, rootDirectory, outputChannel, storageService, resultsService, testsHelper); + constructor(testProvider: TestProvider, product: Product, workspaceFolder: Uri, rootDirectory: string, + serviceContainer: IServiceContainer) { + super(testProvider, product, workspaceFolder, rootDirectory, serviceContainer); + } + protected getDiscoveryOptions(ignoreCache: boolean) { + return {} as TestDiscoveryOptions; } // tslint:disable-next-line:no-any protected async runTestImpl(tests: Tests, testsToRun?: TestsToRun, runFailedTests?: boolean, debug?: boolean): Promise { @@ -71,3 +80,34 @@ export class MockTestManagerWithRunningTests extends BaseTestManager { return this.discoveryDeferred.promise; } } + +@injectable() +export class MockDiscoveryService implements ITestDiscoveryService { + constructor(private discoverPromise: Promise) { } + public async discoverTests(options: TestDiscoveryOptions): Promise { + return this.discoverPromise; + } +} + +// tslint:disable-next-line:max-classes-per-file +@injectable() +export class MockUnitTestSocketServer extends EventEmitter implements IUnitTestSocketServer { + private results: {}[] = []; + public reset() { + this.removeAllListeners(); + } + public addResults(results: {}[]) { + this.results.push(...results); + } + public async start(): Promise { + this.results.forEach(result => { + this.emit('result', result); + }); + this.results = []; + return 0; + } + // tslint:disable-next-line:no-empty + public stop(): void { } + // tslint:disable-next-line:no-empty + public dispose() { } +} diff --git a/src/test/unittests/nosetest.disovery.test.ts b/src/test/unittests/nosetest.disovery.test.ts new file mode 100644 index 000000000000..794ec5f31901 --- /dev/null +++ b/src/test/unittests/nosetest.disovery.test.ts @@ -0,0 +1,145 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import * as assert from 'assert'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as vscode from 'vscode'; +import { IProcessService } from '../../client/common/process/types'; +import { CommandSource } from '../../client/unittests/common/constants'; +import { ITestManagerFactory, Tests } from '../../client/unittests/common/types'; +import { rootWorkspaceUri, updateSetting } from '../common'; +import { MockProcessService } from '../mocks/proc'; +import { initialize, initializeTest, IS_MULTI_ROOT_TEST } from './../initialize'; +import { UnitTestIocContainer } from './serviceRegistry'; + +const PYTHON_FILES_PATH = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles'); +const UNITTEST_TEST_FILES_PATH = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles', 'noseFiles'); +const UNITTEST_SINGLE_TEST_FILE_PATH = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles', 'single'); +const filesToDelete = [ + path.join(UNITTEST_TEST_FILES_PATH, '.noseids'), + path.join(UNITTEST_SINGLE_TEST_FILE_PATH, '.noseids') +]; + +// tslint:disable-next-line:max-func-body-length +suite('Unit Tests - nose - discovery with mocked process output', () => { + let ioc: UnitTestIocContainer; + const configTarget = IS_MULTI_ROOT_TEST ? vscode.ConfigurationTarget.WorkspaceFolder : vscode.ConfigurationTarget.Workspace; + + suiteSetup(async () => { + filesToDelete.forEach(file => { + if (fs.existsSync(file)) { + fs.unlinkSync(file); + } + }); + await updateSetting('unitTest.nosetestArgs', [], rootWorkspaceUri, configTarget); + await initialize(); + }); + suiteTeardown(async () => { + await updateSetting('unitTest.nosetestArgs', [], rootWorkspaceUri, configTarget); + filesToDelete.forEach(file => { + if (fs.existsSync(file)) { + fs.unlinkSync(file); + } + }); + }); + setup(async () => { + await initializeTest(); + initializeDI(); + }); + teardown(async () => { + ioc.dispose(); + await updateSetting('unitTest.nosetestArgs', [], rootWorkspaceUri, configTarget); + }); + + function initializeDI() { + ioc = new UnitTestIocContainer(); + ioc.registerCommonTypes(); + ioc.registerUnitTestTypes(); + ioc.registerVariableTypes(); + + ioc.registerMockProcessTypes(); + } + + function injectTestDiscoveryOutput(outputFileName: string) { + const procService = ioc.serviceContainer.get(IProcessService); + procService.onExecObservable((file, args, options, callback) => { + if (args.indexOf('--collect-only') >= 0) { + let out = fs.readFileSync(path.join(UNITTEST_TEST_FILES_PATH, outputFileName), 'utf8'); + // Value in the test files. + out = out.replace(/\/Users\/donjayamanne\/.vscode\/extensions\/pythonVSCode\/src\/test\/pythonFiles/g, PYTHON_FILES_PATH); + callback({ + out, + source: 'stdout' + }); + } + }); + } + + test('Discover Tests (single test file)', async () => { + injectTestDiscoveryOutput('one.output'); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_SINGLE_TEST_FILE_PATH); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); + assert.equal(tests.testFunctions.length, 6, 'Incorrect number of test functions'); + assert.equal(tests.testSuites.length, 2, 'Incorrect number of test suites'); + assert.equal(tests.testFiles.some(t => t.name === path.join('tests', 'test_one.py') && t.nameToRun === t.name), true, 'Test File not found'); + }); + + test('Check that nameToRun in testSuites has class name after : (single test file)', async () => { + injectTestDiscoveryOutput('two.output'); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_SINGLE_TEST_FILE_PATH); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); + assert.equal(tests.testFunctions.length, 6, 'Incorrect number of test functions'); + assert.equal(tests.testSuites.length, 2, 'Incorrect number of test suites'); + assert.equal(tests.testSuites.every(t => t.testSuite.name === t.testSuite.nameToRun.split(':')[1]), true, 'Suite name does not match class name'); + }); + + function lookForTestFile(tests: Tests, testFile: string) { + const found = tests.testFiles.some(t => t.name === testFile && t.nameToRun === t.name); + assert.equal(found, true, `Test File not found '${testFile}'`); + } + test('Discover Tests (-m=test)', async () => { + injectTestDiscoveryOutput('three.output'); + await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + assert.equal(tests.testFiles.length, 5, 'Incorrect number of test files'); + assert.equal(tests.testFunctions.length, 16, 'Incorrect number of test functions'); + assert.equal(tests.testSuites.length, 6, 'Incorrect number of test suites'); + lookForTestFile(tests, path.join('tests', 'test_unittest_one.py')); + lookForTestFile(tests, path.join('tests', 'test_unittest_two.py')); + lookForTestFile(tests, path.join('tests', 'unittest_three_test.py')); + lookForTestFile(tests, path.join('tests', 'test4.py')); + lookForTestFile(tests, 'test_root.py'); + }); + + test('Discover Tests (-w=specific -m=tst)', async () => { + injectTestDiscoveryOutput('four.output'); + await updateSetting('unitTest.nosetestArgs', ['-w', 'specific', '-m', 'tst'], rootWorkspaceUri, configTarget); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); + assert.equal(tests.testFunctions.length, 6, 'Incorrect number of test functions'); + assert.equal(tests.testSuites.length, 2, 'Incorrect number of test suites'); + lookForTestFile(tests, path.join('specific', 'tst_unittest_one.py')); + lookForTestFile(tests, path.join('specific', 'tst_unittest_two.py')); + }); + + test('Discover Tests (-m=test_)', async () => { + injectTestDiscoveryOutput('five.output'); + await updateSetting('unitTest.nosetestArgs', ['-m', 'test_'], rootWorkspaceUri, configTarget); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + assert.equal(tests.testFiles.length, 1, 'Incorrect number of test files'); + assert.equal(tests.testFunctions.length, 3, 'Incorrect number of test functions'); + assert.equal(tests.testSuites.length, 1, 'Incorrect number of test suites'); + lookForTestFile(tests, 'test_root.py'); + }); +}); diff --git a/src/test/unittests/nosetest.run.test.ts b/src/test/unittests/nosetest.run.test.ts new file mode 100644 index 000000000000..1fc34a684c34 --- /dev/null +++ b/src/test/unittests/nosetest.run.test.ts @@ -0,0 +1,178 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import * as assert from 'assert'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as vscode from 'vscode'; +import { IProcessService } from '../../client/common/process/types'; +import { CommandSource } from '../../client/unittests/common/constants'; +import { ITestManagerFactory, TestsToRun } from '../../client/unittests/common/types'; +import { rootWorkspaceUri, updateSetting } from '../common'; +import { MockProcessService } from '../mocks/proc'; +import { initialize, initializeTest, IS_MULTI_ROOT_TEST } from './../initialize'; +import { UnitTestIocContainer } from './serviceRegistry'; + +const UNITTEST_TEST_FILES_PATH = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles', 'noseFiles'); +const UNITTEST_SINGLE_TEST_FILE_PATH = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles', 'single'); +const filesToDelete = [ + path.join(UNITTEST_TEST_FILES_PATH, '.noseids'), + path.join(UNITTEST_SINGLE_TEST_FILE_PATH, '.noseids') +]; + +// tslint:disable-next-line:max-func-body-length +suite('Unit Tests - nose - run against actual python process', () => { + let ioc: UnitTestIocContainer; + const configTarget = IS_MULTI_ROOT_TEST ? vscode.ConfigurationTarget.WorkspaceFolder : vscode.ConfigurationTarget.Workspace; + + suiteSetup(async () => { + filesToDelete.forEach(file => { + if (fs.existsSync(file)) { + fs.unlinkSync(file); + } + }); + await updateSetting('unitTest.nosetestArgs', [], rootWorkspaceUri, configTarget); + await initialize(); + }); + suiteTeardown(async () => { + await updateSetting('unitTest.nosetestArgs', [], rootWorkspaceUri, configTarget); + filesToDelete.forEach(file => { + if (fs.existsSync(file)) { + fs.unlinkSync(file); + } + }); + }); + setup(async () => { + await initializeTest(); + initializeDI(); + }); + teardown(async () => { + ioc.dispose(); + await updateSetting('unitTest.nosetestArgs', [], rootWorkspaceUri, configTarget); + }); + + function initializeDI() { + ioc = new UnitTestIocContainer(); + ioc.registerCommonTypes(); + ioc.registerUnitTestTypes(); + ioc.registerVariableTypes(); + + ioc.registerMockProcessTypes(); + } + + function injectTestDiscoveryOutput(outputFileName: string) { + const procService = ioc.serviceContainer.get(IProcessService); + procService.onExecObservable((file, args, options, callback) => { + if (args.indexOf('--collect-only') >= 0) { + callback({ + out: fs.readFileSync(path.join(UNITTEST_TEST_FILES_PATH, outputFileName), 'utf8'), + source: 'stdout' + }); + } + }); + } + + function injectTestRunOutput(outputFileName: string, failedOutput: boolean = false) { + const procService = ioc.serviceContainer.get(IProcessService); + procService.onExecObservable((file, args, options, callback) => { + if (failedOutput && args.indexOf('--failed') === -1) { + return; + } + + const index = args.findIndex(arg => arg.startsWith('--xunit-file=')); + if (index >= 0) { + const fileName = args[index].substr('--xunit-file='.length); + const contents = fs.readFileSync(path.join(UNITTEST_TEST_FILES_PATH, outputFileName), 'utf8'); + fs.writeFileSync(fileName, contents, 'utf8'); + callback({ out: '', source: 'stdout' }); + } + }); + } + + test('Run Tests', async () => { + injectTestDiscoveryOutput('run.one.output'); + injectTestRunOutput('run.one.result'); + await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); + const results = await testManager.runTest(CommandSource.ui); + assert.equal(results.summary.errors, 1, 'Errors'); + assert.equal(results.summary.failures, 7, 'Failures'); + assert.equal(results.summary.passed, 6, 'Passed'); + assert.equal(results.summary.skipped, 2, 'skipped'); + }); + + test('Run Failed Tests', async () => { + injectTestDiscoveryOutput('run.two.output'); + injectTestRunOutput('run.two.result'); + injectTestRunOutput('run.two.again.result', true); + await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); + let results = await testManager.runTest(CommandSource.ui); + assert.equal(results.summary.errors, 1, 'Errors'); + assert.equal(results.summary.failures, 7, 'Failures'); + assert.equal(results.summary.passed, 6, 'Passed'); + assert.equal(results.summary.skipped, 2, 'skipped'); + + results = await testManager.runTest(CommandSource.ui, undefined, true); + assert.equal(results.summary.errors, 1, 'Errors again'); + assert.equal(results.summary.failures, 7, 'Failures again'); + assert.equal(results.summary.passed, 0, 'Passed again'); + assert.equal(results.summary.skipped, 0, 'skipped again'); + }); + + test('Run Specific Test File', async () => { + injectTestDiscoveryOutput('run.three.output'); + injectTestRunOutput('run.three.result'); + await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + const testFileToRun = tests.testFiles.find(t => t.fullPath.endsWith('test_root.py')); + assert.ok(testFileToRun, 'Test file not found'); + // tslint:disable-next-line:no-non-null-assertion + const testFile: TestsToRun = { testFile: [testFileToRun!], testFolder: [], testFunction: [], testSuite: [] }; + const results = await testManager.runTest(CommandSource.ui, testFile); + assert.equal(results.summary.errors, 0, 'Errors'); + assert.equal(results.summary.failures, 1, 'Failures'); + assert.equal(results.summary.passed, 1, 'Passed'); + assert.equal(results.summary.skipped, 1, 'skipped'); + }); + + test('Run Specific Test Suite', async () => { + injectTestDiscoveryOutput('run.four.output'); + injectTestRunOutput('run.four.result'); + await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + const testSuiteToRun = tests.testSuites.find(s => s.xmlClassName === 'test_root.Test_Root_test1'); + assert.ok(testSuiteToRun, 'Test suite not found'); + // tslint:disable-next-line:no-non-null-assertion + const testSuite: TestsToRun = { testFile: [], testFolder: [], testFunction: [], testSuite: [testSuiteToRun!.testSuite] }; + const results = await testManager.runTest(CommandSource.ui, testSuite); + assert.equal(results.summary.errors, 0, 'Errors'); + assert.equal(results.summary.failures, 1, 'Failures'); + assert.equal(results.summary.passed, 1, 'Passed'); + assert.equal(results.summary.skipped, 1, 'skipped'); + }); + + test('Run Specific Test Function', async () => { + injectTestDiscoveryOutput('run.five.output'); + injectTestRunOutput('run.five.result'); + await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + const testFnToRun = tests.testFunctions.find(f => f.xmlClassName === 'test_root.Test_Root_test1'); + assert.ok(testFnToRun, 'Test function not found'); + // tslint:disable-next-line:no-non-null-assertion + const testFn: TestsToRun = { testFile: [], testFolder: [], testFunction: [testFnToRun!.testFunction], testSuite: [] }; + const results = await testManager.runTest(CommandSource.ui, testFn); + assert.equal(results.summary.errors, 0, 'Errors'); + assert.equal(results.summary.failures, 1, 'Failures'); + assert.equal(results.summary.passed, 0, 'Passed'); + assert.equal(results.summary.skipped, 0, 'skipped'); + }); +}); diff --git a/src/test/unittests/nosetest.test.ts b/src/test/unittests/nosetest.test.ts index c932a1950332..6e7d7439351b 100644 --- a/src/test/unittests/nosetest.test.ts +++ b/src/test/unittests/nosetest.test.ts @@ -3,16 +3,10 @@ import * as fs from 'fs'; import * as path from 'path'; import * as vscode from 'vscode'; import { CommandSource } from '../../client/unittests/common/constants'; -import { TestCollectionStorageService } from '../../client/unittests/common/storageService'; -import { TestResultsService } from '../../client/unittests/common/testResultsService'; -import { TestsHelper } from '../../client/unittests/common/testUtils'; -import { ITestCollectionStorageService, ITestResultsService, ITestsHelper, Tests, TestsToRun } from '../../client/unittests/common/types'; -import { TestResultDisplay } from '../../client/unittests/display/main'; -import * as nose from '../../client/unittests/nosetest/main'; +import { ITestManagerFactory } from '../../client/unittests/common/types'; import { rootWorkspaceUri, updateSetting } from '../common'; import { initialize, initializeTest, IS_MULTI_ROOT_TEST } from './../initialize'; -import { MockOutputChannel } from './../mockClasses'; -import { MockDebugLauncher } from './mocks'; +import { UnitTestIocContainer } from './serviceRegistry'; const UNITTEST_TEST_FILES_PATH = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles', 'noseFiles'); const UNITTEST_SINGLE_TEST_FILE_PATH = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles', 'single'); @@ -22,15 +16,9 @@ const filesToDelete = [ ]; // tslint:disable-next-line:max-func-body-length -suite('Unit Tests (nosetest)', () => { +suite('Unit Tests - nose - discovery against actual python process', () => { + let ioc: UnitTestIocContainer; const configTarget = IS_MULTI_ROOT_TEST ? vscode.ConfigurationTarget.WorkspaceFolder : vscode.ConfigurationTarget.Workspace; - const rootDirectory = UNITTEST_TEST_FILES_PATH; - let testManager: nose.TestManager; - let testResultDisplay: TestResultDisplay; - let outChannel: vscode.OutputChannel; - let storageService: ITestCollectionStorageService; - let resultsService: ITestResultsService; - let testsHelper: ITestsHelper; suiteSetup(async () => { filesToDelete.forEach(file => { @@ -50,148 +38,29 @@ suite('Unit Tests (nosetest)', () => { }); }); setup(async () => { - outChannel = new MockOutputChannel('Python Test Log'); - testResultDisplay = new TestResultDisplay(outChannel); await initializeTest(); + initializeDI(); }); teardown(async () => { - outChannel.dispose(); - testManager.dispose(); - testResultDisplay.dispose(); + ioc.dispose(); await updateSetting('unitTest.nosetestArgs', [], rootWorkspaceUri, configTarget); }); - function createTestManager(rootDir: string = rootDirectory) { - storageService = new TestCollectionStorageService(); - resultsService = new TestResultsService(); - testsHelper = new TestsHelper(); - testManager = new nose.TestManager(rootDir, outChannel, storageService, resultsService, testsHelper, new MockDebugLauncher()); + + function initializeDI() { + ioc = new UnitTestIocContainer(); + ioc.registerCommonTypes(); + ioc.registerProcessTypes(); + ioc.registerUnitTestTypes(); + ioc.registerVariableTypes(); } test('Discover Tests (single test file)', async () => { - createTestManager(UNITTEST_SINGLE_TEST_FILE_PATH); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_SINGLE_TEST_FILE_PATH); const tests = await testManager.discoverTests(CommandSource.ui, true, true); assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 6, 'Incorrect number of test functions'); assert.equal(tests.testSuites.length, 2, 'Incorrect number of test suites'); assert.equal(tests.testFiles.some(t => t.name === path.join('tests', 'test_one.py') && t.nameToRun === t.name), true, 'Test File not found'); }); - - test('Check that nameToRun in testSuites has class name after : (single test file)', async () => { - createTestManager(UNITTEST_SINGLE_TEST_FILE_PATH); - const tests = await testManager.discoverTests(CommandSource.ui, true, true); - assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); - assert.equal(tests.testFunctions.length, 6, 'Incorrect number of test functions'); - assert.equal(tests.testSuites.length, 2, 'Incorrect number of test suites'); - assert.equal(tests.testSuites.every(t => t.testSuite.name === t.testSuite.nameToRun.split(':')[1]), true, 'Suite name does not match class name'); - }); - - function lookForTestFile(tests: Tests, testFile: string) { - const found = tests.testFiles.some(t => t.name === testFile && t.nameToRun === t.name); - assert.equal(found, true, `Test File not found '${testFile}'`); - } - test('Discover Tests (-m=test)', async () => { - await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); - createTestManager(); - const tests = await testManager.discoverTests(CommandSource.ui, true, true); - assert.equal(tests.testFiles.length, 5, 'Incorrect number of test files'); - assert.equal(tests.testFunctions.length, 16, 'Incorrect number of test functions'); - assert.equal(tests.testSuites.length, 6, 'Incorrect number of test suites'); - lookForTestFile(tests, path.join('tests', 'test_unittest_one.py')); - lookForTestFile(tests, path.join('tests', 'test_unittest_two.py')); - lookForTestFile(tests, path.join('tests', 'unittest_three_test.py')); - lookForTestFile(tests, path.join('tests', 'test4.py')); - lookForTestFile(tests, 'test_root.py'); - }); - - test('Discover Tests (-w=specific -m=tst)', async () => { - await updateSetting('unitTest.nosetestArgs', ['-w', 'specific', '-m', 'tst'], rootWorkspaceUri, configTarget); - createTestManager(); - const tests = await testManager.discoverTests(CommandSource.ui, true, true); - assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); - assert.equal(tests.testFunctions.length, 6, 'Incorrect number of test functions'); - assert.equal(tests.testSuites.length, 2, 'Incorrect number of test suites'); - lookForTestFile(tests, path.join('specific', 'tst_unittest_one.py')); - lookForTestFile(tests, path.join('specific', 'tst_unittest_two.py')); - }); - - test('Discover Tests (-m=test_)', async () => { - await updateSetting('unitTest.nosetestArgs', ['-m', 'test_'], rootWorkspaceUri, configTarget); - createTestManager(); - const tests = await testManager.discoverTests(CommandSource.ui, true, true); - assert.equal(tests.testFiles.length, 1, 'Incorrect number of test files'); - assert.equal(tests.testFunctions.length, 3, 'Incorrect number of test functions'); - assert.equal(tests.testSuites.length, 1, 'Incorrect number of test suites'); - lookForTestFile(tests, 'test_root.py'); - }); - - test('Run Tests', async () => { - await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); - createTestManager(); - const results = await testManager.runTest(CommandSource.ui); - assert.equal(results.summary.errors, 1, 'Errors'); - assert.equal(results.summary.failures, 7, 'Failures'); - assert.equal(results.summary.passed, 6, 'Passed'); - assert.equal(results.summary.skipped, 2, 'skipped'); - }); - - test('Run Failed Tests', async () => { - await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); - createTestManager(); - let results = await testManager.runTest(CommandSource.ui); - assert.equal(results.summary.errors, 1, 'Errors'); - assert.equal(results.summary.failures, 7, 'Failures'); - assert.equal(results.summary.passed, 6, 'Passed'); - assert.equal(results.summary.skipped, 2, 'skipped'); - - results = await testManager.runTest(CommandSource.ui, undefined, true); - assert.equal(results.summary.errors, 1, 'Errors again'); - assert.equal(results.summary.failures, 7, 'Failures again'); - assert.equal(results.summary.passed, 0, 'Passed again'); - assert.equal(results.summary.skipped, 0, 'skipped again'); - }); - - test('Run Specific Test File', async () => { - await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); - createTestManager(); - const tests = await testManager.discoverTests(CommandSource.ui, true, true); - const testFileToRun = tests.testFiles.find(t => t.fullPath.endsWith('test_root.py')); - assert.ok(testFileToRun, 'Test file not found'); - // tslint:disable-next-line:no-non-null-assertion - const testFile: TestsToRun = { testFile: [testFileToRun!], testFolder: [], testFunction: [], testSuite: [] }; - const results = await testManager.runTest(CommandSource.ui, testFile); - assert.equal(results.summary.errors, 0, 'Errors'); - assert.equal(results.summary.failures, 1, 'Failures'); - assert.equal(results.summary.passed, 1, 'Passed'); - assert.equal(results.summary.skipped, 1, 'skipped'); - }); - - test('Run Specific Test Suite', async () => { - await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); - createTestManager(); - const tests = await testManager.discoverTests(CommandSource.ui, true, true); - const testSuiteToRun = tests.testSuites.find(s => s.xmlClassName === 'test_root.Test_Root_test1'); - assert.ok(testSuiteToRun, 'Test suite not found'); - // tslint:disable-next-line:no-non-null-assertion - const testSuite: TestsToRun = { testFile: [], testFolder: [], testFunction: [], testSuite: [testSuiteToRun!.testSuite] }; - const results = await testManager.runTest(CommandSource.ui, testSuite); - assert.equal(results.summary.errors, 0, 'Errors'); - assert.equal(results.summary.failures, 1, 'Failures'); - assert.equal(results.summary.passed, 1, 'Passed'); - assert.equal(results.summary.skipped, 1, 'skipped'); - }); - - test('Run Specific Test Function', async () => { - await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); - createTestManager(); - const tests = await testManager.discoverTests(CommandSource.ui, true, true); - const testFnToRun = tests.testFunctions.find(f => f.xmlClassName === 'test_root.Test_Root_test1'); - assert.ok(testFnToRun, 'Test function not found'); - // tslint:disable-next-line:no-non-null-assertion - const testFn: TestsToRun = { testFile: [], testFolder: [], testFunction: [testFnToRun!.testFunction], testSuite: [] }; - const results = await testManager.runTest(CommandSource.ui, testFn); - assert.equal(results.summary.errors, 0, 'Errors'); - assert.equal(results.summary.failures, 1, 'Failures'); - assert.equal(results.summary.passed, 0, 'Passed'); - assert.equal(results.summary.skipped, 0, 'skipped'); - }); }); diff --git a/src/test/unittests/pytest.discovery.test.ts b/src/test/unittests/pytest.discovery.test.ts new file mode 100644 index 000000000000..9f073f8440bc --- /dev/null +++ b/src/test/unittests/pytest.discovery.test.ts @@ -0,0 +1,268 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import * as assert from 'assert'; +import * as path from 'path'; +import * as vscode from 'vscode'; +import { IProcessService } from '../../client/common/process/types'; +import { CommandSource } from '../../client/unittests/common/constants'; +import { ITestManagerFactory } from '../../client/unittests/common/types'; +import { rootWorkspaceUri, updateSetting } from '../common'; +import { MockProcessService } from '../mocks/proc'; +import { initialize, initializeTest, IS_MULTI_ROOT_TEST } from './../initialize'; +import { UnitTestIocContainer } from './serviceRegistry'; + +const UNITTEST_TEST_FILES_PATH = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles', 'standard'); +const UNITTEST_SINGLE_TEST_FILE_PATH = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles', 'single'); +const UNITTEST_TEST_FILES_PATH_WITH_CONFIGS = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles', 'unitestsWithConfigs'); +const unitTestTestFilesCwdPath = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles', 'cwd', 'src'); + +// tslint:disable-next-line:max-func-body-length +suite('Unit Tests - pytest - discovery with mocked process output', () => { + let ioc: UnitTestIocContainer; + const configTarget = IS_MULTI_ROOT_TEST ? vscode.ConfigurationTarget.WorkspaceFolder : vscode.ConfigurationTarget.Workspace; + suiteSetup(async () => { + await initialize(); + await updateSetting('unitTest.pyTestArgs', [], rootWorkspaceUri, configTarget); + }); + setup(async () => { + await initializeTest(); + initializeDI(); + }); + teardown(async () => { + ioc.dispose(); + await updateSetting('unitTest.pyTestArgs', [], rootWorkspaceUri, configTarget); + }); + + function initializeDI() { + ioc = new UnitTestIocContainer(); + ioc.registerCommonTypes(); + ioc.registerUnitTestTypes(); + ioc.registerVariableTypes(); + + // Mocks. + ioc.registerMockProcessTypes(); + } + + function injectTestDiscoveryOutput(output: string) { + const procService = ioc.serviceContainer.get(IProcessService); + procService.onExecObservable((file, args, options, callback) => { + if (args.indexOf('--collect-only') >= 0) { + callback({ + out: output, + source: 'stdout' + }); + } + }); + } + + test('Discover Tests (single test file)', async () => { + // tslint:disable-next-line:no-multiline-string + injectTestDiscoveryOutput(` + ============================= test session starts ============================== + platform darwin -- Python 3.6.2, pytest-3.3.0, py-1.5.2, pluggy-0.6.0 + rootdir: /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single, inifile: + plugins: pylama-7.4.3 + collected 6 items + + + + + + + + + + + + ========================= no tests ran in 0.03 seconds ========================= + `); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('pytest', rootWorkspaceUri, UNITTEST_SINGLE_TEST_FILE_PATH); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); + assert.equal(tests.testFunctions.length, 6, 'Incorrect number of test functions'); + assert.equal(tests.testSuites.length, 2, 'Incorrect number of test suites'); + assert.equal(tests.testFiles.some(t => t.name === 'tests/test_one.py' && t.nameToRun === t.name), true, 'Test File not found'); + assert.equal(tests.testFiles.some(t => t.name === 'test_root.py' && t.nameToRun === t.name), true, 'Test File not found'); + }); + + test('Discover Tests (pattern = test_)', async () => { + // tslint:disable-next-line:no-multiline-string + injectTestDiscoveryOutput(` + ============================= test session starts ============================== + platform darwin -- Python 3.6.2, pytest-3.3.0, py-1.5.2, pluggy-0.6.0 + rootdir: /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/standard, inifile: + plugins: pylama-7.4.3 + collected 29 items + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ========================= no tests ran in 0.05 seconds ========================= + " + PROBLEMS + OUTPUT + DEBUG CONSOLE + TERMINAL + + + W + + Find + + `); + await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('pytest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + assert.equal(tests.testFiles.length, 6, 'Incorrect number of test files'); + assert.equal(tests.testFunctions.length, 29, 'Incorrect number of test functions'); + assert.equal(tests.testSuites.length, 8, 'Incorrect number of test suites'); + assert.equal(tests.testFiles.some(t => t.name === 'tests/test_unittest_one.py' && t.nameToRun === t.name), true, 'Test File not found'); + assert.equal(tests.testFiles.some(t => t.name === 'tests/test_unittest_two.py' && t.nameToRun === t.name), true, 'Test File not found'); + assert.equal(tests.testFiles.some(t => t.name === 'tests/unittest_three_test.py' && t.nameToRun === t.name), true, 'Test File not found'); + assert.equal(tests.testFiles.some(t => t.name === 'tests/test_pytest.py' && t.nameToRun === t.name), true, 'Test File not found'); + assert.equal(tests.testFiles.some(t => t.name === 'tests/test_another_pytest.py' && t.nameToRun === t.name), true, 'Test File not found'); + assert.equal(tests.testFiles.some(t => t.name === 'test_root.py' && t.nameToRun === t.name), true, 'Test File not found'); + }); + + test('Discover Tests (pattern = _test)', async () => { + // tslint:disable-next-line:no-multiline-string + injectTestDiscoveryOutput(` + ============================= test session starts ============================== + platform darwin -- Python 3.6.2, pytest-3.3.0, py-1.5.2, pluggy-0.6.0 + rootdir: /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/standard, inifile: + plugins: pylama-7.4.3 + collected 29 items + + + + + + ============================= 27 tests deselected ============================== + ======================== 27 deselected in 0.05 seconds ========================= + `); + await updateSetting('unitTest.pyTestArgs', ['-k=_test.py'], rootWorkspaceUri, configTarget); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('pytest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + assert.equal(tests.testFiles.length, 1, 'Incorrect number of test files'); + assert.equal(tests.testFunctions.length, 2, 'Incorrect number of test functions'); + assert.equal(tests.testSuites.length, 1, 'Incorrect number of test suites'); + assert.equal(tests.testFiles.some(t => t.name === 'tests/unittest_three_test.py' && t.nameToRun === t.name), true, 'Test File not found'); + }); + + test('Discover Tests (with config)', async () => { + // tslint:disable-next-line:no-multiline-string + injectTestDiscoveryOutput(` + ============================= test session starts ============================== + platform darwin -- Python 3.6.2, pytest-3.3.0, py-1.5.2, pluggy-0.6.0 + rootdir: /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/unitestsWithConfigs, inifile: pytest.ini + plugins: pylama-7.4.3 + collected 14 items + + + + + + + + + + + + + + + + + + + + + + + + + ========================= no tests ran in 0.04 seconds ========================= + `); + await updateSetting('unitTest.pyTestArgs', [], rootWorkspaceUri, configTarget); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('pytest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH_WITH_CONFIGS); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); + assert.equal(tests.testFunctions.length, 14, 'Incorrect number of test functions'); + assert.equal(tests.testSuites.length, 4, 'Incorrect number of test suites'); + assert.equal(tests.testFiles.some(t => t.name === 'other/test_unittest_one.py' && t.nameToRun === t.name), true, 'Test File not found'); + assert.equal(tests.testFiles.some(t => t.name === 'other/test_pytest.py' && t.nameToRun === t.name), true, 'Test File not found'); + }); + + test('Setting cwd should return tests', async () => { + // tslint:disable-next-line:no-multiline-string + injectTestDiscoveryOutput(` + ============================= test session starts ============================== + platform darwin -- Python 3.6.2, pytest-3.3.0, py-1.5.2, pluggy-0.6.0 + rootdir: /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/cwd/src, inifile: + plugins: pylama-7.4.3 + collected 1 item + + + + + ========================= no tests ran in 0.02 seconds ========================= + `); + await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('pytest', rootWorkspaceUri, unitTestTestFilesCwdPath); + + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + assert.equal(tests.testFiles.length, 1, 'Incorrect number of test files'); + assert.equal(tests.testFolders.length, 1, 'Incorrect number of test folders'); + assert.equal(tests.testFunctions.length, 1, 'Incorrect number of test functions'); + assert.equal(tests.testSuites.length, 1, 'Incorrect number of test suites'); + }); +}); diff --git a/src/test/unittests/pytest.run.test.ts b/src/test/unittests/pytest.run.test.ts new file mode 100644 index 000000000000..b6695db63311 --- /dev/null +++ b/src/test/unittests/pytest.run.test.ts @@ -0,0 +1,161 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import * as assert from 'assert'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as vscode from 'vscode'; +import { IProcessService } from '../../client/common/process/types'; +import { CommandSource } from '../../client/unittests/common/constants'; +import { ITestManagerFactory, TestFile, TestsToRun } from '../../client/unittests/common/types'; +import { rootWorkspaceUri, updateSetting } from '../common'; +import { MockProcessService } from '../mocks/proc'; +import { initialize, initializeTest, IS_MULTI_ROOT_TEST } from './../initialize'; +import { UnitTestIocContainer } from './serviceRegistry'; + +const UNITTEST_TEST_FILES_PATH = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles', 'standard'); +const PYTEST_RESULTS_PATH = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles', 'pytestFiles', 'results'); + +// tslint:disable-next-line:max-func-body-length +suite('Unit Tests - pytest - run with mocked process output', () => { + let ioc: UnitTestIocContainer; + const configTarget = IS_MULTI_ROOT_TEST ? vscode.ConfigurationTarget.WorkspaceFolder : vscode.ConfigurationTarget.Workspace; + suiteSetup(async () => { + await initialize(); + await updateSetting('unitTest.pyTestArgs', [], rootWorkspaceUri, configTarget); + }); + setup(async () => { + await initializeTest(); + initializeDI(); + }); + teardown(async () => { + ioc.dispose(); + await updateSetting('unitTest.pyTestArgs', [], rootWorkspaceUri, configTarget); + }); + + function initializeDI() { + ioc = new UnitTestIocContainer(); + ioc.registerCommonTypes(); + ioc.registerUnitTestTypes(); + ioc.registerVariableTypes(); + + // Mocks. + ioc.registerMockProcessTypes(); + } + + function injectTestDiscoveryOutput(outputFileName: string) { + const procService = ioc.serviceContainer.get(IProcessService); + procService.onExecObservable((file, args, options, callback) => { + if (args.indexOf('--collect-only') >= 0) { + callback({ + out: fs.readFileSync(path.join(PYTEST_RESULTS_PATH, outputFileName), 'utf8'), + source: 'stdout' + }); + } + }); + } + + function injectTestRunOutput(outputFileName: string, failedOutput: boolean = false) { + const procService = ioc.serviceContainer.get(IProcessService); + procService.onExecObservable((file, args, options, callback) => { + if (failedOutput && args.indexOf('--last-failed') === -1) { + return; + } + + const index = args.findIndex(arg => arg.startsWith('--junitxml=')); + if (index >= 0) { + const fileName = args[index].substr('--junitxml='.length); + const contents = fs.readFileSync(path.join(PYTEST_RESULTS_PATH, outputFileName), 'utf8'); + fs.writeFileSync(fileName, contents, 'utf8'); + callback({ out: '', source: 'stdout' }); + } + }); + } + + test('Run Tests', async () => { + injectTestDiscoveryOutput('one.output'); + injectTestRunOutput('one.xml'); + await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('pytest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); + const results = await testManager.runTest(CommandSource.ui); + assert.equal(results.summary.errors, 0, 'Errors'); + assert.equal(results.summary.failures, 9, 'Failures'); + assert.equal(results.summary.passed, 17, 'Passed'); + assert.equal(results.summary.skipped, 3, 'skipped'); + }); + + test('Run Failed Tests', async () => { + injectTestDiscoveryOutput('two.output'); + injectTestRunOutput('two.xml'); + injectTestRunOutput('two.again.xml', true); + await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('pytest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); + let results = await testManager.runTest(CommandSource.ui); + assert.equal(results.summary.errors, 0, 'Errors'); + assert.equal(results.summary.failures, 9, 'Failures'); + assert.equal(results.summary.passed, 17, 'Passed'); + assert.equal(results.summary.skipped, 3, 'skipped'); + + results = await testManager.runTest(CommandSource.ui, undefined, true); + assert.equal(results.summary.errors, 0, 'Failed Errors'); + assert.equal(results.summary.failures, 9, 'Failed Failures'); + assert.equal(results.summary.passed, 0, 'Failed Passed'); + assert.equal(results.summary.skipped, 0, 'Failed skipped'); + }); + + test('Run Specific Test File', async () => { + injectTestDiscoveryOutput('three.output'); + injectTestRunOutput('three.xml'); + await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('pytest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); + await testManager.discoverTests(CommandSource.ui, true, true); + const testFile: TestFile = { + fullPath: path.join(UNITTEST_TEST_FILES_PATH, 'tests', 'test_another_pytest.py'), + name: 'tests/test_another_pytest.py', + nameToRun: 'tests/test_another_pytest.py', + xmlName: 'tests/test_another_pytest.py', + functions: [], + suites: [], + time: 0 + }; + const testFileToRun: TestsToRun = { testFile: [testFile], testFolder: [], testFunction: [], testSuite: [] }; + const results = await testManager.runTest(CommandSource.ui, testFileToRun); + assert.equal(results.summary.errors, 0, 'Errors'); + assert.equal(results.summary.failures, 1, 'Failures'); + assert.equal(results.summary.passed, 3, 'Passed'); + assert.equal(results.summary.skipped, 0, 'skipped'); + }); + + test('Run Specific Test Suite', async () => { + injectTestDiscoveryOutput('four.output'); + injectTestRunOutput('four.xml'); + await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('pytest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + const testSuite: TestsToRun = { testFile: [], testFolder: [], testFunction: [], testSuite: [tests.testSuites[0].testSuite] }; + const results = await testManager.runTest(CommandSource.ui, testSuite); + assert.equal(results.summary.errors, 0, 'Errors'); + assert.equal(results.summary.failures, 1, 'Failures'); + assert.equal(results.summary.passed, 1, 'Passed'); + assert.equal(results.summary.skipped, 1, 'skipped'); + }); + + test('Run Specific Test Function', async () => { + injectTestDiscoveryOutput('five.output'); + injectTestRunOutput('five.xml'); + await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('pytest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + const testFn: TestsToRun = { testFile: [], testFolder: [], testFunction: [tests.testFunctions[0].testFunction], testSuite: [] }; + const results = await testManager.runTest(CommandSource.ui, testFn); + assert.equal(results.summary.errors, 0, 'Errors'); + assert.equal(results.summary.failures, 1, 'Failures'); + assert.equal(results.summary.passed, 0, 'Passed'); + assert.equal(results.summary.skipped, 0, 'skipped'); + }); +}); diff --git a/src/test/unittests/pytest.test.ts b/src/test/unittests/pytest.test.ts index 1b016f4228cc..d8cea72441d5 100644 --- a/src/test/unittests/pytest.test.ts +++ b/src/test/unittests/pytest.test.ts @@ -2,60 +2,41 @@ import * as assert from 'assert'; import * as path from 'path'; import * as vscode from 'vscode'; import { CommandSource } from '../../client/unittests/common/constants'; -import { TestCollectionStorageService } from '../../client/unittests/common/storageService'; -import { TestResultsService } from '../../client/unittests/common/testResultsService'; -import { TestsHelper } from '../../client/unittests/common/testUtils'; -import { ITestCollectionStorageService, ITestResultsService, ITestsHelper, TestFile, TestsToRun } from '../../client/unittests/common/types'; -import { TestResultDisplay } from '../../client/unittests/display/main'; -import * as pytest from '../../client/unittests/pytest/main'; +import { ITestManagerFactory } from '../../client/unittests/common/types'; import { rootWorkspaceUri, updateSetting } from '../common'; import { initialize, initializeTest, IS_MULTI_ROOT_TEST } from './../initialize'; -import { MockOutputChannel } from './../mockClasses'; -import { MockDebugLauncher } from './mocks'; +import { UnitTestIocContainer } from './serviceRegistry'; -const UNITTEST_TEST_FILES_PATH = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles', 'standard'); const UNITTEST_SINGLE_TEST_FILE_PATH = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles', 'single'); -const UNITTEST_TEST_FILES_PATH_WITH_CONFIGS = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles', 'unitestsWithConfigs'); -const unitTestTestFilesCwdPath = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles', 'cwd', 'src'); // tslint:disable-next-line:max-func-body-length -suite('Unit Tests (PyTest)', () => { - let rootDirectory = UNITTEST_TEST_FILES_PATH; - let testManager: pytest.TestManager; - let testResultDisplay: TestResultDisplay; - let outChannel: vscode.OutputChannel; - let storageService: ITestCollectionStorageService; - let resultsService: ITestResultsService; - let testsHelper: ITestsHelper; +suite('Unit Tests - pytest - discovery against actual python process', () => { + let ioc: UnitTestIocContainer; const configTarget = IS_MULTI_ROOT_TEST ? vscode.ConfigurationTarget.WorkspaceFolder : vscode.ConfigurationTarget.Workspace; suiteSetup(async () => { await initialize(); await updateSetting('unitTest.pyTestArgs', [], rootWorkspaceUri, configTarget); }); setup(async () => { - rootDirectory = UNITTEST_TEST_FILES_PATH; - outChannel = new MockOutputChannel('Python Test Log'); - testResultDisplay = new TestResultDisplay(outChannel); await initializeTest(); + initializeDI(); }); teardown(async () => { - outChannel.dispose(); - testManager.dispose(); - testResultDisplay.dispose(); + ioc.dispose(); await updateSetting('unitTest.pyTestArgs', [], rootWorkspaceUri, configTarget); }); - function createTestManager(rootDir: string = rootDirectory) { - storageService = new TestCollectionStorageService(); - resultsService = new TestResultsService(); - testsHelper = new TestsHelper(); - testManager = new pytest.TestManager(rootDir, outChannel, storageService, resultsService, testsHelper, new MockDebugLauncher()); + + function initializeDI() { + ioc = new UnitTestIocContainer(); + ioc.registerCommonTypes(); + ioc.registerProcessTypes(); + ioc.registerUnitTestTypes(); + ioc.registerVariableTypes(); } test('Discover Tests (single test file)', async () => { - storageService = new TestCollectionStorageService(); - resultsService = new TestResultsService(); - testsHelper = new TestsHelper(); - testManager = new pytest.TestManager(UNITTEST_SINGLE_TEST_FILE_PATH, outChannel, storageService, resultsService, testsHelper, new MockDebugLauncher()); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('pytest', rootWorkspaceUri, UNITTEST_SINGLE_TEST_FILE_PATH); const tests = await testManager.discoverTests(CommandSource.ui, true, true); assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 6, 'Incorrect number of test functions'); @@ -63,123 +44,4 @@ suite('Unit Tests (PyTest)', () => { assert.equal(tests.testFiles.some(t => t.name === 'tests/test_one.py' && t.nameToRun === t.name), true, 'Test File not found'); assert.equal(tests.testFiles.some(t => t.name === 'test_root.py' && t.nameToRun === t.name), true, 'Test File not found'); }); - - test('Discover Tests (pattern = test_)', async () => { - await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); - createTestManager(); - const tests = await testManager.discoverTests(CommandSource.ui, true, true); - assert.equal(tests.testFiles.length, 6, 'Incorrect number of test files'); - assert.equal(tests.testFunctions.length, 29, 'Incorrect number of test functions'); - assert.equal(tests.testSuites.length, 8, 'Incorrect number of test suites'); - assert.equal(tests.testFiles.some(t => t.name === 'tests/test_unittest_one.py' && t.nameToRun === t.name), true, 'Test File not found'); - assert.equal(tests.testFiles.some(t => t.name === 'tests/test_unittest_two.py' && t.nameToRun === t.name), true, 'Test File not found'); - assert.equal(tests.testFiles.some(t => t.name === 'tests/unittest_three_test.py' && t.nameToRun === t.name), true, 'Test File not found'); - assert.equal(tests.testFiles.some(t => t.name === 'tests/test_pytest.py' && t.nameToRun === t.name), true, 'Test File not found'); - assert.equal(tests.testFiles.some(t => t.name === 'tests/test_another_pytest.py' && t.nameToRun === t.name), true, 'Test File not found'); - assert.equal(tests.testFiles.some(t => t.name === 'test_root.py' && t.nameToRun === t.name), true, 'Test File not found'); - }); - - test('Discover Tests (pattern = _test)', async () => { - await updateSetting('unitTest.pyTestArgs', ['-k=_test.py'], rootWorkspaceUri, configTarget); - createTestManager(); - const tests = await testManager.discoverTests(CommandSource.ui, true, true); - assert.equal(tests.testFiles.length, 1, 'Incorrect number of test files'); - assert.equal(tests.testFunctions.length, 2, 'Incorrect number of test functions'); - assert.equal(tests.testSuites.length, 1, 'Incorrect number of test suites'); - assert.equal(tests.testFiles.some(t => t.name === 'tests/unittest_three_test.py' && t.nameToRun === t.name), true, 'Test File not found'); - }); - - test('Discover Tests (with config)', async () => { - await updateSetting('unitTest.pyTestArgs', [], rootWorkspaceUri, configTarget); - rootDirectory = UNITTEST_TEST_FILES_PATH_WITH_CONFIGS; - createTestManager(); - const tests = await testManager.discoverTests(CommandSource.ui, true, true); - assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); - assert.equal(tests.testFunctions.length, 14, 'Incorrect number of test functions'); - assert.equal(tests.testSuites.length, 4, 'Incorrect number of test suites'); - assert.equal(tests.testFiles.some(t => t.name === 'other/test_unittest_one.py' && t.nameToRun === t.name), true, 'Test File not found'); - assert.equal(tests.testFiles.some(t => t.name === 'other/test_pytest.py' && t.nameToRun === t.name), true, 'Test File not found'); - }); - - test('Run Tests', async () => { - await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); - createTestManager(); - const results = await testManager.runTest(CommandSource.ui); - assert.equal(results.summary.errors, 0, 'Errors'); - assert.equal(results.summary.failures, 9, 'Failures'); - assert.equal(results.summary.passed, 17, 'Passed'); - assert.equal(results.summary.skipped, 3, 'skipped'); - }); - - test('Run Failed Tests', async () => { - await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); - createTestManager(); - let results = await testManager.runTest(CommandSource.ui); - assert.equal(results.summary.errors, 0, 'Errors'); - assert.equal(results.summary.failures, 9, 'Failures'); - assert.equal(results.summary.passed, 17, 'Passed'); - assert.equal(results.summary.skipped, 3, 'skipped'); - - results = await testManager.runTest(CommandSource.ui, undefined, true); - assert.equal(results.summary.errors, 0, 'Failed Errors'); - assert.equal(results.summary.failures, 9, 'Failed Failures'); - assert.equal(results.summary.passed, 0, 'Failed Passed'); - assert.equal(results.summary.skipped, 0, 'Failed skipped'); - }); - - test('Run Specific Test File', async () => { - await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); - createTestManager(); - await testManager.discoverTests(CommandSource.ui, true, true); - const testFile: TestFile = { - fullPath: path.join(rootDirectory, 'tests', 'test_another_pytest.py'), - name: 'tests/test_another_pytest.py', - nameToRun: 'tests/test_another_pytest.py', - xmlName: 'tests/test_another_pytest.py', - functions: [], - suites: [], - time: 0 - }; - const testFileToRun: TestsToRun = { testFile: [testFile], testFolder: [], testFunction: [], testSuite: [] }; - const results = await testManager.runTest(CommandSource.ui, testFileToRun); - assert.equal(results.summary.errors, 0, 'Errors'); - assert.equal(results.summary.failures, 1, 'Failures'); - assert.equal(results.summary.passed, 3, 'Passed'); - assert.equal(results.summary.skipped, 0, 'skipped'); - }); - - test('Run Specific Test Suite', async () => { - await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); - createTestManager(); - const tests = await testManager.discoverTests(CommandSource.ui, true, true); - const testSuite: TestsToRun = { testFile: [], testFolder: [], testFunction: [], testSuite: [tests.testSuites[0].testSuite] }; - const results = await testManager.runTest(CommandSource.ui, testSuite); - assert.equal(results.summary.errors, 0, 'Errors'); - assert.equal(results.summary.failures, 1, 'Failures'); - assert.equal(results.summary.passed, 1, 'Passed'); - assert.equal(results.summary.skipped, 1, 'skipped'); - }); - - test('Run Specific Test Function', async () => { - await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); - createTestManager(); - const tests = await testManager.discoverTests(CommandSource.ui, true, true); - const testFn: TestsToRun = { testFile: [], testFolder: [], testFunction: [tests.testFunctions[0].testFunction], testSuite: [] }; - const results = await testManager.runTest(CommandSource.ui, testFn); - assert.equal(results.summary.errors, 0, 'Errors'); - assert.equal(results.summary.failures, 1, 'Failures'); - assert.equal(results.summary.passed, 0, 'Passed'); - assert.equal(results.summary.skipped, 0, 'skipped'); - }); - - test('Setting cwd should return tests', async () => { - await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); - createTestManager(unitTestTestFilesCwdPath); - - const tests = await testManager.discoverTests(CommandSource.ui, true, true); - assert.equal(tests.testFiles.length, 1, 'Incorrect number of test files'); - assert.equal(tests.testFolders.length, 1, 'Incorrect number of test folders'); - assert.equal(tests.testFunctions.length, 1, 'Incorrect number of test functions'); - assert.equal(tests.testSuites.length, 1, 'Incorrect number of test suites'); - }); }); diff --git a/src/test/unittests/rediscover.test.ts b/src/test/unittests/rediscover.test.ts index ade46afcbfd5..9278489413cd 100644 --- a/src/test/unittests/rediscover.test.ts +++ b/src/test/unittests/rediscover.test.ts @@ -2,20 +2,11 @@ import { assert } from 'chai'; import * as fs from 'fs-extra'; import * as path from 'path'; import { ConfigurationTarget } from 'vscode'; -import { BaseTestManager } from '../../client/unittests/common/baseTestManager'; import { CommandSource } from '../../client/unittests/common/constants'; -import { TestCollectionStorageService } from '../../client/unittests/common/storageService'; -import { TestResultsService } from '../../client/unittests/common/testResultsService'; -import { TestsHelper } from '../../client/unittests/common/testUtils'; -import { ITestCollectionStorageService, ITestResultsService, ITestsHelper } from '../../client/unittests/common/types'; -import { TestResultDisplay } from '../../client/unittests/display/main'; -import { TestManager as NosetestManager } from '../../client/unittests/nosetest/main'; -import { TestManager as PytestManager } from '../../client/unittests/pytest/main'; -import { TestManager as UnitTestManager } from '../../client/unittests/unittest/main'; +import { ITestManagerFactory, TestProvider } from '../../client/unittests/common/types'; import { deleteDirectory, deleteFile, rootWorkspaceUri, updateSetting } from '../common'; import { initialize, initializeTest, IS_MULTI_ROOT_TEST } from './../initialize'; -import { MockOutputChannel } from './../mockClasses'; -import { MockDebugLauncher } from './mocks'; +import { UnitTestIocContainer } from './serviceRegistry'; const testFilesPath = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles', 'debuggerTest'); const testFile = path.join(testFilesPath, 'tests', 'test_debugger_two.py'); @@ -31,34 +22,23 @@ const defaultUnitTestArgs = [ // tslint:disable-next-line:max-func-body-length suite('Unit Tests re-discovery', () => { - let testManager: BaseTestManager; - let testResultDisplay: TestResultDisplay; - let outChannel: MockOutputChannel; - let storageService: ITestCollectionStorageService; - let resultsService: ITestResultsService; - let mockDebugLauncher: MockDebugLauncher; - let testsHelper: ITestsHelper; + let ioc: UnitTestIocContainer; const configTarget = IS_MULTI_ROOT_TEST ? ConfigurationTarget.WorkspaceFolder : ConfigurationTarget.Workspace; suiteSetup(async () => { await initialize(); }); setup(async () => { - outChannel = new MockOutputChannel('Python Test Log'); - testResultDisplay = new TestResultDisplay(outChannel); await fs.copy(testFileWithFewTests, testFile, { overwrite: true }); await deleteDirectory(path.join(testFilesPath, '.cache')); await resetSettings(); await initializeTest(); + initializeDI(); }); teardown(async () => { + ioc.dispose(); await resetSettings(); await fs.copy(testFileWithFewTests, testFile, { overwrite: true }); await deleteFile(path.join(path.dirname(testFile), `${path.basename(testFile, '.py')}.pyc`)); - outChannel.dispose(); - if (testManager) { - testManager.dispose(); - } - testResultDisplay.dispose(); }); async function resetSettings() { @@ -67,14 +47,16 @@ suite('Unit Tests re-discovery', () => { await updateSetting('unitTest.pyTestArgs', [], rootWorkspaceUri, configTarget); } - function createTestManagerDepedencies() { - storageService = new TestCollectionStorageService(); - resultsService = new TestResultsService(); - testsHelper = new TestsHelper(); - mockDebugLauncher = new MockDebugLauncher(); + function initializeDI() { + ioc = new UnitTestIocContainer(); + ioc.registerCommonTypes(); + ioc.registerProcessTypes(); + ioc.registerVariableTypes(); + ioc.registerUnitTestTypes(); } - async function discoverUnitTests() { + async function discoverUnitTests(testProvider: TestProvider) { + const testManager = ioc.serviceContainer.get(ITestManagerFactory)(testProvider, rootWorkspaceUri, testFilesPath); let tests = await testManager.discoverTests(CommandSource.ui, true, true); assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); assert.equal(tests.testSuites.length, 2, 'Incorrect number of test suites'); @@ -87,22 +69,16 @@ suite('Unit Tests re-discovery', () => { test('Re-discover tests (unittest)', async () => { await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_*.py'], rootWorkspaceUri, configTarget); - createTestManagerDepedencies(); - testManager = new UnitTestManager(testFilesPath, outChannel, storageService, resultsService, testsHelper, mockDebugLauncher); - await discoverUnitTests(); + await discoverUnitTests('unittest'); }); test('Re-discover tests (pytest)', async () => { await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); - createTestManagerDepedencies(); - testManager = new PytestManager(testFilesPath, outChannel, storageService, resultsService, testsHelper, mockDebugLauncher); - await discoverUnitTests(); + await discoverUnitTests('pytest'); }); test('Re-discover tests (nosetest)', async () => { await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); - createTestManagerDepedencies(); - testManager = new NosetestManager(testFilesPath, outChannel, storageService, resultsService, testsHelper, mockDebugLauncher); - await discoverUnitTests(); + await discoverUnitTests('nosetest'); }); }); diff --git a/src/test/unittests/serviceRegistry.ts b/src/test/unittests/serviceRegistry.ts new file mode 100644 index 000000000000..b9fc642c6b62 --- /dev/null +++ b/src/test/unittests/serviceRegistry.ts @@ -0,0 +1,103 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +import { MockUnitTestSocketServer } from './mocks'; + +import 'reflect-metadata'; +import { Uri } from 'vscode'; +import { IServiceContainer } from '../../client/ioc/types'; +import { NOSETEST_PROVIDER, PYTEST_PROVIDER, UNITTEST_PROVIDER } from '../../client/unittests/common/constants'; +import { TestCollectionStorageService } from '../../client/unittests/common/services/storageService'; +import { TestManagerService } from '../../client/unittests/common/services/testManagerService'; +import { TestResultsService } from '../../client/unittests/common/services/testResultsService'; +import { TestsHelper } from '../../client/unittests/common/testUtils'; +import { TestFlatteningVisitor } from '../../client/unittests/common/testVisitors/flatteningVisitor'; +import { TestFolderGenerationVisitor } from '../../client/unittests/common/testVisitors/folderGenerationVisitor'; +import { TestResultResetVisitor } from '../../client/unittests/common/testVisitors/resultResetVisitor'; +import { ITestCollectionStorageService, ITestDiscoveryService, ITestManager, ITestManagerFactory, ITestManagerService, ITestManagerServiceFactory } from '../../client/unittests/common/types'; +import { ITestResultsService, ITestsHelper, ITestsParser, ITestVisitor, IUnitTestSocketServer, TestProvider } from '../../client/unittests/common/types'; +import { TestManager as NoseTestManager } from '../../client/unittests/nosetest/main'; +import { TestDiscoveryService as NoseTestDiscoveryService } from '../../client/unittests/nosetest/services/discoveryService'; +import { TestsParser as NoseTestTestsParser } from '../../client/unittests/nosetest/services/parserService'; +import { TestManager as PyTestTestManager } from '../../client/unittests/pytest/main'; +import { TestDiscoveryService as PytestTestDiscoveryService } from '../../client/unittests/pytest/services/discoveryService'; +import { TestsParser as PytestTestsParser } from '../../client/unittests/pytest/services/parserService'; +import { TestManager as UnitTestTestManager } from '../../client/unittests/unittest/main'; +import { TestDiscoveryService as UnitTestTestDiscoveryService } from '../../client/unittests/unittest/services/discoveryService'; +import { TestsParser as UnitTestTestsParser } from '../../client/unittests/unittest/services/parserService'; +import { IocContainer } from '../serviceRegistry'; + +export class UnitTestIocContainer extends IocContainer { + constructor() { + super(); + } + + public registerTestVisitors() { + this.serviceManager.add(ITestVisitor, TestFlatteningVisitor, 'TestFlatteningVisitor'); + this.serviceManager.add(ITestVisitor, TestFolderGenerationVisitor, 'TestFolderGenerationVisitor'); + this.serviceManager.add(ITestVisitor, TestResultResetVisitor, 'TestResultResetVisitor'); + } + + public registerTestStorage() { + this.serviceManager.addSingleton(ITestCollectionStorageService, TestCollectionStorageService); + } + + public registerTestsHelper() { + this.serviceManager.addSingleton(ITestsHelper, TestsHelper); + } + + public registerTestResultsHelper() { + this.serviceManager.add(ITestResultsService, TestResultsService); + } + + public registerTestParsers() { + this.serviceManager.add(ITestsParser, UnitTestTestsParser, UNITTEST_PROVIDER); + this.serviceManager.add(ITestsParser, PytestTestsParser, PYTEST_PROVIDER); + this.serviceManager.add(ITestsParser, NoseTestTestsParser, NOSETEST_PROVIDER); + } + + public registerTestDiscoveryServices() { + this.serviceManager.add(ITestDiscoveryService, UnitTestTestDiscoveryService, UNITTEST_PROVIDER); + this.serviceManager.add(ITestDiscoveryService, PytestTestDiscoveryService, PYTEST_PROVIDER); + this.serviceManager.add(ITestDiscoveryService, NoseTestDiscoveryService, NOSETEST_PROVIDER); + } + + public registerTestManagers() { + this.serviceManager.addFactory(ITestManagerFactory, (context) => { + return (testProvider: TestProvider, workspaceFolder: Uri, rootDirectory: string) => { + const serviceContainer = context.container.get(IServiceContainer); + + switch (testProvider) { + case NOSETEST_PROVIDER: { + return new NoseTestManager(workspaceFolder, rootDirectory, serviceContainer); + } + case PYTEST_PROVIDER: { + return new PyTestTestManager(workspaceFolder, rootDirectory, serviceContainer); + } + case UNITTEST_PROVIDER: { + return new UnitTestTestManager(workspaceFolder, rootDirectory, serviceContainer); + } + default: { + throw new Error(`Unrecognized test provider '${testProvider}'`); + } + } + }; + }); + } + + public registerTestManagerService() { + this.serviceManager.addFactory(ITestManagerServiceFactory, (context) => { + return (workspaceFolder: Uri) => { + const serviceContainer = context.container.get(IServiceContainer); + const testsHelper = context.container.get(ITestsHelper); + return new TestManagerService(workspaceFolder, testsHelper, serviceContainer); + }; + }); + } + + public registerMockUnitTestSocketServer() { + this.serviceManager.addSingleton(IUnitTestSocketServer, MockUnitTestSocketServer); + } +} diff --git a/src/test/unittests/stoppingDiscoverAndTest.test.ts b/src/test/unittests/stoppingDiscoverAndTest.test.ts index eba6a358aa8d..790778bb41c2 100644 --- a/src/test/unittests/stoppingDiscoverAndTest.test.ts +++ b/src/test/unittests/stoppingDiscoverAndTest.test.ts @@ -4,16 +4,13 @@ import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; import * as path from 'path'; +import { Uri } from 'vscode'; import { Product } from '../../client/common/installer'; -import { CANCELLATION_REASON, CommandSource } from '../../client/unittests/common/constants'; -import { TestCollectionStorageService } from '../../client/unittests/common/storageService'; -import { TestResultsService } from '../../client/unittests/common/testResultsService'; -import { TestsHelper } from '../../client/unittests/common/testUtils'; -import { ITestCollectionStorageService, ITestResultsService, ITestsHelper } from '../../client/unittests/common/types'; -import { TestResultDisplay } from '../../client/unittests/display/main'; +import { CANCELLATION_REASON, CommandSource, UNITTEST_PROVIDER } from '../../client/unittests/common/constants'; +import { ITestDiscoveryService } from '../../client/unittests/common/types'; import { initialize, initializeTest } from '../initialize'; -import { MockOutputChannel } from '../mockClasses'; -import { MockTestManagerWithRunningTests } from './mocks'; +import { MockDiscoveryService, MockTestManagerWithRunningTests } from './mocks'; +import { UnitTestIocContainer } from './serviceRegistry'; use(chaiAsPromised); @@ -35,42 +32,42 @@ const EmptyTests = { // tslint:disable-next-line:max-func-body-length suite('Unit Tests Stopping Discovery and Runner', () => { - let testResultDisplay: TestResultDisplay; - let outChannel: MockOutputChannel; - let storageService: ITestCollectionStorageService; - let resultsService: ITestResultsService; - let testsHelper: ITestsHelper; + let ioc: UnitTestIocContainer; suiteSetup(initialize); setup(async () => { - outChannel = new MockOutputChannel('Python Test Log'); - testResultDisplay = new TestResultDisplay(outChannel); await initializeTest(); + initializeDI(); }); - teardown(() => { - outChannel.dispose(); - testResultDisplay.dispose(); - }); + teardown(() => ioc.dispose()); + + function initializeDI() { + ioc = new UnitTestIocContainer(); + ioc.registerCommonTypes(); + ioc.registerProcessTypes(); + ioc.registerVariableTypes(); + + ioc.registerTestParsers(); + ioc.registerTestVisitors(); + ioc.registerTestResultsHelper(); + ioc.registerTestStorage(); + ioc.registerTestsHelper(); - function createTestManagerDepedencies() { - storageService = new TestCollectionStorageService(); - resultsService = new TestResultsService(); - testsHelper = new TestsHelper(); } test('Running tests should not stop existing discovery', async () => { - createTestManagerDepedencies(); - const mockTestManager = new MockTestManagerWithRunningTests('unittest', Product.unittest, testFilesPath, outChannel, storageService, resultsService, testsHelper); + const mockTestManager = new MockTestManagerWithRunningTests(UNITTEST_PROVIDER, Product.unittest, Uri.file(testFilesPath), testFilesPath, ioc.serviceContainer); + ioc.serviceManager.addSingletonInstance(ITestDiscoveryService, new MockDiscoveryService(mockTestManager.discoveryDeferred.promise), UNITTEST_PROVIDER); + const discoveryPromise = mockTestManager.discoverTests(CommandSource.auto); mockTestManager.discoveryDeferred.resolve(EmptyTests); - // tslint:disable-next-line:no-floating-promises mockTestManager.runTest(CommandSource.ui); await expect(discoveryPromise).to.eventually.equal(EmptyTests); }); test('Discovering tests should stop running tests', async () => { - createTestManagerDepedencies(); - const mockTestManager = new MockTestManagerWithRunningTests('unittest', Product.unittest, testFilesPath, outChannel, storageService, resultsService, testsHelper); + const mockTestManager = new MockTestManagerWithRunningTests(UNITTEST_PROVIDER, Product.unittest, Uri.file(testFilesPath), testFilesPath, ioc.serviceContainer); + ioc.serviceManager.addSingletonInstance(ITestDiscoveryService, new MockDiscoveryService(mockTestManager.discoveryDeferred.promise), UNITTEST_PROVIDER); mockTestManager.discoveryDeferred.resolve(EmptyTests); await mockTestManager.discoverTests(CommandSource.auto); const runPromise = mockTestManager.runTest(CommandSource.ui); @@ -78,7 +75,6 @@ suite('Unit Tests Stopping Discovery and Runner', () => { await new Promise(resolve => setTimeout(resolve, 1000)); // User manually discovering tests will kill the existing test runner. - // tslint:disable-next-line:no-floating-promises mockTestManager.discoverTests(CommandSource.ui, true, false, true); await expect(runPromise).to.eventually.be.rejectedWith(CANCELLATION_REASON); }); diff --git a/src/test/unittests/unittest.discovery.test.ts b/src/test/unittests/unittest.discovery.test.ts new file mode 100644 index 000000000000..b1f95c6ed978 --- /dev/null +++ b/src/test/unittests/unittest.discovery.test.ts @@ -0,0 +1,147 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import * as assert from 'assert'; +import * as fs from 'fs-extra'; +import { EOL } from 'os'; +import * as path from 'path'; +import { ConfigurationTarget } from 'vscode'; +import { IProcessService } from '../../client/common/process/types'; +import { CommandSource } from '../../client/unittests/common/constants'; +import { ITestManagerFactory } from '../../client/unittests/common/types'; +import { rootWorkspaceUri, updateSetting } from '../common'; +import { MockProcessService } from '../mocks/proc'; +import { initialize, initializeTest, IS_MULTI_ROOT_TEST } from './../initialize'; +import { UnitTestIocContainer } from './serviceRegistry'; + +const testFilesPath = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles'); +const UNITTEST_TEST_FILES_PATH = path.join(testFilesPath, 'standard'); +const UNITTEST_SINGLE_TEST_FILE_PATH = path.join(testFilesPath, 'single'); +const unitTestTestFilesCwdPath = path.join(testFilesPath, 'cwd', 'src'); +const defaultUnitTestArgs = [ + '-v', + '-s', + '.', + '-p', + '*test*.py' +]; + +// tslint:disable-next-line:max-func-body-length +suite('Unit Tests - unittest - discovery with mocked process output', () => { + let ioc: UnitTestIocContainer; + const rootDirectory = UNITTEST_TEST_FILES_PATH; + const configTarget = IS_MULTI_ROOT_TEST ? ConfigurationTarget.WorkspaceFolder : ConfigurationTarget.Workspace; + + suiteSetup(async () => { + await initialize(); + await updateSetting('unitTest.unittestArgs', defaultUnitTestArgs, rootWorkspaceUri, configTarget); + }); + setup(async () => { + const cachePath = path.join(UNITTEST_TEST_FILES_PATH, '.cache'); + if (await fs.pathExists(cachePath)) { + await fs.remove(cachePath); + } + await initializeTest(); + initializeDI(); + }); + teardown(async () => { + ioc.dispose(); + await updateSetting('unitTest.unittestArgs', defaultUnitTestArgs, rootWorkspaceUri, configTarget); + }); + + function initializeDI() { + ioc = new UnitTestIocContainer(); + ioc.registerCommonTypes(); + ioc.registerVariableTypes(); + ioc.registerUnitTestTypes(); + + // Mocks. + ioc.registerMockProcessTypes(); + } + + function injectTestDiscoveryOutput(output: string) { + const procService = ioc.serviceContainer.get(IProcessService); + procService.onExecObservable((file, args, options, callback) => { + if (args.length > 1 && args[0] === '-c' && args[1].includes('import unittest') && args[1].includes('loader = unittest.TestLoader()')) { + callback({ + // Ensure any spaces added during code formatting or the like are removed. + out: output.split(/\r?\n/g).map(item => item.trim()).join(EOL), + source: 'stdout' + }); + } + }); + } + + test('Discover Tests (single test file)', async () => { + await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_*.py'], rootWorkspaceUri, configTarget); + // tslint:disable-next-line:no-multiline-string + injectTestDiscoveryOutput(`start + test_one.Test_test1.test_A + test_one.Test_test1.test_B + test_one.Test_test1.test_c + `); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('unittest', rootWorkspaceUri, UNITTEST_SINGLE_TEST_FILE_PATH); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + assert.equal(tests.testFiles.length, 1, 'Incorrect number of test files'); + assert.equal(tests.testFunctions.length, 3, 'Incorrect number of test functions'); + assert.equal(tests.testSuites.length, 1, 'Incorrect number of test suites'); + assert.equal(tests.testFiles.some(t => t.name === 'test_one.py' && t.nameToRun === 'Test_test1.test_A'), true, 'Test File not found'); + }); + + test('Discover Tests', async () => { + await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_*.py'], rootWorkspaceUri, configTarget); + // tslint:disable-next-line:no-multiline-string + injectTestDiscoveryOutput(`start + test_unittest_one.Test_test1.test_A + test_unittest_one.Test_test1.test_B + test_unittest_one.Test_test1.test_c + test_unittest_two.Test_test2.test_A2 + test_unittest_two.Test_test2.test_B2 + test_unittest_two.Test_test2.test_C2 + test_unittest_two.Test_test2.test_D2 + test_unittest_two.Test_test2a.test_222A2 + test_unittest_two.Test_test2a.test_222B2 + `); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('unittest', rootWorkspaceUri, rootDirectory); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); + assert.equal(tests.testFunctions.length, 9, 'Incorrect number of test functions'); + assert.equal(tests.testSuites.length, 3, 'Incorrect number of test suites'); + assert.equal(tests.testFiles.some(t => t.name === 'test_unittest_one.py' && t.nameToRun === 'Test_test1.test_A'), true, 'Test File not found'); + assert.equal(tests.testFiles.some(t => t.name === 'test_unittest_two.py' && t.nameToRun === 'Test_test2.test_A2'), true, 'Test File not found'); + }); + + test('Discover Tests (pattern = *_test_*.py)', async () => { + await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=*_test*.py'], rootWorkspaceUri, configTarget); + // tslint:disable-next-line:no-multiline-string + injectTestDiscoveryOutput(`start + unittest_three_test.Test_test3.test_A + unittest_three_test.Test_test3.test_B + `); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('unittest', rootWorkspaceUri, rootDirectory); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + assert.equal(tests.testFiles.length, 1, 'Incorrect number of test files'); + assert.equal(tests.testFunctions.length, 2, 'Incorrect number of test functions'); + assert.equal(tests.testSuites.length, 1, 'Incorrect number of test suites'); + assert.equal(tests.testFiles.some(t => t.name === 'unittest_three_test.py' && t.nameToRun === 'Test_test3.test_A'), true, 'Test File not found'); + }); + + test('Setting cwd should return tests', async () => { + await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_*.py'], rootWorkspaceUri, configTarget); + // tslint:disable-next-line:no-multiline-string + injectTestDiscoveryOutput(`start + test_cwd.Test_Current_Working_Directory.test_cwd + `); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('unittest', rootWorkspaceUri, unitTestTestFilesCwdPath); + + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + assert.equal(tests.testFiles.length, 1, 'Incorrect number of test files'); + assert.equal(tests.testFolders.length, 1, 'Incorrect number of test folders'); + assert.equal(tests.testFunctions.length, 1, 'Incorrect number of test functions'); + assert.equal(tests.testSuites.length, 1, 'Incorrect number of test suites'); + }); +}); diff --git a/src/test/unittests/unittest.run.test.ts b/src/test/unittests/unittest.run.test.ts new file mode 100644 index 000000000000..f74ff2522acb --- /dev/null +++ b/src/test/unittests/unittest.run.test.ts @@ -0,0 +1,295 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import * as assert from 'assert'; +import * as fs from 'fs-extra'; +import { EOL } from 'os'; +import * as path from 'path'; +import { ConfigurationTarget } from 'vscode'; +import { IProcessService } from '../../client/common/process/types'; +import { CommandSource } from '../../client/unittests/common/constants'; +import { ITestManagerFactory, IUnitTestSocketServer, TestsToRun } from '../../client/unittests/common/types'; +import { rootWorkspaceUri, updateSetting } from '../common'; +import { MockProcessService } from '../mocks/proc'; +import { initialize, initializeTest, IS_MULTI_ROOT_TEST } from './../initialize'; +import { MockUnitTestSocketServer } from './mocks'; +import { UnitTestIocContainer } from './serviceRegistry'; + +const testFilesPath = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles'); +const UNITTEST_TEST_FILES_PATH = path.join(testFilesPath, 'standard'); +const unitTestSpecificTestFilesPath = path.join(testFilesPath, 'specificTest'); +const defaultUnitTestArgs = [ + '-v', + '-s', + '.', + '-p', + '*test*.py' +]; + +// tslint:disable-next-line:max-func-body-length +suite('Unit Tests - unittest - run with mocked process output', () => { + let ioc: UnitTestIocContainer; + const rootDirectory = UNITTEST_TEST_FILES_PATH; + const configTarget = IS_MULTI_ROOT_TEST ? ConfigurationTarget.WorkspaceFolder : ConfigurationTarget.Workspace; + + suiteSetup(async () => { + await initialize(); + await updateSetting('unitTest.unittestArgs', defaultUnitTestArgs, rootWorkspaceUri, configTarget); + }); + setup(async () => { + const cachePath = path.join(UNITTEST_TEST_FILES_PATH, '.cache'); + if (await fs.pathExists(cachePath)) { + await fs.remove(cachePath); + } + await initializeTest(); + initializeDI(); + ignoreTestLauncher(); + }); + teardown(async () => { + ioc.dispose(); + await updateSetting('unitTest.unittestArgs', defaultUnitTestArgs, rootWorkspaceUri, configTarget); + }); + + function initializeDI() { + ioc = new UnitTestIocContainer(); + ioc.registerCommonTypes(); + ioc.registerVariableTypes(); + + // Mocks. + ioc.registerMockProcessTypes(); + ioc.registerMockUnitTestSocketServer(); + + // Standard unit test stypes. + ioc.registerTestDiscoveryServices(); + ioc.registerTestManagers(); + ioc.registerTestManagerService(); + ioc.registerTestParsers(); + ioc.registerTestResultsHelper(); + ioc.registerTestsHelper(); + ioc.registerTestStorage(); + ioc.registerTestVisitors(); + } + + function ignoreTestLauncher() { + const procService = ioc.serviceContainer.get(IProcessService); + // When running the python test launcher, just return. + procService.onExecObservable((file, args, options, callback) => { + if (args.length > 1 && args[0].endsWith('visualstudio_py_testlauncher.py')) { + callback({ out: '', source: 'stdout' }); + } + }); + } + function injectTestDiscoveryOutput(output: string) { + const procService = ioc.serviceContainer.get(IProcessService); + procService.onExecObservable((file, args, options, callback) => { + if (args.length > 1 && args[0] === '-c' && args[1].includes('import unittest') && args[1].includes('loader = unittest.TestLoader()')) { + callback({ + // Ensure any spaces added during code formatting or the like are removed + out: output.split(/\r?\n/g).map(item => item.trim()).join(EOL), + source: 'stdout' + }); + } + }); + } + function injectTestSocketServerResults(results: {}[]) { + // Add results to be sent by unit test socket server. + const socketServer = ioc.serviceContainer.get(IUnitTestSocketServer); + socketServer.reset(); + socketServer.addResults(results); + } + + test('Run Tests', async () => { + await updateSetting('unitTest.unittestArgs', ['-v', '-s', './tests', '-p', 'test_unittest*.py'], rootWorkspaceUri, configTarget); + // tslint:disable-next-line:no-multiline-string + injectTestDiscoveryOutput(`start + test_unittest_one.Test_test1.test_A + test_unittest_one.Test_test1.test_B + test_unittest_one.Test_test1.test_c + test_unittest_two.Test_test2.test_A2 + test_unittest_two.Test_test2.test_B2 + test_unittest_two.Test_test2.test_C2 + test_unittest_two.Test_test2.test_D2 + test_unittest_two.Test_test2a.test_222A2 + test_unittest_two.Test_test2a.test_222B2 + `); + const resultsToSend = [ + { outcome: 'failed', traceback: 'AssertionError: Not implemented\n', message: 'Not implemented', test: 'test_unittest_one.Test_test1.test_A' }, + { outcome: 'passed', traceback: null, message: null, test: 'test_unittest_one.Test_test1.test_B' }, + { outcome: 'skipped', traceback: null, message: null, test: 'test_unittest_one.Test_test1.test_c' }, + { outcome: 'failed', traceback: 'raise self.failureException(msg)\nAssertionError: Not implemented\n', message: 'Not implemented', test: 'test_unittest_two.Test_test2.test_A2' }, + { outcome: 'passed', traceback: null, message: null, test: 'test_unittest_two.Test_test2.test_B2' }, + { outcome: 'failed', traceback: 'raise self.failureException(msg)\nAssertionError: 1 != 2 : Not equal\n', message: '1 != 2 : Not equal', test: 'test_unittest_two.Test_test2.test_C2' }, + { outcome: 'error', traceback: 'raise ArithmeticError()\nArithmeticError\n', message: '', test: 'test_unittest_two.Test_test2.test_D2' }, + { outcome: 'failed', traceback: 'raise self.failureException(msg)\nAssertionError: Not implemented\n', message: 'Not implemented', test: 'test_unittest_two.Test_test2a.test_222A2' }, + { outcome: 'passed', traceback: null, message: null, test: 'test_unittest_two.Test_test2a.test_222B2' } + ]; + injectTestSocketServerResults(resultsToSend); + + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('unittest', rootWorkspaceUri, rootDirectory); + const results = await testManager.runTest(CommandSource.ui); + + assert.equal(results.summary.errors, 1, 'Errors'); + assert.equal(results.summary.failures, 4, 'Failures'); + assert.equal(results.summary.passed, 3, 'Passed'); + assert.equal(results.summary.skipped, 1, 'skipped'); + }); + + test('Run Failed Tests', async () => { + await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_unittest*.py'], rootWorkspaceUri, configTarget); + // tslint:disable-next-line:no-multiline-string + injectTestDiscoveryOutput(`start + test_unittest_one.Test_test1.test_A + test_unittest_one.Test_test1.test_B + test_unittest_one.Test_test1.test_c + test_unittest_two.Test_test2.test_A2 + test_unittest_two.Test_test2.test_B2 + test_unittest_two.Test_test2.test_C2 + test_unittest_two.Test_test2.test_D2 + test_unittest_two.Test_test2a.test_222A2 + test_unittest_two.Test_test2a.test_222B2 + `); + + const resultsToSend = [ + { outcome: 'failed', traceback: 'raise self.failureException(msg)\nAssertionError: Not implemented\n', message: 'Not implemented', test: 'test_unittest_one.Test_test1.test_A' }, + { outcome: 'passed', traceback: null, message: null, test: 'test_unittest_one.Test_test1.test_B' }, + { outcome: 'skipped', traceback: null, message: null, test: 'test_unittest_one.Test_test1.test_c' }, + { outcome: 'failed', traceback: 'raise self.failureException(msg)\nAssertionError: Not implemented\n', message: 'Not implemented', test: 'test_unittest_two.Test_test2.test_A2' }, + { outcome: 'passed', traceback: null, message: null, test: 'test_unittest_two.Test_test2.test_B2' }, + { outcome: 'failed', traceback: 'raise self.failureException(msg)\nAssertionError: 1 != 2 : Not equal\n', message: '1 != 2 : Not equal', test: 'test_unittest_two.Test_test2.test_C2' }, + { outcome: 'error', traceback: 'raise ArithmeticError()\nArithmeticError\n', message: '', test: 'test_unittest_two.Test_test2.test_D2' }, + { outcome: 'failed', traceback: 'raise self.failureException(msg)\nAssertionError: Not implemented\n', message: 'Not implemented', test: 'test_unittest_two.Test_test2a.test_222A2' }, + { outcome: 'passed', traceback: null, message: null, test: 'test_unittest_two.Test_test2a.test_222B2' } + ]; + injectTestSocketServerResults(resultsToSend); + + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('unittest', rootWorkspaceUri, rootDirectory); + let results = await testManager.runTest(CommandSource.ui); + assert.equal(results.summary.errors, 1, 'Errors'); + assert.equal(results.summary.failures, 4, 'Failures'); + assert.equal(results.summary.passed, 3, 'Passed'); + assert.equal(results.summary.skipped, 1, 'skipped'); + + const failedResultsToSend = [ + { outcome: 'failed', traceback: 'raise self.failureException(msg)\nAssertionError: Not implemented\n', message: 'Not implemented', test: 'test_unittest_one.Test_test1.test_A' }, + { outcome: 'failed', traceback: 'raise self.failureException(msg)\nAssertionError: Not implemented\n', message: 'Not implemented', test: 'test_unittest_two.Test_test2.test_A2' }, + { outcome: 'failed', traceback: 'raise self.failureException(msg)\nAssertionError: 1 != 2 : Not equal\n', message: '1 != 2 : Not equal', test: 'test_unittest_two.Test_test2.test_C2' }, + { outcome: 'error', traceback: 'raise ArithmeticError()\nArithmeticError\n', message: '', test: 'test_unittest_two.Test_test2.test_D2' }, + { outcome: 'failed', traceback: 'raise self.failureException(msg)\nAssertionError: Not implemented\n', message: 'Not implemented', test: 'test_unittest_two.Test_test2a.test_222A2' } + ]; + injectTestSocketServerResults(failedResultsToSend); + + results = await testManager.runTest(CommandSource.ui, undefined, true); + assert.equal(results.summary.errors, 1, 'Failed Errors'); + assert.equal(results.summary.failures, 4, 'Failed Failures'); + assert.equal(results.summary.passed, 0, 'Failed Passed'); + assert.equal(results.summary.skipped, 0, 'Failed skipped'); + }); + + test('Run Specific Test File', async () => { + await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_unittest*.py'], rootWorkspaceUri, configTarget); + + // tslint:disable-next-line:no-multiline-string + injectTestDiscoveryOutput(`start + test_unittest_one.Test_test_one_1.test_1_1_1 + test_unittest_one.Test_test_one_1.test_1_1_2 + test_unittest_one.Test_test_one_1.test_1_1_3 + test_unittest_one.Test_test_one_2.test_1_2_1 + test_unittest_two.Test_test_two_1.test_1_1_1 + test_unittest_two.Test_test_two_1.test_1_1_2 + test_unittest_two.Test_test_two_1.test_1_1_3 + test_unittest_two.Test_test_two_2.test_2_1_1 + `); + + const resultsToSend = [ + { outcome: 'passed', traceback: null, message: null, test: 'test_unittest_one.Test_test_one_1.test_1_1_1' }, + { outcome: 'failed', traceback: 'AssertionError: 1 != 2 : Not equal\n', message: '1 != 2 : Not equal', test: 'test_unittest_one.Test_test_one_1.test_1_1_2' }, + { outcome: 'skipped', traceback: null, message: null, test: 'test_unittest_one.Test_test_one_1.test_1_1_3' }, + { outcome: 'passed', traceback: null, message: null, test: 'test_unittest_one.Test_test_one_2.test_1_2_1' } + ]; + injectTestSocketServerResults(resultsToSend); + + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('unittest', rootWorkspaceUri, unitTestSpecificTestFilesPath); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + + // tslint:disable-next-line:no-non-null-assertion + const testFileToTest = tests.testFiles.find(f => f.name === 'test_unittest_one.py')!; + const testFile: TestsToRun = { testFile: [testFileToTest], testFolder: [], testFunction: [], testSuite: [] }; + const results = await testManager.runTest(CommandSource.ui, testFile); + + assert.equal(results.summary.errors, 0, 'Errors'); + assert.equal(results.summary.failures, 1, 'Failures'); + assert.equal(results.summary.passed, 2, 'Passed'); + assert.equal(results.summary.skipped, 1, 'skipped'); + }); + + test('Run Specific Test Suite', async () => { + await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_unittest*.py'], rootWorkspaceUri, configTarget); + // tslint:disable-next-line:no-multiline-string + injectTestDiscoveryOutput(`start + test_unittest_one.Test_test_one_1.test_1_1_1 + test_unittest_one.Test_test_one_1.test_1_1_2 + test_unittest_one.Test_test_one_1.test_1_1_3 + test_unittest_one.Test_test_one_2.test_1_2_1 + test_unittest_two.Test_test_two_1.test_1_1_1 + test_unittest_two.Test_test_two_1.test_1_1_2 + test_unittest_two.Test_test_two_1.test_1_1_3 + test_unittest_two.Test_test_two_2.test_2_1_1 + `); + + const resultsToSend = [ + { outcome: 'passed', traceback: null, message: null, test: 'test_unittest_one.Test_test_one_1.test_1_1_1' }, + { outcome: 'failed', traceback: 'AssertionError: 1 != 2 : Not equal\n', message: '1 != 2 : Not equal', test: 'test_unittest_one.Test_test_one_1.test_1_1_2' }, + { outcome: 'skipped', traceback: null, message: null, test: 'test_unittest_one.Test_test_one_1.test_1_1_3' }, + { outcome: 'passed', traceback: null, message: null, test: 'test_unittest_one.Test_test_one_2.test_1_2_1' } + ]; + injectTestSocketServerResults(resultsToSend); + + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('unittest', rootWorkspaceUri, unitTestSpecificTestFilesPath); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + + // tslint:disable-next-line:no-non-null-assertion + const testSuiteToTest = tests.testSuites.find(s => s.testSuite.name === 'Test_test_one_1')!.testSuite; + const testSuite: TestsToRun = { testFile: [], testFolder: [], testFunction: [], testSuite: [testSuiteToTest] }; + const results = await testManager.runTest(CommandSource.ui, testSuite); + + assert.equal(results.summary.errors, 0, 'Errors'); + assert.equal(results.summary.failures, 1, 'Failures'); + assert.equal(results.summary.passed, 2, 'Passed'); + assert.equal(results.summary.skipped, 1, 'skipped'); + }); + + test('Run Specific Test Function', async () => { + await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_unittest*.py'], rootWorkspaceUri, configTarget); + // tslint:disable-next-line:no-multiline-string + injectTestDiscoveryOutput(`start + test_unittest_one.Test_test1.test_A + test_unittest_one.Test_test1.test_B + test_unittest_one.Test_test1.test_c + test_unittest_two.Test_test2.test_A2 + test_unittest_two.Test_test2.test_B2 + test_unittest_two.Test_test2.test_C2 + test_unittest_two.Test_test2.test_D2 + test_unittest_two.Test_test2a.test_222A2 + test_unittest_two.Test_test2a.test_222B2 + `); + + const resultsToSend = [ + { outcome: 'failed', traceback: 'AssertionError: Not implemented\n', message: 'Not implemented', test: 'test_unittest_one.Test_test1.test_A' } + ]; + injectTestSocketServerResults(resultsToSend); + + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('unittest', rootWorkspaceUri, rootDirectory); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); + const testFn: TestsToRun = { testFile: [], testFolder: [], testFunction: [tests.testFunctions[0].testFunction], testSuite: [] }; + const results = await testManager.runTest(CommandSource.ui, testFn); + assert.equal(results.summary.errors, 0, 'Errors'); + assert.equal(results.summary.failures, 1, 'Failures'); + assert.equal(results.summary.passed, 0, 'Passed'); + assert.equal(results.summary.skipped, 0, 'skipped'); + }); +}); diff --git a/src/test/unittests/unittest.test.ts b/src/test/unittests/unittest.test.ts index d333ed32fa9c..8465b7bdbb92 100644 --- a/src/test/unittests/unittest.test.ts +++ b/src/test/unittests/unittest.test.ts @@ -3,22 +3,14 @@ import * as fs from 'fs-extra'; import * as path from 'path'; import { ConfigurationTarget } from 'vscode'; import { CommandSource } from '../../client/unittests/common/constants'; -import { TestCollectionStorageService } from '../../client/unittests/common/storageService'; -import { TestResultsService } from '../../client/unittests/common/testResultsService'; -import { TestsHelper } from '../../client/unittests/common/testUtils'; -import { ITestCollectionStorageService, ITestResultsService, ITestsHelper, TestsToRun } from '../../client/unittests/common/types'; -import { TestResultDisplay } from '../../client/unittests/display/main'; -import * as unittest from '../../client/unittests/unittest/main'; +import { ITestManagerFactory } from '../../client/unittests/common/types'; import { rootWorkspaceUri, updateSetting } from '../common'; import { initialize, initializeTest, IS_MULTI_ROOT_TEST } from './../initialize'; -import { MockOutputChannel } from './../mockClasses'; -import { MockDebugLauncher } from './mocks'; +import { UnitTestIocContainer } from './serviceRegistry'; const testFilesPath = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles'); const UNITTEST_TEST_FILES_PATH = path.join(testFilesPath, 'standard'); const UNITTEST_SINGLE_TEST_FILE_PATH = path.join(testFilesPath, 'single'); -const unitTestTestFilesCwdPath = path.join(testFilesPath, 'cwd', 'src'); -const unitTestSpecificTestFilesPath = path.join(testFilesPath, 'specificTest'); const defaultUnitTestArgs = [ '-v', '-s', @@ -28,153 +20,43 @@ const defaultUnitTestArgs = [ ]; // tslint:disable-next-line:max-func-body-length -suite('Unit Tests (unittest)', () => { - let testManager: unittest.TestManager; - let testResultDisplay: TestResultDisplay; - let outChannel: MockOutputChannel; - let storageService: ITestCollectionStorageService; - let resultsService: ITestResultsService; - let testsHelper: ITestsHelper; - const rootDirectory = UNITTEST_TEST_FILES_PATH; +suite('Unit Tests - unittest - discovery against actual python process', () => { + let ioc: UnitTestIocContainer; const configTarget = IS_MULTI_ROOT_TEST ? ConfigurationTarget.WorkspaceFolder : ConfigurationTarget.Workspace; + suiteSetup(async () => { await initialize(); await updateSetting('unitTest.unittestArgs', defaultUnitTestArgs, rootWorkspaceUri, configTarget); }); setup(async () => { - outChannel = new MockOutputChannel('Python Test Log'); - testResultDisplay = new TestResultDisplay(outChannel); const cachePath = path.join(UNITTEST_TEST_FILES_PATH, '.cache'); if (await fs.pathExists(cachePath)) { await fs.remove(cachePath); } await initializeTest(); + initializeDI(); }); teardown(async () => { - outChannel.dispose(); - testManager.dispose(); - testResultDisplay.dispose(); + ioc.dispose(); await updateSetting('unitTest.unittestArgs', defaultUnitTestArgs, rootWorkspaceUri, configTarget); }); - function createTestManager(rootDir: string = rootDirectory) { - storageService = new TestCollectionStorageService(); - resultsService = new TestResultsService(); - testsHelper = new TestsHelper(); - testManager = new unittest.TestManager(rootDir, outChannel, storageService, resultsService, testsHelper, new MockDebugLauncher()); + + function initializeDI() { + ioc = new UnitTestIocContainer(); + ioc.registerCommonTypes(); + ioc.registerVariableTypes(); + ioc.registerUnitTestTypes(); + ioc.registerProcessTypes(); } test('Discover Tests (single test file)', async () => { await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_*.py'], rootWorkspaceUri, configTarget); - storageService = new TestCollectionStorageService(); - resultsService = new TestResultsService(); - testsHelper = new TestsHelper(); - testManager = new unittest.TestManager(UNITTEST_SINGLE_TEST_FILE_PATH, outChannel, storageService, resultsService, testsHelper, new MockDebugLauncher()); + const factory = ioc.serviceContainer.get(ITestManagerFactory); + const testManager = factory('unittest', rootWorkspaceUri, UNITTEST_SINGLE_TEST_FILE_PATH); const tests = await testManager.discoverTests(CommandSource.ui, true, true); assert.equal(tests.testFiles.length, 1, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 3, 'Incorrect number of test functions'); assert.equal(tests.testSuites.length, 1, 'Incorrect number of test suites'); assert.equal(tests.testFiles.some(t => t.name === 'test_one.py' && t.nameToRun === 'Test_test1.test_A'), true, 'Test File not found'); }); - - test('Discover Tests', async () => { - await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_*.py'], rootWorkspaceUri, configTarget); - createTestManager(); - const tests = await testManager.discoverTests(CommandSource.ui, true, true); - assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); - assert.equal(tests.testFunctions.length, 9, 'Incorrect number of test functions'); - assert.equal(tests.testSuites.length, 3, 'Incorrect number of test suites'); - assert.equal(tests.testFiles.some(t => t.name === 'test_unittest_one.py' && t.nameToRun === 'Test_test1.test_A'), true, 'Test File not found'); - assert.equal(tests.testFiles.some(t => t.name === 'test_unittest_two.py' && t.nameToRun === 'Test_test2.test_A2'), true, 'Test File not found'); - }); - - test('Discover Tests (pattern = *_test_*.py)', async () => { - await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=*_test*.py'], rootWorkspaceUri, configTarget); - createTestManager(); - const tests = await testManager.discoverTests(CommandSource.ui, true, true); - assert.equal(tests.testFiles.length, 1, 'Incorrect number of test files'); - assert.equal(tests.testFunctions.length, 2, 'Incorrect number of test functions'); - assert.equal(tests.testSuites.length, 1, 'Incorrect number of test suites'); - assert.equal(tests.testFiles.some(t => t.name === 'unittest_three_test.py' && t.nameToRun === 'Test_test3.test_A'), true, 'Test File not found'); - }); - - test('Run Tests', async () => { - await updateSetting('unitTest.unittestArgs', ['-v', '-s', './tests', '-p', 'test_unittest*.py'], rootWorkspaceUri, configTarget); - createTestManager(); - const results = await testManager.runTest(CommandSource.ui); - assert.equal(results.summary.errors, 1, 'Errors'); - assert.equal(results.summary.failures, 4, 'Failures'); - assert.equal(results.summary.passed, 3, 'Passed'); - assert.equal(results.summary.skipped, 1, 'skipped'); - }); - - test('Run Failed Tests', async () => { - await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_unittest*.py'], rootWorkspaceUri, configTarget); - createTestManager(); - let results = await testManager.runTest(CommandSource.ui); - assert.equal(results.summary.errors, 1, 'Errors'); - assert.equal(results.summary.failures, 4, 'Failures'); - assert.equal(results.summary.passed, 3, 'Passed'); - assert.equal(results.summary.skipped, 1, 'skipped'); - - results = await testManager.runTest(CommandSource.ui, undefined, true); - assert.equal(results.summary.errors, 1, 'Failed Errors'); - assert.equal(results.summary.failures, 4, 'Failed Failures'); - assert.equal(results.summary.passed, 0, 'Failed Passed'); - assert.equal(results.summary.skipped, 0, 'Failed skipped'); - }); - - test('Run Specific Test File', async () => { - await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_unittest*.py'], rootWorkspaceUri, configTarget); - createTestManager(unitTestSpecificTestFilesPath); - const tests = await testManager.discoverTests(CommandSource.ui, true, true); - - // tslint:disable-next-line:no-non-null-assertion - const testFileToTest = tests.testFiles.find(f => f.name === 'test_unittest_one.py')!; - const testFile: TestsToRun = { testFile: [testFileToTest], testFolder: [], testFunction: [], testSuite: [] }; - const results = await testManager.runTest(CommandSource.ui, testFile); - - assert.equal(results.summary.errors, 0, 'Errors'); - assert.equal(results.summary.failures, 1, 'Failures'); - assert.equal(results.summary.passed, 2, 'Passed'); - assert.equal(results.summary.skipped, 1, 'skipped'); - }); - - test('Run Specific Test Suite', async () => { - await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_unittest*.py'], rootWorkspaceUri, configTarget); - createTestManager(unitTestSpecificTestFilesPath); - const tests = await testManager.discoverTests(CommandSource.ui, true, true); - - // tslint:disable-next-line:no-non-null-assertion - const testSuiteToTest = tests.testSuites.find(s => s.testSuite.name === 'Test_test_one_1')!.testSuite; - const testSuite: TestsToRun = { testFile: [], testFolder: [], testFunction: [], testSuite: [testSuiteToTest] }; - const results = await testManager.runTest(CommandSource.ui, testSuite); - - assert.equal(results.summary.errors, 0, 'Errors'); - assert.equal(results.summary.failures, 1, 'Failures'); - assert.equal(results.summary.passed, 2, 'Passed'); - assert.equal(results.summary.skipped, 1, 'skipped'); - }); - - test('Run Specific Test Function', async () => { - await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_unittest*.py'], rootWorkspaceUri, configTarget); - createTestManager(); - const tests = await testManager.discoverTests(CommandSource.ui, true, true); - const testFn: TestsToRun = { testFile: [], testFolder: [], testFunction: [tests.testFunctions[0].testFunction], testSuite: [] }; - const results = await testManager.runTest(CommandSource.ui, testFn); - assert.equal(results.summary.errors, 0, 'Errors'); - assert.equal(results.summary.failures, 1, 'Failures'); - assert.equal(results.summary.passed, 0, 'Passed'); - assert.equal(results.summary.skipped, 0, 'skipped'); - }); - - test('Setting cwd should return tests', async () => { - await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_*.py'], rootWorkspaceUri, configTarget); - createTestManager(unitTestTestFilesCwdPath); - - const tests = await testManager.discoverTests(CommandSource.ui, true, true); - assert.equal(tests.testFiles.length, 1, 'Incorrect number of test files'); - assert.equal(tests.testFolders.length, 1, 'Incorrect number of test folders'); - assert.equal(tests.testFunctions.length, 1, 'Incorrect number of test functions'); - assert.equal(tests.testSuites.length, 1, 'Incorrect number of test suites'); - }); }); diff --git a/src/testMultiRootWkspc/multi.code-workspace b/src/testMultiRootWkspc/multi.code-workspace index 6aca26f07b90..cacdd6c7539f 100644 --- a/src/testMultiRootWkspc/multi.code-workspace +++ b/src/testMultiRootWkspc/multi.code-workspace @@ -9,6 +9,12 @@ { "path": "workspace3" }, + { + "path": "workspace4" + }, + { + "path": "workspace5" + }, { "path": "parent\\child" }, diff --git a/src/testMultiRootWkspc/workspace4/.env b/src/testMultiRootWkspc/workspace4/.env new file mode 100644 index 000000000000..0ae33fd6779f --- /dev/null +++ b/src/testMultiRootWkspc/workspace4/.env @@ -0,0 +1,2 @@ +X1234PYEXTUNITTESTVAR=1234 +PYTHONPATH=../workspace5 diff --git a/src/testMultiRootWkspc/workspace4/.env2 b/src/testMultiRootWkspc/workspace4/.env2 new file mode 100644 index 000000000000..c3152625b1a0 --- /dev/null +++ b/src/testMultiRootWkspc/workspace4/.env2 @@ -0,0 +1 @@ +X12345PYEXTUNITTESTVAR=12345 diff --git a/src/testMultiRootWkspc/workspace4/.vscode/settings.json b/src/testMultiRootWkspc/workspace4/.vscode/settings.json new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/src/testMultiRootWkspc/workspace4/.vscode/settings.json @@ -0,0 +1 @@ +{} diff --git a/src/testMultiRootWkspc/workspace4/one.py b/src/testMultiRootWkspc/workspace4/one.py new file mode 100644 index 000000000000..635f08868a11 --- /dev/null +++ b/src/testMultiRootWkspc/workspace4/one.py @@ -0,0 +1,2 @@ +from hello import world +print(world.sayHello()) diff --git a/src/testMultiRootWkspc/workspace5/.vscode/settings.json b/src/testMultiRootWkspc/workspace5/.vscode/settings.json new file mode 100644 index 000000000000..0db3279e44b0 --- /dev/null +++ b/src/testMultiRootWkspc/workspace5/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + +} diff --git a/src/testMultiRootWkspc/workspace5/hello/__init__.py b/src/testMultiRootWkspc/workspace5/hello/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/testMultiRootWkspc/workspace5/hello/world.py b/src/testMultiRootWkspc/workspace5/hello/world.py new file mode 100644 index 000000000000..553782e40de3 --- /dev/null +++ b/src/testMultiRootWkspc/workspace5/hello/world.py @@ -0,0 +1,2 @@ +def sayHello(): + return "Hello" diff --git a/tsconfig.json b/tsconfig.json index c6bac46ad4fa..392fc2a2fbf9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,7 +8,8 @@ ], "sourceMap": true, "rootDir": "src", - "experimentalDecorators": true + "experimentalDecorators": true, + "noImplicitThis": false // TODO: enable to ensure all code complies with strict coding standards // , "noUnusedLocals": true // , "noUnusedParameters": false diff --git a/tslint.json b/tslint.json index 75d8cad06fc4..7004970518fd 100644 --- a/tslint.json +++ b/tslint.json @@ -49,6 +49,8 @@ "no-import-side-effect": false, "no-string-based-set-timeout": false, "no-floating-promises": false, - "no-empty-interface": false + "no-empty-interface": false, + "no-bitwise": false, + "eofline": true } }