Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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