1*082815dcSEvan Baconimport { ExportedConfig, Mod } from '../../Plugin.types';
2*082815dcSEvan Baconimport { evalModsAsync } from '../mod-compiler';
3*082815dcSEvan Baconimport { withBaseMod, withMod } from '../withMod';
4*082815dcSEvan Bacon
5*082815dcSEvan Bacondescribe(withMod, () => {
6*082815dcSEvan Bacon  it('compiles mods', async () => {
7*082815dcSEvan Bacon    // A basic plugin exported from an app.json
8*082815dcSEvan Bacon    const exportedConfig: ExportedConfig = { name: 'app', slug: '', mods: null };
9*082815dcSEvan Bacon
10*082815dcSEvan Bacon    const action: Mod<any> = jest.fn((props) => {
11*082815dcSEvan Bacon      // Capitalize app name
12*082815dcSEvan Bacon      props.name = (props.name as string).toUpperCase();
13*082815dcSEvan Bacon      return props;
14*082815dcSEvan Bacon    });
15*082815dcSEvan Bacon    // Apply mod
16*082815dcSEvan Bacon    let config = withBaseMod<any>(exportedConfig, {
17*082815dcSEvan Bacon      platform: 'android',
18*082815dcSEvan Bacon      mod: 'custom',
19*082815dcSEvan Bacon      isProvider: true,
20*082815dcSEvan Bacon      action,
21*082815dcSEvan Bacon    });
22*082815dcSEvan Bacon
23*082815dcSEvan Bacon    // Compile plugins generically
24*082815dcSEvan Bacon    config = await evalModsAsync(config, { projectRoot: '/' });
25*082815dcSEvan Bacon
26*082815dcSEvan Bacon    // Plugins should all be functions
27*082815dcSEvan Bacon    expect(Object.values(config.mods.android).every((value) => typeof value === 'function')).toBe(
28*082815dcSEvan Bacon      true
29*082815dcSEvan Bacon    );
30*082815dcSEvan Bacon
31*082815dcSEvan Bacon    delete config.mods;
32*082815dcSEvan Bacon
33*082815dcSEvan Bacon    // App config should have been modified
34*082815dcSEvan Bacon    expect(config).toStrictEqual({
35*082815dcSEvan Bacon      name: 'APP',
36*082815dcSEvan Bacon      slug: '',
37*082815dcSEvan Bacon    });
38*082815dcSEvan Bacon
39*082815dcSEvan Bacon    expect(action).toBeCalledWith(config);
40*082815dcSEvan Bacon  });
41*082815dcSEvan Bacon  it('asserts multiple providers added', async () => {
42*082815dcSEvan Bacon    // Apply a provider mod.
43*082815dcSEvan Bacon    const config = withBaseMod<any>(
44*082815dcSEvan Bacon      { name: 'app', slug: '', mods: null },
45*082815dcSEvan Bacon      {
46*082815dcSEvan Bacon        platform: 'android',
47*082815dcSEvan Bacon        mod: 'custom',
48*082815dcSEvan Bacon        isProvider: true,
49*082815dcSEvan Bacon        action(props) {
50*082815dcSEvan Bacon          // Capitalize app name
51*082815dcSEvan Bacon          props.name = (props.name as string).toUpperCase();
52*082815dcSEvan Bacon          return props;
53*082815dcSEvan Bacon        },
54*082815dcSEvan Bacon      }
55*082815dcSEvan Bacon    );
56*082815dcSEvan Bacon
57*082815dcSEvan Bacon    expect(() =>
58*082815dcSEvan Bacon      withBaseMod<any>(config, {
59*082815dcSEvan Bacon        platform: 'android',
60*082815dcSEvan Bacon        mod: 'custom',
61*082815dcSEvan Bacon        isProvider: true,
62*082815dcSEvan Bacon        action(props) {
63*082815dcSEvan Bacon          // Capitalize app name
64*082815dcSEvan Bacon          props.name = (props.name as string).toUpperCase();
65*082815dcSEvan Bacon          return props;
66*082815dcSEvan Bacon        },
67*082815dcSEvan Bacon      })
68*082815dcSEvan Bacon    ).toThrow(
69*082815dcSEvan Bacon      'Cannot set provider mod for "android.custom" because another is already being used.'
70*082815dcSEvan Bacon    );
71*082815dcSEvan Bacon  });
72*082815dcSEvan Bacon  it('throws when attempting to add a mod as the parent of a provider', async () => {
73*082815dcSEvan Bacon    // Apply a provider mod.
74*082815dcSEvan Bacon    const config = withBaseMod<any>(
75*082815dcSEvan Bacon      { name: 'app', slug: '' },
76*082815dcSEvan Bacon      {
77*082815dcSEvan Bacon        platform: 'android',
78*082815dcSEvan Bacon        mod: 'custom',
79*082815dcSEvan Bacon        isProvider: true,
80*082815dcSEvan Bacon        action(props) {
81*082815dcSEvan Bacon          // Capitalize app name
82*082815dcSEvan Bacon          props.name = (props.name as string).toUpperCase();
83*082815dcSEvan Bacon          return props;
84*082815dcSEvan Bacon        },
85*082815dcSEvan Bacon      }
86*082815dcSEvan Bacon    );
87*082815dcSEvan Bacon
88*082815dcSEvan Bacon    expect(() =>
89*082815dcSEvan Bacon      withMod<any>(config, {
90*082815dcSEvan Bacon        platform: 'android',
91*082815dcSEvan Bacon        mod: 'custom',
92*082815dcSEvan Bacon        action(props) {
93*082815dcSEvan Bacon          // Capitalize app name
94*082815dcSEvan Bacon          props.name = (props.name as string).toUpperCase();
95*082815dcSEvan Bacon          return props;
96*082815dcSEvan Bacon        },
97*082815dcSEvan Bacon      })
98*082815dcSEvan Bacon    ).toThrow(
99*082815dcSEvan Bacon      'Cannot add mod to "android.custom" because the provider has already been added. Provider must be the last mod added.'
100*082815dcSEvan Bacon    );
101*082815dcSEvan Bacon  });
102*082815dcSEvan Bacon});
103