feat: e2e 테스트 실행 및 에러 수정

This commit is contained in:
2026-01-18 13:28:02 +00:00
parent e1f21d3209
commit e2accc31a7
13 changed files with 210 additions and 34 deletions
+3
View File
@@ -29,6 +29,9 @@ export type { ReservedTurnView } from './turns/reservedTurns.js';
export type { JsonObject, JsonArray } from './context.js';
const isMain = (): boolean => {
if (typeof process.env.NODE_APP_INSTANCE === 'string') {
return true;
}
if (!process.argv[1]) {
return false;
}
+1 -1
View File
@@ -26,5 +26,5 @@ export const formatSseFrame = (frame: SseFrame): string => {
}
lines.push('');
return lines.join('\n');
return `${lines.join('\n')}\n`;
};
+3
View File
@@ -22,6 +22,9 @@ export * from './turn/turnDaemon.js';
export * from './turn/cli.js';
const isMain = (): boolean => {
if (typeof process.env.NODE_APP_INSTANCE === 'string') {
return true;
}
if (!process.argv[1]) {
return false;
}
@@ -89,6 +89,117 @@ const normalizeCommand = (envelope: TurnDaemonCommandEnvelope): TurnDaemonComman
generalId: command.generalId,
};
}
case 'dieOnPrestart': {
if (typeof command.generalId !== 'number') {
return null;
}
return {
type: 'dieOnPrestart',
requestId: envelope.requestId,
generalId: command.generalId,
};
}
case 'buildNationCandidate': {
if (typeof command.generalId !== 'number') {
return null;
}
return {
type: 'buildNationCandidate',
requestId: envelope.requestId,
generalId: command.generalId,
};
}
case 'instantRetreat': {
if (typeof command.generalId !== 'number') {
return null;
}
return {
type: 'instantRetreat',
requestId: envelope.requestId,
generalId: command.generalId,
};
}
case 'vacation': {
if (typeof command.generalId !== 'number') {
return null;
}
return {
type: 'vacation',
requestId: envelope.requestId,
generalId: command.generalId,
};
}
case 'setMySetting': {
if (typeof command.generalId !== 'number' || !command.settings || typeof command.settings !== 'object') {
return null;
}
return {
type: 'setMySetting',
requestId: envelope.requestId,
generalId: command.generalId,
settings: command.settings,
};
}
case 'dropItem': {
if (typeof command.generalId !== 'number' || typeof command.itemType !== 'string') {
return null;
}
return {
type: 'dropItem',
requestId: envelope.requestId,
generalId: command.generalId,
itemType: command.itemType,
};
}
case 'changePermission': {
if (
typeof command.generalId !== 'number' ||
typeof command.isAmbassador !== 'boolean' ||
!Array.isArray(command.targetGeneralIds)
) {
return null;
}
const targetGeneralIds = command.targetGeneralIds.filter((id) => typeof id === 'number');
if (targetGeneralIds.length === 0) {
return null;
}
return {
type: 'changePermission',
requestId: envelope.requestId,
generalId: command.generalId,
isAmbassador: command.isAmbassador,
targetGeneralIds,
};
}
case 'kick': {
if (typeof command.generalId !== 'number' || typeof command.destGeneralId !== 'number') {
return null;
}
return {
type: 'kick',
requestId: envelope.requestId,
generalId: command.generalId,
destGeneralId: command.destGeneralId,
};
}
case 'appoint': {
if (
typeof command.generalId !== 'number' ||
typeof command.destGeneralId !== 'number' ||
typeof command.destCityId !== 'number' ||
typeof command.officerLevel !== 'number'
) {
return null;
}
return {
type: 'appoint',
requestId: envelope.requestId,
generalId: command.generalId,
destGeneralId: command.destGeneralId,
destCityId: command.destCityId,
officerLevel: command.officerLevel,
};
}
case 'getStatus': {
const requestId = typeof command.requestId === 'string' ? command.requestId : envelope.requestId;
return { type: 'getStatus', requestId };
+25
View File
@@ -0,0 +1,25 @@
import fs from 'node:fs';
import path from 'node:path';
const WORKSPACE_MARKERS = ['pnpm-workspace.yaml'];
const hasWorkspaceMarker = (dir: string): boolean =>
WORKSPACE_MARKERS.some((marker) => fs.existsSync(path.join(dir, marker)));
export const resolveWorkspaceRoot = (
startDir: string = process.env.GATEWAY_WORKSPACE_ROOT ?? process.cwd(),
maxDepth = 6
): string => {
let current = path.resolve(startDir);
for (let depth = 0; depth <= maxDepth; depth += 1) {
if (hasWorkspaceMarker(current)) {
return current;
}
const parent = path.dirname(current);
if (parent === current) {
break;
}
current = parent;
}
return path.resolve(startDir);
};
+3 -4
View File
@@ -1,12 +1,11 @@
import fs from 'node:fs/promises';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { MapDefinitionSchema, type MapDefinition } from '@sammo-ts/logic';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const REPO_ROOT = path.resolve(__dirname, '..', '..', '..', '..');
import { resolveWorkspaceRoot } from '../paths.js';
const REPO_ROOT = resolveWorkspaceRoot();
const DEFAULT_MAP_ROOT = path.resolve(REPO_ROOT, 'resources', 'map');
export interface MapLoaderOptions {
@@ -1,6 +1,5 @@
import fs from 'node:fs/promises';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import {
parseScenarioDefaults,
@@ -9,9 +8,9 @@ import {
type ScenarioDefinition,
} from '@sammo-ts/logic';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const REPO_ROOT = path.resolve(__dirname, '..', '..', '..', '..');
import { resolveWorkspaceRoot } from '../paths.js';
const REPO_ROOT = resolveWorkspaceRoot();
const DEFAULT_SCENARIO_ROOT = path.resolve(REPO_ROOT, 'resources', 'scenario');
export interface ScenarioLoaderOptions {
@@ -1,12 +1,11 @@
import fs from 'node:fs/promises';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { parseUnitSetDefinition, type UnitSetDefinition } from '@sammo-ts/logic';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const REPO_ROOT = path.resolve(__dirname, '..', '..', '..', '..');
import { resolveWorkspaceRoot } from '../paths.js';
const REPO_ROOT = resolveWorkspaceRoot();
const DEFAULT_UNIT_SET_ROOT = path.resolve(REPO_ROOT, 'resources', 'unitset');
export interface UnitSetLoaderOptions {
@@ -1,12 +1,11 @@
import fs from 'node:fs/promises';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { DEFAULT_TURN_COMMAND_PROFILE, parseTurnCommandProfile, type TurnCommandProfile } from '@sammo-ts/logic';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const REPO_ROOT = path.resolve(__dirname, '..', '..', '..', '..');
import { resolveWorkspaceRoot } from '../paths.js';
const REPO_ROOT = resolveWorkspaceRoot();
const DEFAULT_PROFILE_PATH = path.resolve(REPO_ROOT, 'resources', 'turn-commands', 'default.json');
export interface TurnCommandProfileOptions {