1import spawnAsync from '@expo/spawn-async';
2
3import { mockSpawnPromise, STUB_SPAWN_CHILD, STUB_SPAWN_RESULT } from '../../__tests__/spawn-utils';
4import { createPendingSpawnAsync } from '../spawn';
5
6jest.mock('@expo/spawn-async');
7
8const mockedSpawnAsync = spawnAsync as jest.MockedFunction<typeof spawnAsync>;
9
10describe(createPendingSpawnAsync, () => {
11  it('creates a promise with pending child promise', async () => {
12    const pending = createPendingSpawnAsync(
13      () => Promise.resolve(),
14      () => spawnAsync('foo', ['bar'])
15    );
16
17    expect(pending).toHaveProperty('child', expect.any(Promise));
18  });
19
20  it('pipes return of async action to spawn action', async () => {
21    const pending = createPendingSpawnAsync(
22      () => Promise.resolve(['custom', 'flags']),
23      (flags) => spawnAsync('foo', flags)
24    );
25
26    await pending;
27    expect(mockedSpawnAsync).toBeCalledWith('foo', ['custom', 'flags']);
28  });
29
30  it('pending promises resolves when both actions resolves', async () => {
31    const pending = createPendingSpawnAsync(
32      () => Promise.resolve(),
33      () => spawnAsync('foo', ['bar'])
34    );
35
36    await expect(pending).resolves.toMatchObject(STUB_SPAWN_RESULT);
37    await expect(pending.child).resolves.toMatchObject(STUB_SPAWN_CHILD);
38  });
39
40  it('pending child promise resolves to `null` when async action rejects', async () => {
41    const error = new Error('foo');
42    const pending = createPendingSpawnAsync(
43      () => Promise.reject(error),
44      () => spawnAsync('foo', ['bar'])
45    );
46
47    await expect(pending.child).resolves.toBeNull();
48    await expect(pending).rejects.toBe(error);
49  });
50
51  it('pending promise rejects when spawn action rejects', async () => {
52    const error = new Error('foo');
53    mockedSpawnAsync.mockImplementation(() => mockSpawnPromise(Promise.reject(error)));
54
55    const pending = createPendingSpawnAsync(
56      () => Promise.resolve(['other', 'custom', 'flags']),
57      (flags) => spawnAsync('foo', flags)
58    );
59
60    await expect(pending).rejects.toBe(error);
61    await expect(pending.child).resolves.toMatchObject(STUB_SPAWN_CHILD);
62
63    expect(mockedSpawnAsync).toBeCalledWith('foo', ['other', 'custom', 'flags']);
64  });
65});
66