Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: standardize unity project setup #99

Merged
merged 14 commits into from
Jan 14, 2024
Merged
18 changes: 18 additions & 0 deletions src/utils/project-version-io.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import path from "path";
import fse from "fs-extra";

/**
* Creates a ProjectVersion.txt file for a Unity project.
* Nothing besides m_EditorVersion is specified.
* @param projectDirPath The projects root folder.
* @param version The editor-version to use.
*/
export function createProjectVersionTxt(
projectDirPath: string,
version: string
) {
const projectSettingsDir = path.join(projectDirPath, "ProjectSettings");
fse.mkdirpSync(projectSettingsDir);
const data = `m_EditorVersion: ${version}`;
fse.writeFileSync(path.join(projectSettingsDir, "ProjectVersion.txt"), data);
}
44 changes: 0 additions & 44 deletions test/mock-work-dir.ts

This file was deleted.

153 changes: 153 additions & 0 deletions test/setup/unity-project.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import {
emptyProjectManifest,
UnityProjectManifest,
} from "../../src/types/project-manifest";
import path from "path";
import os from "os";
import fse from "fs-extra";
import {
loadProjectManifest,
saveProjectManifest,
} from "../../src/utils/project-manifest-io";
import assert from "assert";
import { mockEnv, MockEnvSession } from "../mock-env";
import { UPMConfig } from "../../src/types/upm-config";
import { saveUpmConfig } from "../../src/utils/upm-config-io";
import {createProjectVersionTxt} from "../../src/utils/project-version-io";

/**
* A mock Unity project for testing
*/
export type MockUnityProject = {
/**
* The path to the projects root folder
*/
projectPath: string;

/**
* Attempts to load the project manifest for the project.
* Null if not found.
*/
tryGetManifest(): UnityProjectManifest | null;

/**
* Runs an assertion function on the project manifest.
* @param assertFn An assertion function.
* @throws AssertionError if no manifest was found.
*/
tryAssertManifest(assertFn: (manifest: UnityProjectManifest) => void): void;

/**
* Resets the mock-project to its original state
*/
reset(): Promise<void>;

/**
* Deletes the mock-project
*/
restore(): Promise<void>;
};

const defaultVersion = "2020.2.1f1";

const defaultManifest = emptyProjectManifest();

const defaultUpmConfig = {} satisfies UPMConfig;

type Config = {
/**
* The version to use for the project.
* If not specified uses {@link defaultVersion}
*/
version?: string;
/**
* The manifest to use for the project.
* If not specified uses {@link defaultManifest}.
* If {@link false} no manifest is created
*/
manifest?: UnityProjectManifest | false;

/**
* Override for the generated .upmconfig.toml.
* If not specified uses {@link defaultUpmConfig}
*/
upmConfig?: UPMConfig;
};

const rootPath = path.join(os.tmpdir(), "test-openupm-cli");

const projectPath = path.join(rootPath, "Project");

/**
* Setups a mock Unity project for testing.
* This will set up a directory structure with a Unity project, as well
* as some other effects:
* - Change {@link process.cwd} to {@link projectPath}.
* - Clear {@link process.env.USERPROFILE}.
* - Change {@link process.env.HOME} to {@link rootPath}.
* - Place a .upmconfig.toml in the root folder of the test directory structure.
* @param config Config describing the project to be setup
*/
export async function setupUnityProject(
config: Config
): Promise<MockUnityProject> {
let originalCwd: () => string = null!;
let envSession: MockEnvSession = null!;

async function setup() {
originalCwd = process.cwd;
process.cwd = () => projectPath;

await fse.ensureDir(projectPath);

envSession = mockEnv({ HOME: rootPath });

// Upmconfig
const upmConfig = config.upmConfig ?? defaultUpmConfig;
await saveUpmConfig(upmConfig, rootPath);

// Editor-version
const version = config.version ?? defaultVersion;
createProjectVersionTxt(projectPath, version);

// Project manifest
if (config.manifest !== false) {
const manifest = config.manifest ?? defaultManifest;
saveProjectManifest(projectPath, manifest);
}
}

async function restore() {
process.cwd = originalCwd;

await fse.rm(rootPath, { recursive: true, force: true });

envSession?.unhook();
}

function tryGetManifest(): UnityProjectManifest | null {
return loadProjectManifest(projectPath);
}

function tryAssertManifest(
assertFn: (manifest: UnityProjectManifest) => void
) {
const manifest = tryGetManifest();
assert(manifest !== null);
assertFn(manifest);
}

async function reset() {
await restore();
await setup();
}

await setup();
return {
projectPath,
tryGetManifest,
tryAssertManifest,
reset,
restore,
};
}
Loading