123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- const path = require('path');
- const fs = require('fs');
- exports = module.exports = Command;
- const subCommands = {
- init: {
- description: 'initialize jasmine',
- action: initJasmine
- },
- examples: {
- description: 'install examples',
- action: installExamples
- },
- help: {
- description: 'show help',
- action: help,
- alias: '-h'
- },
- version: {
- description: 'show jasmine and jasmine-core versions',
- action: version,
- alias: '-v'
- }
- };
- function Command(projectBaseDir, examplesDir, deps) {
- const {print, platform} = deps;
- const isWindows = platform() === 'win32';
- this.projectBaseDir = isWindows ? unWindows(projectBaseDir) : projectBaseDir;
- this.specDir = `${this.projectBaseDir}/spec`;
- const command = this;
- this.run = async function(jasmine, commands) {
- setEnvironmentVariables(commands);
- let commandToRun;
- Object.keys(subCommands).forEach(function(cmd) {
- const commandObject = subCommands[cmd];
- if (commands.indexOf(cmd) >= 0) {
- commandToRun = commandObject;
- } else if(commandObject.alias && commands.indexOf(commandObject.alias) >= 0) {
- commandToRun = commandObject;
- }
- });
- if (commandToRun) {
- commandToRun.action({jasmine: jasmine, projectBaseDir: command.projectBaseDir, specDir: command.specDir, examplesDir: examplesDir, print: print});
- } else {
- const env = parseOptions(commands, isWindows);
- if (env.unknownOptions.length > 0) {
- process.exitCode = 1;
- print('Unknown options: ' + env.unknownOptions.join(', '));
- print('');
- help({print: print});
- } else {
- await runJasmine(jasmine, env);
- }
- }
- };
- }
- function isFileArg(arg) {
- return arg.indexOf('--') !== 0 && !isEnvironmentVariable(arg);
- }
- function parseOptions(argv, isWindows) {
- let files = [],
- helpers = [],
- requires = [],
- unknownOptions = [],
- color = process.stdout.isTTY || false,
- reporter,
- configPath,
- filter,
- failFast,
- random,
- seed;
- for (const arg of argv) {
- if (arg === '--no-color') {
- color = false;
- } else if (arg === '--color') {
- color = true;
- } else if (arg.match("^--filter=")) {
- filter = arg.match("^--filter=(.*)")[1];
- } else if (arg.match("^--helper=")) {
- helpers.push(arg.match("^--helper=(.*)")[1]);
- } else if (arg.match("^--require=")) {
- requires.push(arg.match("^--require=(.*)")[1]);
- } else if (arg === '--fail-fast') {
- failFast = true;
- } else if (arg.match("^--random=")) {
- random = arg.match("^--random=(.*)")[1] === 'true';
- } else if (arg.match("^--seed=")) {
- seed = arg.match("^--seed=(.*)")[1];
- } else if (arg.match("^--config=")) {
- configPath = arg.match("^--config=(.*)")[1];
- } else if (arg.match("^--reporter=")) {
- reporter = arg.match("^--reporter=(.*)")[1];
- } else if (arg === '--') {
- break;
- } else if (isFileArg(arg)) {
- files.push(isWindows ? unWindows(arg) : arg);
- } else if (!isEnvironmentVariable(arg)) {
- unknownOptions.push(arg);
- }
- }
- return {
- color,
- configPath,
- filter,
- failFast,
- helpers,
- requires,
- reporter,
- files,
- random,
- seed,
- unknownOptions
- };
- }
- async function runJasmine(jasmine, options) {
- await jasmine.loadConfigFile(options.configPath || process.env.JASMINE_CONFIG_PATH);
- if (options.failFast !== undefined) {
- jasmine.env.configure({
- stopSpecOnExpectationFailure: options.failFast,
- stopOnSpecFailure: options.failFast
- });
- }
- if (options.seed !== undefined) {
- jasmine.seed(options.seed);
- }
- if (options.random !== undefined) {
- jasmine.randomizeTests(options.random);
- }
- if (options.helpers !== undefined && options.helpers.length) {
- jasmine.addMatchingHelperFiles(options.helpers);
- }
- if (options.requires !== undefined && options.requires.length) {
- jasmine.addRequires(options.requires);
- }
- if (options.reporter !== undefined) {
- await registerReporter(options.reporter, jasmine);
- }
- jasmine.showColors(options.color);
- try {
- await jasmine.execute(options.files, options.filter);
- } catch (error) {
- console.error(error);
- process.exit(1);
- }
- }
- async function registerReporter(reporterModuleName, jasmine) {
- let Reporter;
- try {
- Reporter = await jasmine.loader.load(resolveReporter(reporterModuleName));
- } catch (e) {
- throw new Error('Failed to load reporter module '+ reporterModuleName +
- '\nUnderlying error: ' + e.stack + '\n(end underlying error)');
- }
- let reporter;
- try {
- reporter = new Reporter();
- } catch (e) {
- throw new Error('Failed to instantiate reporter from '+ reporterModuleName +
- '\nUnderlying error: ' + e.stack + '\n(end underlying error)');
- }
- jasmine.clearReporters();
- jasmine.addReporter(reporter);
- }
- function resolveReporter(nameOrPath) {
- if (nameOrPath.startsWith('./') || nameOrPath.startsWith('../')) {
- return path.resolve(nameOrPath);
- } else {
- return nameOrPath;
- }
- }
- function initJasmine(options) {
- const print = options.print;
- const specDir = options.specDir;
- makeDirStructure(path.join(specDir, 'support/'));
- if(!fs.existsSync(path.join(specDir, 'support/jasmine.json'))) {
- fs.writeFileSync(path.join(specDir, 'support/jasmine.json'), fs.readFileSync(path.join(__dirname, '../lib/examples/jasmine.json'), 'utf-8'));
- }
- else {
- print('spec/support/jasmine.json already exists in your project.');
- }
- }
- function installExamples(options) {
- const specDir = options.specDir;
- const projectBaseDir = options.projectBaseDir;
- const examplesDir = options.examplesDir;
- makeDirStructure(path.join(specDir, 'support'));
- makeDirStructure(path.join(specDir, 'jasmine_examples'));
- makeDirStructure(path.join(specDir, 'helpers', 'jasmine_examples'));
- makeDirStructure(path.join(projectBaseDir, 'lib', 'jasmine_examples'));
- copyFiles(
- path.join(examplesDir, 'spec', 'helpers', 'jasmine_examples'),
- path.join(specDir, 'helpers', 'jasmine_examples'),
- new RegExp(/[Hh]elper\.js/)
- );
- copyFiles(
- path.join(examplesDir, 'lib', 'jasmine_examples'),
- path.join(projectBaseDir, 'lib', 'jasmine_examples'),
- new RegExp(/\.js/)
- );
- copyFiles(
- path.join(examplesDir, 'spec', 'jasmine_examples'),
- path.join(specDir, 'jasmine_examples'),
- new RegExp(/[Ss]pec.js/)
- );
- }
- function help(options) {
- const print = options.print;
- print('Usage: jasmine [command] [options] [files] [--]');
- print('');
- print('Commands:');
- Object.keys(subCommands).forEach(function(cmd) {
- let commandNameText = cmd;
- if(subCommands[cmd].alias) {
- commandNameText = commandNameText + ',' + subCommands[cmd].alias;
- }
- print('%s\t%s', lPad(commandNameText, 10), subCommands[cmd].description);
- });
- print('');
- print('If no command is given, jasmine specs will be run');
- print('');
- print('');
- print('Options:');
- print('%s\tturn off color in spec output', lPad('--no-color', 18));
- print('%s\tforce turn on color in spec output', lPad('--color', 18));
- print('%s\tfilter specs to run only those that match the given string', lPad('--filter=', 18));
- print('%s\tload helper files that match the given string', lPad('--helper=', 18));
- print('%s\tload module that match the given string', lPad('--require=', 18));
- print('%s\tstop Jasmine execution on spec failure', lPad('--fail-fast', 18));
- print('%s\tpath to your optional jasmine.json', lPad('--config=', 18));
- print('%s\tpath to reporter to use instead of the default Jasmine reporter', lPad('--reporter=', 18));
- print('%s\tmarker to signal the end of options meant for Jasmine', lPad('--', 18));
- print('');
- print('The given arguments take precedence over options in your jasmine.json');
- print('The path to your optional jasmine.json can also be configured by setting the JASMINE_CONFIG_PATH environment variable');
- }
- function version(options) {
- const print = options.print;
- print('jasmine v' + require('../package.json').version);
- print('jasmine-core v' + options.jasmine.coreVersion());
- }
- function lPad(str, length) {
- if (str.length >= length) {
- return str;
- } else {
- return lPad(' ' + str, length);
- }
- }
- function copyFiles(srcDir, destDir, pattern) {
- const srcDirFiles = fs.readdirSync(srcDir);
- srcDirFiles.forEach(function(file) {
- if (file.search(pattern) !== -1) {
- fs.writeFileSync(path.join(destDir, file), fs.readFileSync(path.join(srcDir, file)));
- }
- });
- }
- function makeDirStructure(absolutePath) {
- const splitPath = absolutePath.split(path.sep);
- splitPath.forEach(function(dir, index) {
- if(index > 1) {
- const fullPath = path.join(splitPath.slice(0, index).join('/'), dir);
- if (!fs.existsSync(fullPath)) {
- fs.mkdirSync(fullPath);
- }
- }
- });
- }
- function isEnvironmentVariable(command) {
- const envRegExp = /(.*)=(.*)/;
- return command.match(envRegExp);
- }
- function setEnvironmentVariables(commands) {
- commands.forEach(function (command) {
- const regExpMatch = isEnvironmentVariable(command);
- if(regExpMatch) {
- const key = regExpMatch[1];
- const value = regExpMatch[2];
- process.env[key] = value;
- }
- });
- }
- // Future versions of glob will interpret backslashes as escape sequences on
- // all platforms, and Jasmine warns about them. Convert to slashes to avoid
- // the warning and future behavior change. Should only be called when running
- // on Windows.
- function unWindows(projectBaseDir) {
- return projectBaseDir.replace(/\\/g, '/');
- }
|