Merge remote-tracking branch 'origin/main' into mbg/repo-props/config-file-shorthands

This commit is contained in:
Michael B. Gale
2026-07-06 15:51:17 +01:00
105 changed files with 4972 additions and 9113 deletions

View File

@@ -28,6 +28,7 @@ import {
} from "./feature-flags";
import { Logger } from "./logging";
import { OverlayDatabaseMode } from "./overlay/overlay-database-mode";
import { ActionName } from "./status-report";
import {
DEFAULT_DEBUG_ARTIFACT_NAME,
DEFAULT_DEBUG_DATABASE_NAME,
@@ -190,22 +191,25 @@ export function getTestActionsEnv(): ActionsEnv {
}
/** For testing purposes, we make all available state features accessible in `TestEnv`. */
type AllState = ["Logger", "Env", "FeatureFlags"];
type AllState = ["Logger", "Env", "Actions", "FeatureFlags"];
/** Initialise a fresh `ActionState<AllState>` value. */
export function initAllState(
overrides?: Partial<ActionState<AllState>>,
): ActionState<AllState> {
return {
name: ActionName.Init,
startedAt: new Date(),
logger: new RecordingLogger(),
env: getTestEnv(),
actions: getTestActionsEnv(),
features: createFeatures([]),
...overrides,
};
}
/**
* Wraps a function that accepts an `ActionEnv` for testing in different environments.
* Wraps a function that accepts an `ActionState` for testing in different environments.
*/
export class TestEnv<
Args extends readonly any[],
@@ -214,20 +218,28 @@ export class TestEnv<
> {
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,
args?: Args,
initialState?: ActionState<AllState>,
cloneFrom?: TestEnv<Args, R, Fs>,
) {
this.fn = fn;
this.args = args;
this.state = initialState || initAllState();
this.args = cloneFrom?.args;
this.logger = new RecordingLogger();
this.state =
cloneFrom !== undefined
? { ...cloneFrom.state, logger: this.logger }
: initAllState({ logger: this.logger });
}
private clone(): TestEnv<Args, R, Fs> {
return new TestEnv(this.fn, this.args, { ...this.state });
return new TestEnv(this.fn, this);
}
public getLogger(): RecordingLogger {
return this.logger;
}
public getState(): ActionState<AllState> {
@@ -256,11 +268,17 @@ export class TestEnv<
return result;
}
public withActions(actions: ActionsEnv): TestEnv<Args, R, Fs> {
const result = this.clone();
result.state.actions = actions;
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);
return this.fn(this.state as unknown as ActionState<Fs>, ...this.args);
}
public passes<T>(