Skip to content
94 changes: 94 additions & 0 deletions packages/eas-cli/src/commands/simulator/__tests__/exec.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { loadEnvFiles, loadProjectEnv } from '@expo/env';
import spawnAsync from '@expo/spawn-async';
import { Config } from '@oclif/core';

import SimulatorExec from '../exec';

jest.mock('@expo/env', () => ({
loadEnvFiles: jest.fn(),
loadProjectEnv: jest.fn(),
}));
jest.mock('@expo/spawn-async');

function getMockOclifConfig(): Config {
const config = new Config({ root: __dirname });
config.runHook = async () => ({
failures: [],
successes: [],
});
return config;
}

describe(SimulatorExec, () => {
const mockConfig = getMockOclifConfig();
const projectDir = '/test/project';

beforeEach(() => {
jest.clearAllMocks();
jest.mocked(spawnAsync).mockResolvedValue({} as never);
});

function createCommand(argv: string[]): {
command: SimulatorExec;
getContextAsync: jest.SpyInstance;
} {
const command = new SimulatorExec(argv, mockConfig);
// @ts-expect-error getContextAsync is protected
const getContextAsync = jest.spyOn(command, 'getContextAsync').mockResolvedValue({
projectDir,
});
return { command, getContextAsync };
}

it('loads local env files and spawns the supplied command with inherited stdio', async () => {
const { command, getContextAsync } = createCommand(['agent-device', 'touch', '@e2']);

await command.runAsync();

expect(getContextAsync).toHaveBeenCalledWith(SimulatorExec, {
nonInteractive: true,
});
expect(loadProjectEnv).toHaveBeenCalledWith(projectDir, { silent: true });
expect(loadEnvFiles).toHaveBeenCalledWith([`${projectDir}/.env.eas-simulator`], {
force: true,
});
expect(spawnAsync).toHaveBeenCalledWith('agent-device', ['touch', '@e2'], {
stdio: 'inherit',
env: process.env,
});
});

it('passes through command flags as args', async () => {
const { command } = createCommand([
'agent-device',
'screenshot',
'/test/path.png',
'--format',
'png',
]);

await command.runAsync();

expect(spawnAsync).toHaveBeenCalledWith(
'agent-device',
['screenshot', '/test/path.png', '--format', 'png'],
{
stdio: 'inherit',
env: process.env,
}
);
});

it('loads simulator-specific env after regular env files', async () => {
const { command } = createCommand(['agent-device', 'touch', '@e2']);
await command.runAsync();

expect(loadProjectEnv).toHaveBeenCalledWith(projectDir, { silent: true });
expect(loadEnvFiles).toHaveBeenCalledWith([`${projectDir}/.env.eas-simulator`], {
force: true,
});
expect(jest.mocked(loadProjectEnv).mock.invocationCallOrder[0]).toBeLessThan(
jest.mocked(loadEnvFiles).mock.invocationCallOrder[0]
);
});
});
31 changes: 31 additions & 0 deletions packages/eas-cli/src/commands/simulator/__tests__/get.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@ import {
JobRunStatus,
} from '../../../graphql/generated';
import { DeviceRunSessionQuery } from '../../../graphql/queries/DeviceRunSessionQuery';
import { EAS_SIMULATOR_SESSION_ID, loadSimulatorEnvAsync } from '../../../simulator/env';
import { enableJsonOutput, printJsonOnlyOutput } from '../../../utils/json';
import SimulatorGet from '../get';

jest.mock('../../../graphql/queries/DeviceRunSessionQuery');
jest.mock('../../../log');
jest.mock('../../../simulator/env', () => ({
...jest.requireActual('../../../simulator/env'),
loadSimulatorEnvAsync: jest.fn(),
}));
jest.mock('../../../ora', () => ({
ora: jest.fn(() => {
const spinner = {
Expand All @@ -30,6 +35,7 @@ type DeviceRunSessionById = DeviceRunSessionByIdQuery['deviceRunSessions']['byId

const mockByIdAsync = jest.mocked(DeviceRunSessionQuery.byIdAsync);
const mockEnableJsonOutput = jest.mocked(enableJsonOutput);
const mockLoadSimulatorEnvironmentVariablesAsync = jest.mocked(loadSimulatorEnvAsync);
const mockPrintJsonOnlyOutput = jest.mocked(printJsonOnlyOutput);

function makeDeviceRunSession(overrides: Partial<DeviceRunSessionById> = {}): DeviceRunSessionById {
Expand Down Expand Up @@ -71,9 +77,11 @@ function getMockOclifConfig(): Config {
describe(SimulatorGet, () => {
const graphqlClient = {} as ExpoGraphqlClient;
const mockConfig = getMockOclifConfig();
const projectDir = '/test/project';

beforeEach(() => {
jest.clearAllMocks();
mockLoadSimulatorEnvironmentVariablesAsync.mockResolvedValue();
});

function createCommand(argv: string[]): {
Expand All @@ -84,6 +92,7 @@ describe(SimulatorGet, () => {
// @ts-expect-error getContextAsync is protected
const getContextAsync = jest.spyOn(command, 'getContextAsync').mockResolvedValue({
loggedIn: { graphqlClient },
projectDir,
});
return { command, getContextAsync };
}
Expand All @@ -96,6 +105,7 @@ describe(SimulatorGet, () => {
await command.runAsync();

expect(mockEnableJsonOutput).toHaveBeenCalled();
expect(mockLoadSimulatorEnvironmentVariablesAsync).toHaveBeenCalledWith(projectDir);
expect(getContextAsync).toHaveBeenCalledWith(SimulatorGet, {
nonInteractive: true,
});
Expand All @@ -108,4 +118,25 @@ describe(SimulatorGet, () => {
remoteConfig: session.remoteConfig,
});
});

it(`uses ${EAS_SIMULATOR_SESSION_ID} from simulator env when --id is not passed`, async () => {
const previousDeviceRunSessionId = process.env[EAS_SIMULATOR_SESSION_ID];
const session = makeDeviceRunSession({ id: 'session-from-env' });
mockByIdAsync.mockResolvedValue(session);
process.env[EAS_SIMULATOR_SESSION_ID] = 'session-from-env';

try {
const { command } = createCommand([]);
await command.runAsync();

expect(mockLoadSimulatorEnvironmentVariablesAsync).toHaveBeenCalledWith(projectDir);
expect(mockByIdAsync).toHaveBeenCalledWith(graphqlClient, 'session-from-env');
} finally {
if (previousDeviceRunSessionId === undefined) {
delete process.env[EAS_SIMULATOR_SESSION_ID];
} else {
process.env[EAS_SIMULATOR_SESSION_ID] = previousDeviceRunSessionId;
}
}
});
});
Loading
Loading