command.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. var path = require('path'),
  2. fs = require('fs');
  3. exports = module.exports = Command;
  4. var subCommands = {
  5. init: {
  6. description: 'initialize jasmine',
  7. action: initJasmine
  8. },
  9. examples: {
  10. description: 'install examples',
  11. action: installExamples
  12. },
  13. help: {
  14. description: 'show help',
  15. action: help,
  16. alias: '-h'
  17. },
  18. version: {
  19. description: 'show jasmine and jasmine-core versions',
  20. action: version,
  21. alias: '-v'
  22. }
  23. };
  24. function Command(projectBaseDir, examplesDir, print) {
  25. this.projectBaseDir = projectBaseDir;
  26. this.specDir = path.join(projectBaseDir, 'spec');
  27. var command = this;
  28. this.run = function(jasmine, commands) {
  29. setEnvironmentVariables(commands);
  30. var commandToRun;
  31. Object.keys(subCommands).forEach(function(cmd) {
  32. var commandObject = subCommands[cmd];
  33. if (commands.indexOf(cmd) >= 0) {
  34. commandToRun = commandObject;
  35. } else if(commandObject.alias && commands.indexOf(commandObject.alias) >= 0) {
  36. commandToRun = commandObject;
  37. }
  38. });
  39. if (commandToRun) {
  40. commandToRun.action({jasmine: jasmine, projectBaseDir: command.projectBaseDir, specDir: command.specDir, examplesDir: examplesDir, print: print});
  41. } else {
  42. var env = parseOptions(commands);
  43. if (env.unknownOptions.length > 0) {
  44. print('Unknown options: ' + env.unknownOptions.join(', '));
  45. print('');
  46. help({print: print});
  47. } else {
  48. runJasmine(jasmine, env);
  49. }
  50. }
  51. };
  52. }
  53. function isFileArg(arg) {
  54. return arg.indexOf('--') !== 0 && !isEnvironmentVariable(arg);
  55. }
  56. function parseOptions(argv) {
  57. var files = [],
  58. helpers = [],
  59. unknownOptions = [],
  60. color = process.stdout.isTTY || false,
  61. configPath,
  62. filter,
  63. stopOnFailure,
  64. random,
  65. seed;
  66. argv.forEach(function(arg) {
  67. if (arg === '--no-color') {
  68. color = false;
  69. } else if (arg.match("^--filter=")) {
  70. filter = arg.match("^--filter=(.*)")[1];
  71. } else if (arg.match("^--helper=")) {
  72. helpers.push(arg.match("^--helper=(.*)")[1]);
  73. } else if (arg.match("^--stop-on-failure=")) {
  74. stopOnFailure = arg.match("^--stop-on-failure=(.*)")[1] === 'true';
  75. } else if (arg.match("^--random=")) {
  76. random = arg.match("^--random=(.*)")[1] === 'true';
  77. } else if (arg.match("^--seed=")) {
  78. seed = arg.match("^--seed=(.*)")[1];
  79. } else if (arg.match("^--config=")) {
  80. configPath = arg.match("^--config=(.*)")[1];
  81. } else if (isFileArg(arg)) {
  82. files.push(arg);
  83. } else if (!isEnvironmentVariable(arg)) {
  84. unknownOptions.push(arg);
  85. }
  86. });
  87. return {
  88. color: color,
  89. configPath: configPath,
  90. filter: filter,
  91. stopOnFailure: stopOnFailure,
  92. helpers: helpers,
  93. files: files,
  94. random: random,
  95. seed: seed,
  96. unknownOptions: unknownOptions
  97. };
  98. }
  99. function runJasmine(jasmine, env) {
  100. jasmine.loadConfigFile(env.configPath || process.env.JASMINE_CONFIG_PATH);
  101. if (env.stopOnFailure !== undefined) {
  102. jasmine.stopSpecOnExpectationFailure(env.stopOnFailure);
  103. }
  104. if (env.seed !== undefined) {
  105. jasmine.seed(env.seed);
  106. }
  107. if (env.random !== undefined) {
  108. jasmine.randomizeTests(env.random);
  109. }
  110. if (env.helpers !== undefined && env.helpers.length) {
  111. jasmine.addHelperFiles(env.helpers);
  112. }
  113. jasmine.showColors(env.color);
  114. jasmine.execute(env.files, env.filter);
  115. }
  116. function initJasmine(options) {
  117. var print = options.print;
  118. var specDir = options.specDir;
  119. makeDirStructure(path.join(specDir, 'support/'));
  120. if(!fs.existsSync(path.join(specDir, 'support/jasmine.json'))) {
  121. fs.writeFileSync(path.join(specDir, 'support/jasmine.json'), fs.readFileSync(path.join(__dirname, '../lib/examples/jasmine.json'), 'utf-8'));
  122. }
  123. else {
  124. print('spec/support/jasmine.json already exists in your project.');
  125. }
  126. }
  127. function installExamples(options) {
  128. var specDir = options.specDir;
  129. var projectBaseDir = options.projectBaseDir;
  130. var examplesDir = options.examplesDir;
  131. makeDirStructure(path.join(specDir, 'support'));
  132. makeDirStructure(path.join(specDir, 'jasmine_examples'));
  133. makeDirStructure(path.join(specDir, 'helpers', 'jasmine_examples'));
  134. makeDirStructure(path.join(projectBaseDir, 'lib', 'jasmine_examples'));
  135. copyFiles(
  136. path.join(examplesDir, 'spec', 'helpers', 'jasmine_examples'),
  137. path.join(specDir, 'helpers', 'jasmine_examples'),
  138. new RegExp(/[Hh]elper\.js/)
  139. );
  140. copyFiles(
  141. path.join(examplesDir, 'lib', 'jasmine_examples'),
  142. path.join(projectBaseDir, 'lib', 'jasmine_examples'),
  143. new RegExp(/\.js/)
  144. );
  145. copyFiles(
  146. path.join(examplesDir, 'spec', 'jasmine_examples'),
  147. path.join(specDir, 'jasmine_examples'),
  148. new RegExp(/[Ss]pec.js/)
  149. );
  150. }
  151. function help(options) {
  152. var print = options.print;
  153. print('Usage: jasmine [command] [options] [files]');
  154. print('');
  155. print('Commands:');
  156. Object.keys(subCommands).forEach(function(cmd) {
  157. var commandNameText = cmd;
  158. if(subCommands[cmd].alias) {
  159. commandNameText = commandNameText + ',' + subCommands[cmd].alias;
  160. }
  161. print('%s\t%s', lPad(commandNameText, 10), subCommands[cmd].description);
  162. });
  163. print('');
  164. print('If no command is given, jasmine specs will be run');
  165. print('');
  166. print('');
  167. print('Options:');
  168. print('%s\tturn off color in spec output', lPad('--no-color', 18));
  169. print('%s\tfilter specs to run only those that match the given string', lPad('--filter=', 18));
  170. print('%s\tload helper files that match the given string', lPad('--helper=', 18));
  171. print('%s\t[true|false] stop spec execution on expectation failure', lPad('--stop-on-failure=', 18));
  172. print('%s\tpath to your optional jasmine.json', lPad('--config=', 18));
  173. print('');
  174. print('The given arguments take precedence over options in your jasmine.json');
  175. print('The path to your optional jasmine.json can also be configured by setting the JASMINE_CONFIG_PATH environment variable');
  176. }
  177. function version(options) {
  178. var print = options.print;
  179. print('jasmine v' + require('../package.json').version);
  180. print('jasmine-core v' + options.jasmine.coreVersion());
  181. }
  182. function lPad(str, length) {
  183. if (str.length >= length) {
  184. return str;
  185. } else {
  186. return lPad(' ' + str, length);
  187. }
  188. }
  189. function copyFiles(srcDir, destDir, pattern) {
  190. var srcDirFiles = fs.readdirSync(srcDir);
  191. srcDirFiles.forEach(function(file) {
  192. if (file.search(pattern) !== -1) {
  193. fs.writeFileSync(path.join(destDir, file), fs.readFileSync(path.join(srcDir, file)));
  194. }
  195. });
  196. }
  197. function makeDirStructure(absolutePath) {
  198. var splitPath = absolutePath.split(path.sep);
  199. splitPath.forEach(function(dir, index) {
  200. if(index > 1) {
  201. var fullPath = path.join(splitPath.slice(0, index).join('/'), dir);
  202. if (!fs.existsSync(fullPath)) {
  203. fs.mkdirSync(fullPath);
  204. }
  205. }
  206. });
  207. }
  208. function isEnvironmentVariable(command) {
  209. var envRegExp = /(.*)=(.*)/;
  210. return command.match(envRegExp);
  211. }
  212. function setEnvironmentVariables(commands) {
  213. commands.forEach(function (command) {
  214. var regExpMatch = isEnvironmentVariable(command);
  215. if(regExpMatch) {
  216. var key = regExpMatch[1];
  217. var value = regExpMatch[2];
  218. process.env[key] = value;
  219. }
  220. });
  221. }