Search code examples
javascripttestingyeomanyeoman-generator

What can yeoman's withGenerators test helper be used for?


I've been creating a lot of tests for yeoman generators lately, and I'm having trouble understanding the purpose of the withGenerators() helper method.

The example given:

var angular = new RunContext('../../app');
 angular.withGenerators([
   '../../common',
   '../../controller',
   '../../main',
   [helpers.createDummyGenerator(), 'testacular:app']
 ]);

The function itself:

RunContext.prototype.withGenerators = function (dependencies) {
  assert(_.isArray(dependencies), 'dependencies should be an array');
  this.dependencies = this.dependencies.concat(dependencies);
  return this;
};

I see that the function adds an array of dependencies to the Run Context object, with each item in the array being a path to a dependent generator.

What are these paths used for?

When and why would I need to use this method?

In the example given, is calling angular.withGenerators([...]) identical to calling yo angular, yo angular:common, yo angular:controller, and so on from the command line, or does it somehow simulate or modify calls to composeWith() in the actual generator?

What is the difference between running withGenerators() in the tests, and calling composeWith() from the generator itself?


Solution

  • This is used for composeWith() (or the legacy invoke() and hookFor() methods).

    You can see the relevant code here: https://github.com/yeoman/yeoman-test/blob/master/lib/index.js#L173-L188

    Basically when calling composeWith(), it'll use the dummy generator mock you passed instead of the one the environment would resolve.

    A tricky part at the moment is that if you pass the local path settings to composeWith, it'll ignore the stubs - you can see the bug filled here https://github.com/yeoman/generator/issues/704 (the ticket suggests some manual workarounds)