Skip to content

Commit 6109575

Browse files
committed
Allow withActions and withEnv to mutate values
1 parent eb96739 commit 6109575

3 files changed

Lines changed: 43 additions & 38 deletions

File tree

src/config/file.test.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,17 @@ const repositoryProperties = {
2222

2323
test("getConfigFileInput returns input value", async (t) => {
2424
const testInput = "/some/path";
25-
const target = callee(getConfigFileInput).withFeatures([
26-
Feature.ConfigFileRepositoryProperty,
27-
]);
28-
29-
const actionsEnv = target.getState().actions;
30-
sinon
31-
.stub(actionsEnv, "getOptionalInput")
32-
.withArgs("config-file")
33-
.returns(testInput);
3425

3526
// Even though both an input and repository property are configured,
3627
// we prefer the direct input to the Action.
37-
await target
38-
.withActions(actionsEnv)
28+
await callee(getConfigFileInput)
29+
.withFeatures([Feature.ConfigFileRepositoryProperty])
30+
.withActions((actionsEnv) => {
31+
sinon
32+
.stub(actionsEnv, "getOptionalInput")
33+
.withArgs("config-file")
34+
.returns(testInput);
35+
})
3936
.withArgs(repositoryProperties)
4037
.logs(t, "Using configuration file input from workflow")
4138
.passes(t.is, testInput);

src/config/remote-file.test.ts

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import sinon from "sinon";
44
import { ActionsEnvVars } from "../environment";
55
import * as errors from "../error-messages";
66
import { Feature } from "../feature-flags";
7-
import { callee, getTestEnv } from "../testing-utils";
7+
import { callee } from "../testing-utils";
88
import { ConfigurationError } from "../util";
99

1010
import {
@@ -88,16 +88,13 @@ test("parseRemoteFileAddress accepts full remote addresses", async (t) => {
8888
});
8989

9090
test("parseRemoteFileAddress accepts remote address without an owner", async (t) => {
91-
const target = callee(parseRemoteFileAddress);
92-
93-
const env = target.getState().env;
9491
const owner = "test-owner";
95-
const getRequired = sinon.stub(env, "getRequired");
96-
getRequired
97-
.withArgs(ActionsEnvVars.GITHUB_REPOSITORY)
98-
.returns(`${owner}/current-repo`);
99-
100-
const targetWithEnv = target.withEnv(env);
92+
const target = callee(parseRemoteFileAddress).withEnv((env) => {
93+
const getRequired = sinon.stub(env, "getRequired");
94+
getRequired
95+
.withArgs(ActionsEnvVars.GITHUB_REPOSITORY)
96+
.returns(`${owner}/current-repo`);
97+
});
10198

10299
const testCases: ParseRemoteFileAddressTest[] = [
103100
{
@@ -139,7 +136,7 @@ test("parseRemoteFileAddress accepts remote address without an owner", async (t)
139136
];
140137

141138
for (const testCase of testCases) {
142-
const targetWithArgs = targetWithEnv.withArgs(testCase.input);
139+
const targetWithArgs = target.withArgs(testCase.input);
143140

144141
// Should fail when the FF is not enabled.
145142
await targetWithArgs
@@ -154,14 +151,16 @@ test("parseRemoteFileAddress accepts remote address without an owner", async (t)
154151
});
155152

156153
test("parseRemoteFileAddress throws for invalid `GITHUB_REPOSITORY`", async (t) => {
157-
const target = callee(parseRemoteFileAddress).withArgs("repo@ref");
158-
159-
const env = target.getState().env;
160-
const getRequired = sinon.stub(env, "getRequired");
154+
const getRequired: sinon.SinonStub = sinon.stub();
161155
getRequired.withArgs(ActionsEnvVars.GITHUB_REPOSITORY).returns(`not-valid`);
162156

157+
const target = callee(parseRemoteFileAddress)
158+
.withArgs("repo@ref")
159+
.withEnv((env) => {
160+
sinon.define(env, "getRequired", getRequired);
161+
});
162+
163163
await target
164-
.withEnv(env)
165164
.withFeatures([Feature.NewRemoteFileAddresses])
166165
.throws(t, { instanceOf: Error });
167166

@@ -223,14 +222,13 @@ test("parseRemoteFileAddress accepts remote address without a ref", async (t) =>
223222
});
224223

225224
test("parseRemoteFileAddress rejects invalid values", async (t) => {
226-
const env = getTestEnv();
227225
const owner = "owner";
228-
const getRequired = sinon.stub(env, "getRequired");
229-
getRequired
230-
.withArgs(ActionsEnvVars.GITHUB_REPOSITORY)
231-
.returns(`${owner}/current-repo`);
232-
233-
const target = callee(parseRemoteFileAddress).withEnv(env);
226+
const target = callee(parseRemoteFileAddress).withEnv((env) => {
227+
const getRequired = sinon.stub(env, "getRequired");
228+
getRequired
229+
.withArgs(ActionsEnvVars.GITHUB_REPOSITORY)
230+
.returns(`${owner}/current-repo`);
231+
});
234232

235233
const testInputs = [
236234
" ",

src/testing-utils.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ type DelayedCheck<
216216
Fs extends ReadonlyArray<AllState[number]>,
217217
> = (env: Readonly<BaseEnvBuilder<Args, R, Fs>>) => Promise<any>;
218218

219+
export type ValueOrMutation<T> = T | ((val: T) => void);
220+
219221
/**
220222
* Wraps a function that accepts an `ActionState` for testing in different environments.
221223
*/
@@ -267,15 +269,23 @@ abstract class BaseEnvBuilder<
267269
return result;
268270
}
269271

270-
public withEnv(env: Env): this {
272+
public withEnv(arg: ValueOrMutation<Env>): this {
271273
const result = this.clone();
272-
result.state.env = env;
274+
if (typeof arg === "function") {
275+
arg(result.state.env);
276+
} else {
277+
result.state.env = arg;
278+
}
273279
return result;
274280
}
275281

276-
public withActions(actions: ActionsEnv): this {
282+
public withActions(arg: ValueOrMutation<ActionsEnv>): this {
277283
const result = this.clone();
278-
result.state.actions = actions;
284+
if (typeof arg === "function") {
285+
arg(result.state.actions);
286+
} else {
287+
result.state.actions = arg;
288+
}
279289
return result;
280290
}
281291

0 commit comments

Comments
 (0)