1import { asMock } from '../../__tests__/asMock';
2import { hasDirectDevClientDependency } from '../../utils/analytics/getDevClientProperties';
3import { resolvePortAsync } from '../../utils/port';
4import { resolveHostType, resolveOptionsAsync, resolvePortsAsync } from '../resolveOptions';
5
6jest.mock('../../utils/port', () => {
7  return {
8    resolvePortAsync: jest.fn(),
9  };
10});
11jest.mock('../../utils/scheme', () => {
12  return {
13    getOptionalDevClientSchemeAsync: jest.fn(async () => []),
14  };
15});
16jest.mock('../../utils/analytics/getDevClientProperties', () => {
17  return {
18    hasDirectDevClientDependency: jest.fn(() => false),
19  };
20});
21
22describe(resolveOptionsAsync, () => {
23  it(`prevents using --dev-client and --go together`, async () => {
24    await expect(
25      resolveOptionsAsync('/noop', {
26        '--dev-client': true,
27        '--go': true,
28      })
29    ).rejects.toThrowErrorMatchingInlineSnapshot(
30      `"Cannot use both --dev-client and --go together."`
31    );
32  });
33  it(`--go sets devClient to false`, async () => {
34    expect(
35      (
36        await resolveOptionsAsync('/noop', {
37          '--go': true,
38        })
39      ).devClient
40    ).toBe(false);
41  });
42  it(`defaults to devClient being false`, async () => {
43    expect((await resolveOptionsAsync('/noop', {})).devClient).toBe(false);
44  });
45  it(`sets devClient to true`, async () => {
46    expect((await resolveOptionsAsync('/noop', { '--dev-client': true })).devClient).toBe(true);
47  });
48  it(`infers that devClient should be true`, async () => {
49    jest.mocked(hasDirectDevClientDependency).mockReturnValueOnce(true);
50    expect((await resolveOptionsAsync('/noop', {})).devClient).toBe(true);
51  });
52  it(`--go forces devClient to false`, async () => {
53    jest.mocked(hasDirectDevClientDependency).mockReturnValueOnce(true);
54    expect((await resolveOptionsAsync('/noop', { '--go': true })).devClient).toBe(false);
55  });
56});
57
58describe(resolveHostType, () => {
59  it(`resolves no options`, () => {
60    expect(resolveHostType({})).toBe('lan');
61  });
62  it(`resolves host type`, () => {
63    expect(resolveHostType({ lan: true })).toBe('lan');
64    expect(resolveHostType({ localhost: true })).toBe('localhost');
65    expect(resolveHostType({ tunnel: true })).toBe('tunnel');
66    expect(resolveHostType({ offline: true })).toBe('lan');
67    expect(resolveHostType({ host: 'tunnel' })).toBe('tunnel');
68    // Default
69    expect(resolveHostType({})).toBe('lan');
70  });
71  it(`asserts invalid host type`, () => {
72    expect(() => resolveHostType({ host: 'bacon' })).toThrow();
73  });
74  it(`asserts conflicting options`, () => {
75    expect(() => resolveHostType({ localhost: true, offline: true })).toThrow(/Specify at most/);
76    expect(() => resolveHostType({ localhost: true, host: 'lan' })).toThrow(/Specify at most/);
77    expect(() => resolveHostType({ localhost: true, lan: true })).toThrow(/Specify at most/);
78    expect(() => resolveHostType({ tunnel: true, lan: true })).toThrow(/Specify at most/);
79  });
80});
81
82describe(resolvePortsAsync, () => {
83  beforeEach(() => {
84    asMock(resolvePortAsync).mockImplementation(async (root, { defaultPort, fallbackPort }) => {
85      if (typeof defaultPort === 'string' && defaultPort) {
86        return parseInt(defaultPort, 10);
87      } else if (typeof defaultPort === 'number' && defaultPort) {
88        return defaultPort;
89      }
90      return fallbackPort;
91    });
92  });
93  it(`resolves default port for metro`, async () => {
94    await expect(resolvePortsAsync('/noop', {}, { webOnly: false })).resolves.toStrictEqual({
95      metroPort: 8081,
96    });
97  });
98  it(`resolves default port with given port`, async () => {
99    await expect(
100      resolvePortsAsync('/noop', { port: 1234 }, { webOnly: false })
101    ).resolves.toStrictEqual({
102      metroPort: 1234,
103    });
104    await expect(
105      resolvePortsAsync('/noop', { port: 1234, devClient: true }, { webOnly: false })
106    ).resolves.toStrictEqual({
107      metroPort: 1234,
108    });
109    await expect(
110      resolvePortsAsync('/noop', { port: 1234 }, { webOnly: true })
111    ).resolves.toStrictEqual({
112      webpackPort: 1234,
113    });
114  });
115  it(`resolves default port for metro with dev client`, async () => {
116    await expect(
117      resolvePortsAsync('/noop', { devClient: true }, { webOnly: false })
118    ).resolves.toStrictEqual({
119      metroPort: 8081,
120    });
121  });
122  it(`resolves default port for webpack`, async () => {
123    await expect(resolvePortsAsync('/noop', {}, { webOnly: true })).resolves.toStrictEqual({
124      webpackPort: 19006,
125    });
126    // dev client changes nothing on Webpack...
127    await expect(
128      resolvePortsAsync('/noop', { devClient: true }, { webOnly: true })
129    ).resolves.toStrictEqual({
130      webpackPort: 19006,
131    });
132  });
133});
134