mirror of
https://github.com/github/codeql-action.git
synced 2026-10-03 17:41:28 +00:00
Add TestEnv class to simplify testing of ActionState-dependent functions
This commit is contained in:
@@ -10,6 +10,7 @@ import test, {
|
|||||||
import nock from "nock";
|
import nock from "nock";
|
||||||
import * as sinon from "sinon";
|
import * as sinon from "sinon";
|
||||||
|
|
||||||
|
import { ActionState, StateFeature } from "./action-common";
|
||||||
import { ActionsEnv, ActionsEnvVars, getActionVersion } from "./actions-util";
|
import { ActionsEnv, ActionsEnvVars, getActionVersion } from "./actions-util";
|
||||||
import { AnalysisKind } from "./analyses";
|
import { AnalysisKind } from "./analyses";
|
||||||
import * as apiClient from "./api-client";
|
import * as apiClient from "./api-client";
|
||||||
@@ -188,6 +189,99 @@ export function getTestActionsEnv(): ActionsEnv {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** For testing purposes, we make all available state features accessible in `TestEnv`. */
|
||||||
|
type AllState = ["Logger", "Env", "FeatureFlags"];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps a function that accepts an `ActionState` for testing in different environments.
|
||||||
|
*/
|
||||||
|
export class TestEnv<
|
||||||
|
Args extends readonly any[],
|
||||||
|
R,
|
||||||
|
Fs extends ReadonlyArray<AllState[number]>,
|
||||||
|
> {
|
||||||
|
private readonly fn: (state: ActionState<Fs>, ...args: Args) => R;
|
||||||
|
private args?: Args;
|
||||||
|
private logger: RecordingLogger;
|
||||||
|
private state: ActionState<AllState>;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
fn: (state: ActionState<Fs>, ...args: Args) => R,
|
||||||
|
cloneFrom?: TestEnv<Args, R, Fs>,
|
||||||
|
) {
|
||||||
|
this.fn = fn;
|
||||||
|
this.args = cloneFrom?.args;
|
||||||
|
this.logger = new RecordingLogger();
|
||||||
|
this.state =
|
||||||
|
cloneFrom !== undefined
|
||||||
|
? { ...cloneFrom.state }
|
||||||
|
: {
|
||||||
|
logger: new RecordingLogger(),
|
||||||
|
env: getTestEnv(),
|
||||||
|
features: createFeatures([]),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private clone(): TestEnv<Args, R, Fs> {
|
||||||
|
return new TestEnv(this.fn, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getLogger(): RecordingLogger {
|
||||||
|
return this.logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getState(): ActionState<AllState> {
|
||||||
|
return this.state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getArgs(): Args | undefined {
|
||||||
|
return this.args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public withArgs(...args: Args) {
|
||||||
|
const result = this.clone();
|
||||||
|
result.args = args;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public withFeatures(enabled: Feature[]): TestEnv<Args, R, Fs> {
|
||||||
|
const result = this.clone();
|
||||||
|
result.state.features = createFeatures(enabled);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public withEnv(env: Env): TestEnv<Args, R, Fs> {
|
||||||
|
const result = this.clone();
|
||||||
|
result.state.env = env;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
call(): R {
|
||||||
|
if (!this.args) {
|
||||||
|
throw new Error("Trying to call function in TestEnv without arguments.");
|
||||||
|
}
|
||||||
|
return this.fn(this.state as ActionState<Fs>, ...this.args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public passes<T>(
|
||||||
|
assertion: (makeCall: () => R) => T | Promise<T>,
|
||||||
|
): T | Promise<T> {
|
||||||
|
return assertion(() => {
|
||||||
|
const result = this.call();
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Utility function to construct a `TestEnv`. */
|
||||||
|
export function callee<
|
||||||
|
Args extends readonly any[],
|
||||||
|
R,
|
||||||
|
Fs extends readonly StateFeature[],
|
||||||
|
>(fn: (state: ActionState<Fs>, ...args: Args) => R): TestEnv<Args, R, Fs> {
|
||||||
|
return new TestEnv(fn);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default values for environment variables typically set in an Actions
|
* Default values for environment variables typically set in an Actions
|
||||||
* environment. Tests can override individual variables by passing them in the
|
* environment. Tests can override individual variables by passing them in the
|
||||||
|
|||||||
Reference in New Issue
Block a user