Skip to content

Commit 86eef6d

Browse files
committed
Split EnvBuilder into it + CallableEnvBuilder
1 parent 225d45f commit 86eef6d

1 file changed

Lines changed: 38 additions & 19 deletions

File tree

src/testing-utils.ts

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -218,26 +218,28 @@ class EnvBuilder<
218218
R,
219219
Fs extends ReadonlyArray<AllState[number]>,
220220
> {
221-
private readonly fn: (state: ActionState<Fs>, ...args: Args) => R;
222-
private args?: Args;
221+
protected readonly fn: (state: ActionState<Fs>, ...args: Args) => R;
223222
private logger: RecordingLogger;
224-
private state: ActionState<AllState>;
223+
protected state: ActionState<AllState>;
225224

226225
constructor(
227226
fn: (state: ActionState<Fs>, ...args: Args) => R,
228227
cloneFrom?: EnvBuilder<Args, R, Fs>,
229228
) {
230229
this.fn = fn;
231-
this.args = cloneFrom?.args;
232230
this.logger = new RecordingLogger();
233231
this.state =
234232
cloneFrom !== undefined
235233
? { ...cloneFrom.state, logger: this.logger }
236234
: initAllState({ logger: this.logger });
237235
}
238236

239-
private clone(): EnvBuilder<Args, R, Fs> {
240-
return new EnvBuilder(this.fn, this);
237+
/**
238+
* Creates a clone of this object. Used internally.
239+
* Must be overriden by subclasses.
240+
*/
241+
protected clone(): this {
242+
return new EnvBuilder(this.fn, this) as this;
241243
}
242244

243245
public getLogger(): RecordingLogger {
@@ -248,38 +250,55 @@ class EnvBuilder<
248250
return this.state;
249251
}
250252

251-
public getArgs(): Args | undefined {
252-
return this.args;
253-
}
254-
255-
public withArgs(...args: Args) {
256-
const result = this.clone();
257-
result.args = args;
253+
public withArgs(...args: Args): CallableEnvBuilder<Args, R, Fs> {
254+
const result = new CallableEnvBuilder(this.fn, args, this.clone());
258255
return result;
259256
}
260257

261-
public withFeatures(enabled: Feature[]): EnvBuilder<Args, R, Fs> {
258+
public withFeatures(enabled: Feature[]): this {
262259
const result = this.clone();
263260
result.state.features = createFeatures(enabled);
264261
return result;
265262
}
266263

267-
public withEnv(env: Env): EnvBuilder<Args, R, Fs> {
264+
public withEnv(env: Env): this {
268265
const result = this.clone();
269266
result.state.env = env;
270267
return result;
271268
}
272269

273-
public withActions(actions: ActionsEnv): EnvBuilder<Args, R, Fs> {
270+
public withActions(actions: ActionsEnv): this {
274271
const result = this.clone();
275272
result.state.actions = actions;
276273
return result;
277274
}
275+
}
276+
277+
class CallableEnvBuilder<
278+
Args extends readonly any[],
279+
R,
280+
Fs extends ReadonlyArray<AllState[number]>,
281+
> extends EnvBuilder<Args, R, Fs> {
282+
private args: Args;
283+
284+
constructor(
285+
fn: (state: ActionState<Fs>, ...args: Args) => R,
286+
args: Args,
287+
cloneFrom?: EnvBuilder<Args, R, Fs>,
288+
) {
289+
super(fn, cloneFrom);
290+
this.args = args;
291+
}
292+
293+
protected clone(): this {
294+
return new CallableEnvBuilder(this.fn, this.args, this) as this;
295+
}
296+
297+
public getArgs(): Args {
298+
return this.args;
299+
}
278300

279301
call(): R {
280-
if (!this.args) {
281-
throw new Error("Trying to call function in TestEnv without arguments.");
282-
}
283302
return this.fn(this.state as unknown as ActionState<Fs>, ...this.args);
284303
}
285304

0 commit comments

Comments
 (0)