diff --git a/src/bin/intern.ts b/src/bin/intern.ts index fd4aaffd5..538e62281 100644 --- a/src/bin/intern.ts +++ b/src/bin/intern.ts @@ -20,7 +20,7 @@ getConfig() console.log(getConfigDescription(config)); } else { if (!file) { - console.warn('No config file was loaded'); + console.warn('No config file was loaded, using default one...'); } intern.configure({ reporters: 'runner' }); @@ -29,9 +29,9 @@ getConfig() if ( intern.environment === 'browser' && ((intern.config.suites && - intern.config.suites.some(pattern => pattern.endsWith('.ts'))) || + intern.config.suites.some((pattern) => pattern.endsWith('.ts'))) || (intern.config.plugins && - intern.config.plugins.some(plugin => + intern.config.plugins.some((plugin) => plugin.script.endsWith('.ts') ))) ) { @@ -42,7 +42,7 @@ getConfig() return intern.run(); } }) - .catch(error => { + .catch((error) => { // If intern wasn't initialized, then this error won't have been // reported if (!error.reported) { @@ -76,7 +76,7 @@ function printHelp(config: any, file?: string) { const internConfig = (intern)._config; const opts = Object.keys(internConfig) - .map(key => { + .map((key) => { return { name: key, value: JSON.stringify(internConfig[key]) }; }) .sort((a, b) => { diff --git a/src/index.html b/src/index.html index cfcc57d3a..0d6b71a75 100644 --- a/src/index.html +++ b/src/index.html @@ -32,7 +32,7 @@ } if (!result.file) { - console.warn('No config file was found'); + console.warn('No config file was found, using default one...'); } // Add the HTML and console reporters to the default diff --git a/src/lib/browser/util.ts b/src/lib/browser/util.ts index f58ac50b4..23b1c137c 100644 --- a/src/lib/browser/util.ts +++ b/src/lib/browser/util.ts @@ -1,10 +1,11 @@ import { request, CancellablePromise, global } from '@theintern/common'; import { + createDefaultConfig, getBasePath, loadConfig, parseArgs, - splitConfigPath + splitConfigPath, } from '../common/util'; /** @@ -30,31 +31,32 @@ export function getConfig(file?: string) { // If no config parameter was provided, try 'intern.json'. If that file // doesn't exist, just return the args file = resolvePath('intern.json', configBase); - load = loadConfig(file, loadText, args).catch(error => { + load = loadConfig(file, loadText, args).catch((error) => { if (error.message.indexOf('Request failed') === 0) { // The file wasn't found, clear the file name file = undefined; - return args; + return getSuitesExtension(configBase).then((extension) => + createDefaultConfig(args, extension) + ); } - throw error; }); } return load - .then(config => { + .then((config) => { // If a basePath wasn't set in the config or via a query arg, and we // have a config file path, use that. if (file) { config.basePath = getBasePath( file, config.basePath, - path => path[0] === '/', + (path) => path[0] === '/', '/' ); } return config; }) - .then(config => ({ config, file })); + .then((config) => ({ config, file })); } /** @@ -138,9 +140,10 @@ export type Url = { }; export function parseUrl(url: string): Url | undefined { if (url) { - const match = /^(([^:\/?#]+):)?(\/\/(([^:\/?#]*)(:(\d+))?))?([^?#]*)(\?([^#]*))?(#(.*))?/.exec( - url - ); + const match = + /^(([^:\/?#]+):)?(\/\/(([^:\/?#]*)(:(\d+))?))?([^?#]*)(\?([^#]*))?(#(.*))?/.exec( + url + ); if (match) { return { protocol: match[2], @@ -148,7 +151,7 @@ export function parseUrl(url: string): Url | undefined { port: match[7], path: match[8], query: match[10], - hash: match[12] + hash: match[12], }; } } @@ -158,7 +161,7 @@ export function parseUrl(url: string): Url | undefined { * Load a text resource */ function loadText(path: string): CancellablePromise { - return request(path).then(response => { + return request(path).then((response) => { if (!response.ok) { throw new Error('Request failed: ' + response.status); } @@ -191,3 +194,13 @@ function resolvePath(path: string, basePath: string) { return basePathParts.join('/'); } + +async function getSuitesExtension(basePath: string) { + return existsAsync(resolvePath('tsconfig.json', basePath)).then( + (tsconfigExists) => (tsconfigExists ? 'ts' : 'js') + ); +} + +async function existsAsync(filePath: string) { + return request(filePath, { method: 'HEAD' }).then((response) => response.ok); +} diff --git a/src/lib/common/util.ts b/src/lib/common/util.ts index 7d48e6900..a9bc586c3 100644 --- a/src/lib/common/util.ts +++ b/src/lib/common/util.ts @@ -799,6 +799,18 @@ export function setOption( } } +/** + * Create a default config to make zero-config running possible + */ +export function createDefaultConfig(baseConfig: any, suitesExtension: string) { + let config = Object.assign({}, baseConfig); + config.suites = [ + `tests/**/*.${suitesExtension}`, + `src/**/*.spec.${suitesExtension}`, + ]; + return config; +} + /** * Split a config path into a file name and a child config name. * diff --git a/src/lib/node/util.ts b/src/lib/node/util.ts index 0c002a12e..3fbced391 100644 --- a/src/lib/node/util.ts +++ b/src/lib/node/util.ts @@ -6,7 +6,7 @@ import { join, normalize, resolve, - sep + sep, } from 'path'; import { parse } from 'shell-quote'; import { RawSourceMap } from 'source-map'; @@ -16,10 +16,11 @@ import { Task, CancellablePromise } from '@theintern/common'; import process from './process'; import { + createDefaultConfig, getBasePath, loadConfig, parseArgs, - splitConfigPath + splitConfigPath, } from '../common/util'; /** * Expand a list of glob patterns into a flat file list. Patterns may be simple @@ -50,10 +51,10 @@ export function expandFiles(patterns?: string[] | string) { } const allPaths = includes - .map(pattern => glob(pattern, { ignore: excludes })) + .map((pattern) => glob(pattern, { ignore: excludes })) .reduce((allFiles, files) => allFiles.concat(files), paths); const uniquePaths: { [name: string]: boolean } = {}; - allPaths.forEach(path => (uniquePaths[path] = true)); + allPaths.forEach((path) => (uniquePaths[path] = true)); return Object.keys(uniquePaths); } @@ -116,15 +117,14 @@ export function getConfig( (error: NodeJS.ErrnoException) => { if (error.code === 'ENOENT') { file = undefined; - return args; + return createDefaultConfig(args, getSuitesExtension()); } - throw error; } ); } return load - .then(config => { + .then((config) => { // If a basePath wasn't set in the config or via a query arg, and we // have a config file path, use that. if (file) { @@ -132,7 +132,7 @@ export function getConfig( } return config; }) - .then(config => ({ config, file })); + .then((config) => ({ config, file })); } /** @@ -213,7 +213,7 @@ export function transpileSource(filename: string, code: string) { { _compile(source: string) { code = source; - } + }, } as any, filename ); @@ -222,4 +222,9 @@ export function transpileSource(filename: string, code: string) { } // Regex for matching sourceMappingUrl comments -const sourceMapRegEx = /^(?:\/{2}[#@]{1,2}|\/\*)\s+sourceMappingURL\s*=\s*(data:(?:[^;]+;)+base64,)?(\S+)/; +const sourceMapRegEx = + /^(?:\/{2}[#@]{1,2}|\/\*)\s+sourceMappingURL\s*=\s*(data:(?:[^;]+;)+base64,)?(\S+)/; + +function getSuitesExtension() { + return existsSync(resolve('tsconfig.json')) ? 'ts' : 'js'; +}