Skip to content

Commit

Permalink
test: standardize unity project setup (#99)
Browse files Browse the repository at this point in the history
* refactor: extract helper function

* feat: mock-project test-utility

* refactor: use project-setup in add test

* refactor: use project-setup in deps test

* refactor: use project-setup in remove test

* refactor: use project-setup in search test

* refactor: use project-setup in view test

* refactor: make project-setup async

In preparation for async work in setup function.

* feat: modify env for project-setup

* feat: upmconfig for project-setup

* refactor: use project-setup in env test

* refactor: use project-setup in project-manifest test

* refactor: move function

* refactor: delete unused code
  • Loading branch information
ComradeVanti authored Jan 14, 2024
1 parent 0437a9c commit 432d923
Show file tree
Hide file tree
Showing 10 changed files with 383 additions and 225 deletions.
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

0 comments on commit 432d923

Please sign in to comment.