Skip to content

Commit

Permalink
Add OneOf sequence
Browse files Browse the repository at this point in the history
  • Loading branch information
Noah Bogart committed Jul 9, 2020
1 parent 4d531cf commit dec29c2
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 23 deletions.
27 changes: 15 additions & 12 deletions lib/definition-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,13 @@ import {ImplicitDeclaration} from "./declarations/implicit-declaration";
import {Trait} from "./trait";
import {Definition} from "./definition";
import {Fixture} from "./fixture";
import {
blockFunction,
FixtureOptions,
} from "./fixture-options-parser";
import {blockFunction, FixtureOptions} from "./fixture-options-parser";
import {callbackFunction} from "./callback";
import {FixtureRiveter} from "./fixture-riveter";
import {
Sequence,
SequenceCallback,
} from "./sequences/sequence";
import {SequenceHandler} from "./sequence-handler";

import {SequenceCallback} from "./sequences/sequence";
import {OneOfSequence} from "./sequences/one-of-sequence";
import {SequenceHandler, optionsParser} from "./sequence-handler";

import {isFunction, last} from "lodash";

Expand Down Expand Up @@ -84,12 +80,19 @@ export class DefinitionProxy {
sequence(
name: string,
initial?: string | number | {aliases: string[]} | SequenceCallback,
): Sequence;
): void;

sequence(name: string, ...rest: any[]): Sequence {
sequence(name: string, ...rest: any[]): void {
const sequence = this.sequenceHandler.registerSequence(name, ...rest);
this.attr(name, () => sequence.next());
return sequence;
}

oneOf(name: string, choices: any[]): void;
oneOf(name: string, choices: any[], ...rest: any[]): void {
const options = optionsParser(...rest);
const sequence = new OneOfSequence(name, choices, options);
this.sequenceHandler.sequences.push(sequence);
this.attr(name, () => sequence.next());
}

trait(name: string, block?: blockFunction): void {
Expand Down
13 changes: 12 additions & 1 deletion lib/fixture-riveter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ import {
Sequence,
SequenceCallback,
} from "./sequences/sequence";
import {SequenceHandler} from "./sequence-handler";
import {OneOfSequence} from "./sequences/one-of-sequence";
import {
optionsParser,
SequenceHandler,
} from "./sequence-handler";
import {Trait} from "./trait";
import {
callbackFunction,
Expand Down Expand Up @@ -161,6 +165,13 @@ export class FixtureRiveter {
}
}

oneOf(name: string, choices: any[]): void;
oneOf(name: string, choices: any[], ...rest: any[]): void {
const options = optionsParser(...rest);
const sequence = new OneOfSequence(name, choices, options);
this.sequenceHandler.sequences.push(sequence);
}

async run(name: string, strategy: string, traits: any[]): Promise<Record<string, any>> {
const overrides = extractAttributes(traits);
let fixture = this.getFixture(name);
Expand Down
26 changes: 26 additions & 0 deletions lib/sequences/one-of-sequence.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {Sequence} from "./sequence";

import {sample} from "lodash";

/* eslint-disable @typescript-eslint/no-empty-function */
/* eslint-disable class-methods-use-this */
export class OneOfSequence extends Sequence {
choices: any[];

constructor(name: string, choices: any[], options?: any) {
super(name, options);
if (!choices || choices.length < 1) {
throw new Error("OneOfSequence requires a positive number of values in choices");
}
this.choices = choices;
}

increment(): void { }

reset(): void { }

next(): number {
const result = sample(this.choices);
return this.callback(result);
}
}
2 changes: 1 addition & 1 deletion test/acceptance/guide.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {FixtureRiveter} from "../../lib/fixture-riveter";

import {expect} from "chai";

describe.only("All of the code from the guide", function() {
describe("All of the code from the guide", function() {
let fr: FixtureRiveter;
let User: any;
let Post: any;
Expand Down
8 changes: 4 additions & 4 deletions test/unit/definition-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,9 @@ describe("DefinitionProxy", function() {
const fixtureRiveter = new FixtureRiveter();
const fixture = new Fixture(fixtureRiveter, "dummy", DummyModel);
const proxy = new DefinitionProxy(fixture);
const result = proxy.sequence("email");
expect(result).to.be.an.instanceof(Sequence);
proxy.sequence("email");
expect(proxy.sequenceHandler.sequences).to.have.length(1);
expect(proxy.sequenceHandler.sequences[0].name).to.equal("email");
});

it("adds the sequence as an attribute", function() {
Expand All @@ -117,13 +118,12 @@ describe("DefinitionProxy", function() {
const proxy = new DefinitionProxy(fixture);
sinon.spy(fixture, "declareAttribute");
const name = "email";
const result = proxy.sequence(name);
proxy.sequence(name);
const {declarations} = fixture.declarationHandler;

expect(declarations).to.be.length(1);
expect(declarations[0].name).to.equal(name);
expect(fixture.declareAttribute).to.be.calledOnce;
expect(declarations[0].name).to.equal(result.name);
});

it("delegates sequence creation to sequenceHandler", function() {
Expand Down
File renamed without changes.
12 changes: 7 additions & 5 deletions test/unit/factory-builder.ts → test/unit/fixture-riveter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,15 +251,17 @@ describe("FixtureRiveter", function() {
const fr = new FixtureRiveter();
let sequenceInFixture = new IntegerSequence("temp");
fr.fixture(name, DummyModel, (f: any) => {
sequenceInFixture = f.sequence("email") as IntegerSequence;
f.sequence("email");
sequenceInFixture = f.sequenceHandler.sequences.find((s) => s.name === "email");
});
const globalSeq: any = fr.sequence("usernames");
globalSeq.next();
globalSeq.next();
fr.sequence("usernames");
const globalSeq = fr.sequenceHandler.sequences.find((s) => s.name === "usernames");
globalSeq?.next();
globalSeq?.next();
sequenceInFixture.next();
sequenceInFixture.next();
fr.resetSequences();
expect(globalSeq.index).to.equal(1);
expect((globalSeq as any).index).to.equal(1);
expect(sequenceInFixture.index).to.equal(1);
});
});
Expand Down
File renamed without changes.
File renamed without changes.
53 changes: 53 additions & 0 deletions test/unit/sequences/one-of-sequence.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {OneOfSequence} from "../../../lib/sequences/one-of-sequence";

import _ from "lodash";
import {expect} from "chai";
import sinon from "sinon";

describe.only("OneOfSequence", function() {
it("returns an instance", function() {
const seq = new OneOfSequence("name", [1, 2]);
expect(seq).to.exist;
expect(seq).to.be.an.instanceof(OneOfSequence);
});

describe("#next", function() {
it("returns the only value when given a list of length 1", function() {
const seq = new OneOfSequence("name", [1]);
const result = seq.next();
expect(result).to.equal(1);
});

it("calls lodash sample correctly", function() {
const seq = new OneOfSequence("name", [1, 2]);
sinon.stub(_, "sample").returns(2 as any);
const result = seq.next();
expect(result).to.equal(2);
});

it("uses available callback", function() {
const seq = new OneOfSequence("name", [1]);
seq.callback = (x: string) => x.toString();
const result = seq.next();
expect(result).to.equal("1");
});
});

describe("iterator", function() {
it("acts like an iterator", function() {
const choices = [1, 2, 3];
const seq = new OneOfSequence("name", choices);
const result = [] as any;
for (const char of seq) {
result.push(char);
if (result.length >= 3) {
break;
}
}
expect(result).to.have.length(3);
for (const n of result) {
expect(choices.includes(n)).to.be.true;
}
});
});
});

0 comments on commit dec29c2

Please sign in to comment.