Files
DcsMissionScriptingTools/dutchies-dcs-scripting-tools/src/test/lua-addons-manager.test.ts
T

256 lines
11 KiB
TypeScript

import * as assert from 'assert';
import * as fs from 'fs/promises';
import * as path from 'path';
import * as os from 'os';
import { existsSync } from 'fs';
import { LuaAddonsManager } from '../lua-addons-manager';
/**
* Integration tests for LuaAddonsManager
* Uses temporary directories to avoid polluting the file system
*/
suite('LuaAddonsManager', () => {
let tempDir: string;
suiteSetup(async () => {
tempDir = path.join(os.tmpdir(), `dcs-test-${Date.now()}-${Math.random()}`);
});
suiteTeardown(async () => {
if (existsSync(tempDir)) {
await fs.rm(tempDir, { recursive: true, force: true });
}
});
suite('getExtensionVersion', () => {
test('should return undefined if addon not found', async () => {
const extensionDir = path.join(tempDir, 'getExtensionVersion-1');
const sourceDir = path.join(tempDir, 'getExtensionVersion-1-source');
await fs.mkdir(extensionDir, { recursive: true });
await fs.mkdir(sourceDir, { recursive: true });
const manager = new LuaAddonsManager(extensionDir, sourceDir);
const version = await manager.getExtensionVersion('nonexistent');
assert.strictEqual(version, undefined);
});
test('should return version string for installed addon', async () => {
const extensionDir = path.join(tempDir, 'getExtensionVersion-2');
const sourceDir = path.join(tempDir, 'getExtensionVersion-2-source');
await fs.mkdir(extensionDir, { recursive: true });
await fs.mkdir(sourceDir, { recursive: true });
await fs.mkdir(path.join(extensionDir, 'dcs-types.1.2.3'), { recursive: true });
const manager = new LuaAddonsManager(extensionDir, sourceDir);
const version = await manager.getExtensionVersion('dcs-types');
assert.strictEqual(version, '1.2.3');
});
test('should return first matching version if multiple versions exist', async () => {
const extensionDir = path.join(tempDir, 'getExtensionVersion-3');
const sourceDir = path.join(tempDir, 'getExtensionVersion-3-source');
await fs.mkdir(extensionDir, { recursive: true });
await fs.mkdir(sourceDir, { recursive: true });
await fs.mkdir(path.join(extensionDir, 'addon.1.0.0'), { recursive: true });
await fs.mkdir(path.join(extensionDir, 'addon.2.0.0'), { recursive: true });
const manager = new LuaAddonsManager(extensionDir, sourceDir);
const version = await manager.getExtensionVersion('addon');
// Should return one of the versions (first found)
assert.match(version!, /^[12]\.0\.0$/);
});
});
suite('getPackageVersion', () => {
test('should read version from package.json', async () => {
const extensionDir = path.join(tempDir, 'getPackageVersion-1');
const sourceDir = path.join(tempDir, 'getPackageVersion-1-source');
await fs.mkdir(extensionDir, { recursive: true });
await fs.mkdir(sourceDir, { recursive: true });
const packageJson = path.join(extensionDir, 'package.json');
await fs.writeFile(packageJson, JSON.stringify({ version: '2.1.0' }));
const manager = new LuaAddonsManager(extensionDir, sourceDir);
const version = await manager.getPackageVersion();
assert.strictEqual(version, '2.1.0');
});
test('should throw error if package.json not found', async () => {
const extensionDir = path.join(tempDir, 'getPackageVersion-2');
const sourceDir = path.join(tempDir, 'getPackageVersion-2-source');
await fs.mkdir(extensionDir, { recursive: true });
await fs.mkdir(sourceDir, { recursive: true });
const manager = new LuaAddonsManager(extensionDir, sourceDir);
await assert.rejects(
() => manager.getPackageVersion(),
/Failed to read extension version/
);
});
test('should throw error if version field missing', async () => {
const extensionDir = path.join(tempDir, 'getPackageVersion-3');
const sourceDir = path.join(tempDir, 'getPackageVersion-3-source');
await fs.mkdir(extensionDir, { recursive: true });
await fs.mkdir(sourceDir, { recursive: true });
const packageJson = path.join(extensionDir, 'package.json');
await fs.writeFile(packageJson, JSON.stringify({ name: 'test' }));
const manager = new LuaAddonsManager(extensionDir, sourceDir);
await assert.rejects(
() => manager.getPackageVersion(),
/Version field not found/
);
});
});
suite('removeExtension', () => {
test('should remove addon by name', async () => {
const extensionDir = path.join(tempDir, 'removeExtension-1');
const sourceDir = path.join(tempDir, 'removeExtension-1-source');
await fs.mkdir(extensionDir, { recursive: true });
await fs.mkdir(sourceDir, { recursive: true });
await fs.mkdir(path.join(extensionDir, 'addon1.1.0.0'), { recursive: true });
const manager = new LuaAddonsManager(extensionDir, sourceDir);
await manager.removeExtension('addon1');
const remaining = await fs.readdir(extensionDir);
assert.strictEqual(remaining.length, 0);
});
test('should not affect other addons', async () => {
const extensionDir = path.join(tempDir, 'removeExtension-2');
const sourceDir = path.join(tempDir, 'removeExtension-2-source');
await fs.mkdir(extensionDir, { recursive: true });
await fs.mkdir(sourceDir, { recursive: true });
await fs.mkdir(path.join(extensionDir, 'addon1.1.0.0'), { recursive: true });
await fs.mkdir(path.join(extensionDir, 'addon2.1.0.0'), { recursive: true });
const manager = new LuaAddonsManager(extensionDir, sourceDir);
await manager.removeExtension('addon1');
const remaining = await fs.readdir(extensionDir);
assert.strictEqual(remaining.length, 1);
assert.strictEqual(remaining[0], 'addon2.1.0.0');
});
});
suite('removeAllExtensions', () => {
test('should remove multiple addons by name', async () => {
const extensionDir = path.join(tempDir, 'removeAllExtensions-1');
const sourceDir = path.join(tempDir, 'removeAllExtensions-1-source');
await fs.mkdir(extensionDir, { recursive: true });
await fs.mkdir(sourceDir, { recursive: true });
await fs.mkdir(path.join(extensionDir, 'addon1.1.0.0'), { recursive: true });
await fs.mkdir(path.join(extensionDir, 'addon2.1.0.0'), { recursive: true });
await fs.mkdir(path.join(extensionDir, 'addon3.1.0.0'), { recursive: true });
const manager = new LuaAddonsManager(extensionDir, sourceDir);
await manager.removeAllExtensions(['addon1', 'addon2']);
const remaining = await fs.readdir(extensionDir);
assert.deepStrictEqual(remaining.sort(), ['addon3.1.0.0']);
});
test('should delete all versions of matching addons', async () => {
const extensionDir = path.join(tempDir, 'removeAllExtensions-2');
const sourceDir = path.join(tempDir, 'removeAllExtensions-2-source');
await fs.mkdir(extensionDir, { recursive: true });
await fs.mkdir(sourceDir, { recursive: true });
await fs.mkdir(path.join(extensionDir, 'addon1.0.0.1'), { recursive: true });
await fs.mkdir(path.join(extensionDir, 'addon1.0.0.2'), { recursive: true });
await fs.mkdir(path.join(extensionDir, 'addon1.0.0.3'), { recursive: true });
await fs.mkdir(path.join(extensionDir, 'addon2.1.0.0'), { recursive: true });
const manager = new LuaAddonsManager(extensionDir, sourceDir);
await manager.removeAllExtensions(['addon1']);
const remaining = await fs.readdir(extensionDir);
assert.deepStrictEqual(remaining.sort(), ['addon2.1.0.0']);
});
test('should ignore folders with invalid version format', async () => {
const extensionDir = path.join(tempDir, 'removeAllExtensions-3');
const sourceDir = path.join(tempDir, 'removeAllExtensions-3-source');
await fs.mkdir(extensionDir, { recursive: true });
await fs.mkdir(sourceDir, { recursive: true });
await fs.mkdir(path.join(extensionDir, 'addon1.1.0.0'), { recursive: true });
await fs.mkdir(path.join(extensionDir, 'invalid-folder'), { recursive: true });
const manager = new LuaAddonsManager(extensionDir, sourceDir);
await manager.removeAllExtensions(['addon1']);
const remaining = await fs.readdir(extensionDir);
assert.deepStrictEqual(remaining.sort(), ['invalid-folder']);
});
test('should not throw if addon does not exist', async () => {
const extensionDir = path.join(tempDir, 'removeAllExtensions-4');
const sourceDir = path.join(tempDir, 'removeAllExtensions-4-source');
await fs.mkdir(extensionDir, { recursive: true });
await fs.mkdir(sourceDir, { recursive: true });
const manager = new LuaAddonsManager(extensionDir, sourceDir);
// Should not throw
await manager.removeAllExtensions(['nonexistent']);
});
});
suite('installExtension', () => {
test('should copy addon from source to target', async () => {
const extensionDir = path.join(tempDir, 'installExtension-1');
const sourceDir = path.join(tempDir, 'installExtension-1-source');
await fs.mkdir(extensionDir, { recursive: true });
await fs.mkdir(sourceDir, { recursive: true });
const sourceAddon = path.join(sourceDir, 'addon1');
await fs.mkdir(sourceAddon, { recursive: true });
await fs.writeFile(path.join(sourceAddon, 'file.lua'), 'content');
const manager = new LuaAddonsManager(extensionDir, sourceDir);
await manager.installExtension('addon1');
const targetAddon = path.join(extensionDir, 'addon1');
assert.strictEqual(existsSync(targetAddon), true);
assert.strictEqual(existsSync(path.join(targetAddon, 'file.lua')), true);
});
test('should throw error if source directory does not exist', async () => {
const extensionDir = path.join(tempDir, 'installExtension-2');
const sourceDir = path.join(tempDir, 'installExtension-2-source');
await fs.mkdir(extensionDir, { recursive: true });
await fs.mkdir(sourceDir, { recursive: true });
const manager = new LuaAddonsManager(extensionDir, sourceDir);
await assert.rejects(
() => manager.installExtension('nonexistent'),
/Source extension folder not found/
);
});
test('should copy nested directories recursively', async () => {
const extensionDir = path.join(tempDir, 'installExtension-3');
const sourceDir = path.join(tempDir, 'installExtension-3-source');
await fs.mkdir(extensionDir, { recursive: true });
await fs.mkdir(sourceDir, { recursive: true });
const sourceAddon = path.join(sourceDir, 'addon1');
await fs.mkdir(path.join(sourceAddon, 'subdir'), { recursive: true });
await fs.writeFile(path.join(sourceAddon, 'file.lua'), 'root');
await fs.writeFile(path.join(sourceAddon, 'subdir', 'file.lua'), 'nested');
const manager = new LuaAddonsManager(extensionDir, sourceDir);
await manager.installExtension('addon1');
const targetAddon = path.join(extensionDir, 'addon1');
assert.strictEqual(existsSync(path.join(targetAddon, 'file.lua')), true);
assert.strictEqual(existsSync(path.join(targetAddon, 'subdir', 'file.lua')), true);
});
});
});