helpers.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. var fs = require('fs');
  2. var path = require('path');
  3. var rimraf = require('rimraf');
  4. var mkdirp = require('mkdirp');
  5. var util = require('util');
  6. var assert = require('assert');
  7. var generators = require('../..');
  8. // Mocha helpers
  9. var helpers = module.exports;
  10. helpers.stubs = [];
  11. // cleanup the test dir, and cd into it
  12. helpers.before = function before(dir) {
  13. if (!dir) {
  14. throw new Error('Missing directory');
  15. }
  16. dir = path.resolve(dir);
  17. return function (done) {
  18. rimraf(dir, function (err) {
  19. if (err) {
  20. return done(err);
  21. }
  22. mkdirp.sync(dir);
  23. process.chdir(dir);
  24. helpers.gruntfile({ dummy: true }, done);
  25. });
  26. };
  27. };
  28. // Wrap a method with custom functionality.
  29. //
  30. // - context - (object) context to find the original method
  31. // - method - (string) name of the method to wrap
  32. // - replacement - (function) executes before the original method
  33. // - options - (opt) (object) config settings
  34. helpers.decorate = function decorate(context, method, replacement, options) {
  35. options = options || {};
  36. replacement = replacement || function () {};
  37. var naturalMethod = context[method];
  38. helpers.stubs.push({
  39. context: context,
  40. method: method,
  41. naturalMethod: naturalMethod
  42. });
  43. context[method] = function () {
  44. var rep = replacement.apply(context, arguments);
  45. if (!options.stub) {
  46. naturalMethod.apply(context, arguments);
  47. }
  48. return rep;
  49. };
  50. };
  51. // Override a method with custom functionality.
  52. //
  53. // - context - (object) context to find the original method
  54. // - method - (string) name of the method to wrap
  55. // - replacement - (function) executes before the original method
  56. helpers.stub = function stub(context, method, replacement) {
  57. helpers.decorate(context, method, replacement, { stub: true });
  58. };
  59. // Restore all stubs with original behavior.
  60. helpers.restore = function restore() {
  61. helpers.stubs.forEach(function (stub) {
  62. stub.context[stub.method] = stub.naturalMethod;
  63. });
  64. };
  65. // Generates a new Gruntfile.js in the current working directory based on
  66. // `options` hash passed in. Same as other helpers, meant to be use as a mocha
  67. // handler.
  68. //
  69. // - options - Grunt configuration
  70. // - done - callback to call on completion
  71. //
  72. // Example
  73. //
  74. // before(helpers.gruntfile({
  75. // foo: {
  76. // bar: '<config.baz>'
  77. // }
  78. // }));
  79. //
  80. // Returns a function suitable to use with mocha hooks.
  81. helpers.gruntfile = function (options, done) {
  82. var config = 'grunt.initConfig(' + JSON.stringify(options, null, 2) + ');';
  83. config = config.split('\n').map(function (line) {
  84. return ' ' + line;
  85. }).join('\n');
  86. var out = [
  87. 'module.exports = function (grunt) {',
  88. config,
  89. '};'
  90. ];
  91. fs.writeFile('Gruntfile.js', out.join('\n'), done);
  92. };
  93. helpers.assertFile = function (file, reg) {
  94. var here = fs.existsSync(file);
  95. assert.ok(here, file + ', no such file or directory');
  96. if (!reg) {
  97. return assert.ok(here);
  98. }
  99. var body = fs.readFileSync(file, 'utf8');
  100. assert.ok(reg.test(body), file + ' did not match \'' + reg + '\'.');
  101. };
  102. // Check all files present in the array are existing.
  103. // If the item is an array first item is the file path, 2nd a regexp
  104. // to check file content with
  105. //
  106. // helpers.assertFiles(['foo.js', 'bar.js', ['baz.js', /function baz/]]);
  107. //
  108. helpers.assertFiles = function (files) {
  109. files.forEach(function (item) {
  110. var file = item;
  111. var rx;
  112. if (item instanceof Array) {
  113. file = item[0];
  114. rx = item[1];
  115. }
  116. helpers.assertFile(file, rx);
  117. });
  118. };
  119. // Clean-up the test directory and ce into it.
  120. // Call given callback when you're there.
  121. //
  122. helpers.testDirectory = function (dir, cb) {
  123. if (!dir) {
  124. throw new Error('Missing directory');
  125. }
  126. dir = path.resolve(dir);
  127. rimraf(dir, function (err) {
  128. if (err) {
  129. return cb(err);
  130. }
  131. mkdirp.sync(dir);
  132. process.chdir(dir);
  133. cb();
  134. });
  135. };
  136. // Will answer to the questions for the furnished generator
  137. //
  138. // Example:
  139. // mockPrompt(angular, {'bootstrap': 'Y', 'compassBoostrap': 'Y'});
  140. //
  141. helpers.mockPrompt = function (generator, answers) {
  142. var origPrompt = generator.prompt;
  143. generator.prompt = function (prompts, done) {
  144. done(answers);
  145. };
  146. generator.origPrompt = origPrompt;
  147. };
  148. //
  149. // Create a simple, dummy generator
  150. //
  151. helpers.createDummyGenerator = function () {
  152. var dummy = function Dummy() {
  153. generators.Base.apply(this, arguments);
  154. };
  155. util.inherits(dummy, generators.Base);
  156. dummy.prototype.test = function () {
  157. this.shouldRun = true;
  158. };
  159. return dummy;
  160. };
  161. // Create a generator, using the given dependencies and controller arguments
  162. // Dependecies can be path (autodiscovery) or an array [<generator>, <name>]
  163. //
  164. // Example:
  165. // var deps = ['../../app',
  166. // '../../common',
  167. // '../../controller',
  168. // '../../main',
  169. // [createDummyGenerator(), 'testacular:app']
  170. // ];
  171. // var angular = createGenerator('angular:app', deps);
  172. //
  173. helpers.createGenerator = function (name, dependencies, args) {
  174. var env = generators();
  175. dependencies.forEach(function (d) {
  176. if (d instanceof Array) {
  177. env.register(d[0], d[1]);
  178. } else {
  179. env.register(d);
  180. }
  181. });
  182. var generator = env.create(name, {arguments: args});
  183. generator.on('start', env.emit.bind(this, 'generators:start'));
  184. generator.on('start', env.emit.bind(this, name + ':start'));
  185. generator.on('method', function (method) {
  186. env.emit(name + ':' + method);
  187. });
  188. generator.on('end', env.emit.bind(this, name + ':end'));
  189. generator.on('end', env.emit.bind(this, 'generators:end'));
  190. return generator;
  191. };