Skip to content

Commit

Permalink
Merge 50a32a2 into 8d50cd8
Browse files Browse the repository at this point in the history
  • Loading branch information
mshima committed Feb 19, 2020
2 parents 8d50cd8 + 50a32a2 commit 04418bc
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 0 deletions.
50 changes: 50 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,56 @@ class Generator extends EventEmitter {
);
}

queueComposedMethod(name, options) {
const property = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(this), name);
if (!property) {
throw new Error(`Property ${name} not found at ${this.options.namespace}`);
}

const method = property.value;
if (typeof method !== 'function') {
throw new Error(`Property ${name} is not a function at ${this.options.namespace}`);
}

const tasks = method.call(this, options);
if (typeof tasks !== 'object') {
throw new Error(
`Function ${name} is not a composed method at ${this.options.namespace}`
);
}

const self = this;
const queueTask = function(task) {
if (!task.method) {
throw new Error(
`Invalid task at composed method ${name} at ${self.options.namespace}`
);
}

if (task.priorityName) {
const priority = self._queues[task.priorityName];
if (!priority) {
throw new Error(`Priority ${task.priorityName} is not defined`);
}

// If priority is defined, use it configs as defaults;
task = { ...priority, ...task };
}

// If run in not defined, set to false to don't start the loop if not running yet
task.run = task.run === undefined ? false : task.run;
self.queueTask(task);
};

if (Array.isArray(tasks)) {
tasks.filter(task => task.method && task.taskName).forEach(queueTask);
return;
}

tasks.taskName = tasks.taskName || name;
queueTask(tasks);
}

/**
* Runs the generator, scheduling prototype methods on a run queue. Method names
* will determine the order each method is run. Methods without special names
Expand Down
111 changes: 111 additions & 0 deletions test/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -1519,6 +1519,117 @@ describe('Base', () => {
});
});

describe('#queueComposedMethod', () => {
it('correctly run queueComposedMethod', function() {
const commonConfiguring = sinon.spy();
const configuring = sinon.spy();

const TestGenerator = class extends Base {
constructor(args, opts) {
super(args, {
...opts,
customPriorities: [{ name: 'commonConfiguring', once: true }]
});
}
};
_.extend(TestGenerator.prototype, {
commonConfiguring: commonConfiguring,

_composed(options) {
return [
{
method: this.commonConfiguring,
taskName: 'commonConfiguring',
priorityName: 'commonConfiguring'
},
{
method: this.commonConfiguring,
taskName: 'commonConfiguring',
priorityName: 'commonConfiguring'
},
{
method: function() {
configuring(options.callNumber);
},
taskName: 'configuring'
}
];
}
});

const testGen = new TestGenerator([], {
resolved: 'unknown',
namespace: 'dummy',
env: this.env,
'skip-install': true
});

testGen.queueComposedMethod('_composed', { callNumber: 1 });
testGen.queueComposedMethod('_composed', { callNumber: 2 });

return testGen.run().then(() => {
sinon.assert.calledOnce(commonConfiguring);
sinon.assert.calledTwice(configuring);
assert.equal(1, configuring.getCall(0).args[0]);
assert.equal(2, configuring.getCall(1).args[0]);
});
});

it("throws if the method doesn't exists", function() {
assert.throws(() => this.dummy.queueComposedMethod('dontExists'), /not found/);
});

describe('throws on errors', function() {
before(function() {
const TestGenerator = class extends Base {};
TestGenerator.prototype.notAFunction = {};
TestGenerator.prototype.returnUndefined = () => {};
TestGenerator.prototype.invalidComposedMethod = () => {
return {};
};

TestGenerator.prototype.invalidPriority = () => {
return { method: () => {}, priorityName: 'dontExists' };
};

this.gen = new TestGenerator([], {
resolved: 'unknown',
namespace: 'dummy',
env: this.env,
'skip-install': true
});
});

it('throws if not a function', function() {
assert.throws(
() => this.gen.queueComposedMethod('notAFunction'),
/not a function/
);
});

it('throws if passed an invalid priority', function() {
assert.throws(
() => this.gen.queueComposedMethod('invalidPriority'),
/Priority (.*) is not defined/
);
});

it('throws if the function returns not an object', function() {
assert.throws(
() => this.gen.queueComposedMethod('returnUndefined'),
/not a composed method/
);
});

it('throws if the function returns a invalid task', function() {
assert.throws(
() => this.gen.queueComposedMethod('invalidComposedMethod'),
/Invalid task at composed method/
);
});
});
});

describe('Custom priorities errors', () => {
it('error is thrown with duplicate custom queue', function() {
const TestGenerator = class extends Base {
Expand Down

0 comments on commit 04418bc

Please sign in to comment.