Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/RELOADEROO_FOR_XCODEBUILDMCP.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ npx reloaderoo@latest --help

- **`boot_sim`**: Boots a simulator.
```bash
npx reloaderoo@latest inspect call-tool boot_sim --params '{"simulatorUuid": "SIMULATOR_UUID"}' -- node build/index.js
npx reloaderoo@latest inspect call-tool boot_sim --params '{"simulatorId": "SIMULATOR_UUID"}' -- node build/index.js
```
- **`build_run_sim`**: Builds and runs an app on a simulator.
```bash
Expand All @@ -76,11 +76,11 @@ npx reloaderoo@latest --help
```
- **`install_app_sim`**: Installs an app on a simulator.
```bash
npx reloaderoo@latest inspect call-tool install_app_sim --params '{"simulatorUuid": "SIMULATOR_UUID", "appPath": "/path/to/MyApp.app"}' -- node build/index.js
npx reloaderoo@latest inspect call-tool install_app_sim --params '{"simulatorId": "SIMULATOR_UUID", "appPath": "/path/to/MyApp.app"}' -- node build/index.js
```
- **`launch_app_logs_sim`**: Launches an app on a simulator with log capture.
```bash
npx reloaderoo@latest inspect call-tool launch_app_logs_sim --params '{"simulatorUuid": "SIMULATOR_UUID", "bundleId": "com.example.MyApp"}' -- node build/index.js
npx reloaderoo@latest inspect call-tool launch_app_logs_sim --params '{"simulatorId": "SIMULATOR_UUID", "bundleId": "com.example.MyApp"}' -- node build/index.js
```
- **`launch_app_sim`**: Launches an app on a simulator.
```bash
Expand Down
12 changes: 6 additions & 6 deletions docs/session-aware-migration-todo.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ Reference: `docs/session_management_plan.md`
- [x] `src/mcp/tools/simulator/get_sim_app_path.ts` — session defaults: `projectPath`, `workspacePath`, `scheme`, `simulatorId`, `simulatorName`, `configuration`, `useLatestOS`, `arch`.

## Simulator Runtime Actions
- [ ] `src/mcp/tools/simulator/boot_sim.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
- [ ] `src/mcp/tools/simulator/install_app_sim.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
- [ ] `src/mcp/tools/simulator/launch_app_sim.ts` — session defaults: `simulatorId`, `simulatorName` (hydrate `simulatorUuid`).
- [ ] `src/mcp/tools/simulator/launch_app_logs_sim.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
- [ ] `src/mcp/tools/simulator/stop_app_sim.ts` — session defaults: `simulatorId`, `simulatorName` (hydrate `simulatorUuid`).
- [ ] `src/mcp/tools/simulator/record_sim_video.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
- [x] `src/mcp/tools/simulator/boot_sim.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
- [x] `src/mcp/tools/simulator/install_app_sim.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
- [x] `src/mcp/tools/simulator/launch_app_sim.ts` — session defaults: `simulatorId`, `simulatorName` (hydrate `simulatorUuid`).
- [x] `src/mcp/tools/simulator/launch_app_logs_sim.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
- [x] `src/mcp/tools/simulator/stop_app_sim.ts` — session defaults: `simulatorId`, `simulatorName` (hydrate `simulatorUuid`).
- [x] `src/mcp/tools/simulator/record_sim_video.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).

## Simulator Management
- [ ] `src/mcp/tools/simulator-management/erase_sims.ts` — session defaults: `simulatorId` (covers `simulatorUdid`).
Expand Down
86 changes: 37 additions & 49 deletions src/mcp/tools/simulator/__tests__/boot_sim.test.ts
Original file line number Diff line number Diff line change
@@ -1,57 +1,54 @@
/**
* Tests for boot_sim plugin
* Following CLAUDE.md testing standards with literal validation
* Using dependency injection for deterministic testing
* Tests for boot_sim plugin (session-aware version)
* Follows CLAUDE.md guidance: dependency injection, no vi-mocks, literal validation.
*/

import { describe, it, expect } from 'vitest';
import { describe, it, expect, beforeEach } from 'vitest';
import { z } from 'zod';
import {
createMockExecutor,
createMockFileSystemExecutor,
createNoopExecutor,
} from '../../../../test-utils/mock-executors.ts';
import { createMockExecutor } from '../../../../test-utils/mock-executors.ts';
import { sessionStore } from '../../../../utils/session-store.ts';
import bootSim, { boot_simLogic } from '../boot_sim.ts';

describe('boot_sim tool', () => {
beforeEach(() => {
sessionStore.clear();
});

describe('Export Field Validation (Literal)', () => {
it('should have correct name', () => {
expect(bootSim.name).toBe('boot_sim');
});

it('should have correct description', () => {
expect(bootSim.description).toBe(
"Boots an iOS simulator. After booting, use open_sim() to make the simulator visible. IMPORTANT: You MUST provide the simulatorUuid parameter. Example: boot_sim({ simulatorUuid: 'YOUR_UUID_HERE' })",
);
});

it('should have handler function', () => {
expect(typeof bootSim.handler).toBe('function');
it('should have concise description', () => {
expect(bootSim.description).toBe('Boots an iOS simulator.');
});

it('should have correct schema with simulatorUuid string field', () => {
it('should expose empty public schema', () => {
const schema = z.object(bootSim.schema);
expect(schema.safeParse({}).success).toBe(true);
expect(Object.keys(bootSim.schema)).toHaveLength(0);
});
});

// Valid inputs
expect(schema.safeParse({ simulatorUuid: 'test-uuid-123' }).success).toBe(true);
expect(schema.safeParse({ simulatorUuid: 'ABC123-DEF456' }).success).toBe(true);
describe('Handler Requirements', () => {
it('should require simulatorId when not provided', async () => {
const result = await bootSim.handler({});

// Invalid inputs
expect(schema.safeParse({ simulatorUuid: 123 }).success).toBe(false);
expect(schema.safeParse({ simulatorUuid: null }).success).toBe(false);
expect(schema.safeParse({ simulatorUuid: undefined }).success).toBe(false);
expect(schema.safeParse({}).success).toBe(false);
expect(result.isError).toBe(true);
expect(result.content[0].text).toContain('Missing required session defaults');
expect(result.content[0].text).toContain('simulatorId is required');
expect(result.content[0].text).toContain('session-set-defaults');
});
});

describe('Handler Behavior (Complete Literal Returns)', () => {
describe('Logic Behavior (Literal Results)', () => {
it('should handle successful boot', async () => {
const mockExecutor = createMockExecutor({
success: true,
output: 'Simulator booted successfully',
});

const result = await boot_simLogic({ simulatorUuid: 'test-uuid-123' }, mockExecutor);
const result = await boot_simLogic({ simulatorId: 'test-uuid-123' }, mockExecutor);

expect(result).toEqual({
content: [
Expand All @@ -61,24 +58,10 @@ describe('boot_sim tool', () => {

Next steps:
1. Open the Simulator app (makes it visible): open_sim()
2. Install an app: install_app_sim({ simulatorUuid: "test-uuid-123", appPath: "PATH_TO_YOUR_APP" })
3. Launch an app: launch_app_sim({ simulatorUuid: "test-uuid-123", bundleId: "YOUR_APP_BUNDLE_ID" })`,
},
],
});
});

it('should handle validation failure via handler', async () => {
const result = await bootSim.handler({ simulatorUuid: undefined });

expect(result).toEqual({
content: [
{
type: 'text',
text: 'Error: Parameter validation failed\nDetails: Invalid parameters:\nsimulatorUuid: Required',
2. Install an app: install_app_sim({ simulatorId: "test-uuid-123", appPath: "PATH_TO_YOUR_APP" })
3. Launch an app: launch_app_sim({ simulatorId: "test-uuid-123", bundleId: "YOUR_APP_BUNDLE_ID" })`,
},
],
isError: true,
});
});

Expand All @@ -88,7 +71,7 @@ Next steps:
error: 'Simulator not found',
});

const result = await boot_simLogic({ simulatorUuid: 'invalid-uuid' }, mockExecutor);
const result = await boot_simLogic({ simulatorId: 'invalid-uuid' }, mockExecutor);

expect(result).toEqual({
content: [
Expand All @@ -105,7 +88,7 @@ Next steps:
throw new Error('Connection failed');
};

const result = await boot_simLogic({ simulatorUuid: 'test-uuid-123' }, mockExecutor);
const result = await boot_simLogic({ simulatorId: 'test-uuid-123' }, mockExecutor);

expect(result).toEqual({
content: [
Expand All @@ -122,7 +105,7 @@ Next steps:
throw 'String error';
};

const result = await boot_simLogic({ simulatorUuid: 'test-uuid-123' }, mockExecutor);
const result = await boot_simLogic({ simulatorId: 'test-uuid-123' }, mockExecutor);

expect(result).toEqual({
content: [
Expand All @@ -135,7 +118,12 @@ Next steps:
});

it('should verify command generation with mock executor', async () => {
const calls: any[] = [];
const calls: Array<{
command: string[];
description: string;
allowStderr: boolean;
timeout?: number;
}> = [];
const mockExecutor = async (
command: string[],
description: string,
Expand All @@ -151,7 +139,7 @@ Next steps:
};
};

await boot_simLogic({ simulatorUuid: 'test-uuid-123' }, mockExecutor);
await boot_simLogic({ simulatorId: 'test-uuid-123' }, mockExecutor);

expect(calls).toHaveLength(1);
expect(calls[0]).toEqual({
Expand Down
Loading
Loading