Permalink
Browse files

fix(core): fixes maximum call stack size reached in @step

affects: serenity-js

ISSUES CLOSED: #38
  • Loading branch information...
jan-molak committed May 3, 2017
1 parent 0b15563 commit 1a8ad0f4382849eb57257f4e9d936ac67a57c2c9
@@ -26,7 +26,6 @@ describe('Description of an Activity', () => {
}
given(
[ describe_as('name: {0}', 'John'), 'name: John' ],
[ describe_as('{1}, {0}; age: {2}', 'John', 'Smith', 47), 'Smith, John; age: 47' ],
[ describe_as('{0} selects a product', Actor.named('Emma')), 'Emma selects a product' ],
[ describe_as('#actor selects a product', Actor.named('Emma')), 'Emma selects a product' ],
@@ -46,6 +45,7 @@ describe('Description of an Activity', () => {
it ('interpolates field tokens before taking argument tokens into consideration', () => {
const activity = {
products: () => ['apples', 'oranges'],
performAs: (actor: PerformsTasks) => actor.attemptsTo(),
toString: () => describe_as('{0} adds #products to the basket', activity),
};
@@ -159,6 +159,28 @@ describe('Notifiers', () => {
expect(lastEntry.value.result).to.equal(Result.ERROR);
}));
});
describe('Automatic migration from @step to toString()', () => {
class AnnotatedTask implements Task {
private style = 'annotated';
@step('{0} performs an #style task')
performAs(actor: PerformsTasks): PromiseLike<void> {
return actor.attemptsTo(/* perform some tasks */);
}
}
it ('adds a toString() method to the task if it is not present', () => {
const task = new AnnotatedTask();
return expect(bruce.attemptsTo(task)).to.be.fulfilled.then(() => {
expect(task.toString()).to.equal('{0} performs an annotated task');
});
});
});
});
});
@@ -1,22 +1,22 @@
import { Activity } from '../screenplay/activities';
import { Actor } from '../screenplay/actor';
export function describe_as(template: string, ...parameters: any[]): string {
const isActor = (candidate: any) => candidate instanceof Actor;
const
argument_tokens = /{(\d+)}/g,
field_tokens = /#(\w+)/g,
actor_token = '#actor',
actor_name = parameters[0] instanceof Actor ? parameters[0] : actor_token;
const using = (source: any) => (token: string, field: string|number) => stringify(token, source[field]);
const interpolated = field_tokens.test(template)
? template.replace(field_tokens, using(parameters[0]))
: template.replace(argument_tokens, using(parameters));
const includeActorName = (template: string, actor: Actor) => template.replace('#actor', actor.toString());
const interpolateArguments = (template: string, parameters: any[]) => template.replace(/{(\d+)}/g, using(parameters));
const interpolateFields = (template: string, activity: Activity) => template.replace(/#(\w+)/g, using(activity));
return interpolated.replace(actor_token, actor_name);
}
export function describe_as(template: string, ...parameters: any[]): string {
const first: any = parameters[0];
function using(source: any) {
return (token: string, field: string|number) => stringify(token, source[field]);
switch (true) {
case parameters.length > 1: return interpolateArguments(template, parameters);
case isActor(first): return includeActorName(interpolateArguments(template, parameters), first);
default: return interpolateFields(template, first);
}
}
function stringify(token: string, value: any): string {

0 comments on commit 1a8ad0f

Please sign in to comment.