1import { compileMockModWithResultsAsync } from '../../plugins/__tests__/mockMods';
2import { withGradleProperties } from '../../plugins/android-plugins';
3import {
4  updateAndroidBuildPropertiesFromConfig,
5  updateAndroidBuildProperty,
6  withJsEngineGradleProps,
7} from '../BuildProperties';
8import { parsePropertiesFile, PropertiesItem } from '../Properties';
9
10jest.mock('../../plugins/android-plugins');
11
12describe(withJsEngineGradleProps, () => {
13  const JS_ENGINE_PROP_KEY = 'expo.jsEngine';
14
15  it('set the property from shared `jsEngine` config', async () => {
16    const { modResults } = await compileMockModWithResultsAsync(
17      { jsEngine: 'hermes' },
18      {
19        plugin: withJsEngineGradleProps,
20        mod: withGradleProperties,
21        modResults: [],
22      }
23    );
24    expect(modResults).toContainEqual({
25      type: 'property',
26      key: JS_ENGINE_PROP_KEY,
27      value: 'hermes',
28    });
29  });
30
31  it('set the property from platform override `jsEngine`', async () => {
32    const { modResults } = await compileMockModWithResultsAsync(
33      { jsEngine: 'hermes', android: { jsEngine: 'jsc' } },
34      {
35        plugin: withJsEngineGradleProps,
36        mod: withGradleProperties,
37        modResults: [],
38      }
39    );
40    expect(modResults).toContainEqual({
41      type: 'property',
42      key: JS_ENGINE_PROP_KEY,
43      value: 'jsc',
44    });
45  });
46
47  it('overwrite the property if an old property is existed', async () => {
48    const originalGradleProperties = parsePropertiesFile(`
49android.useAndroidX=true
50android.enableJetifier=true
51expo.jsEngine=jsc
52`);
53
54    const { modResults } = await compileMockModWithResultsAsync(
55      { android: { jsEngine: 'hermes' } },
56      {
57        plugin: withJsEngineGradleProps,
58        mod: withGradleProperties,
59        modResults: originalGradleProperties,
60      }
61    );
62    expect(modResults).toContainEqual({
63      type: 'property',
64      key: JS_ENGINE_PROP_KEY,
65      value: 'hermes',
66    });
67  });
68});
69
70describe(updateAndroidBuildPropertiesFromConfig, () => {
71  it('should respect `propValueGetter` order', () => {
72    const gradleProperties = [];
73    const configToPropertyRules = [
74      {
75        propName: 'expo.jsEngine',
76        propValueGetter: (config) => config.android?.jsEngine ?? config.jsEngine ?? 'NOTFOUND',
77      },
78    ];
79
80    expect(
81      updateAndroidBuildPropertiesFromConfig(
82        { jsEngine: 'hermes', android: { jsEngine: 'jsc' } },
83        gradleProperties,
84        configToPropertyRules
85      )
86    ).toContainEqual({
87      type: 'property',
88      key: 'expo.jsEngine',
89      value: 'jsc',
90    });
91
92    expect(
93      updateAndroidBuildPropertiesFromConfig(
94        { jsEngine: 'jsc' },
95        gradleProperties,
96        configToPropertyRules
97      )
98    ).toContainEqual({
99      type: 'property',
100      key: 'expo.jsEngine',
101      value: 'jsc',
102    });
103
104    expect(
105      updateAndroidBuildPropertiesFromConfig({}, gradleProperties, configToPropertyRules)
106    ).toContainEqual({
107      type: 'property',
108      key: 'expo.jsEngine',
109      value: 'NOTFOUND',
110    });
111  });
112});
113
114describe(updateAndroidBuildProperty, () => {
115  it('should merge properties', () => {
116    const gradleProperties: PropertiesItem[] = [
117      { type: 'property', key: 'foo', value: 'foo' },
118      { type: 'property', key: 'bar', value: 'bar' },
119      { type: 'property', key: 'name', value: 'oldName' },
120    ];
121    expect(updateAndroidBuildProperty(gradleProperties, 'name', 'newName')).toEqual([
122      { type: 'property', key: 'foo', value: 'foo' },
123      { type: 'property', key: 'bar', value: 'bar' },
124      { type: 'property', key: 'name', value: 'newName' },
125    ]);
126  });
127
128  it('should keep original property when `value` is null by default', () => {
129    const gradleProperties: PropertiesItem[] = [
130      { type: 'property', key: 'foo', value: 'foo' },
131      { type: 'property', key: 'bar', value: 'bar' },
132    ];
133    expect(updateAndroidBuildProperty(gradleProperties, 'bar', null)).toEqual([
134      { type: 'property', key: 'foo', value: 'foo' },
135      { type: 'property', key: 'bar', value: 'bar' },
136    ]);
137  });
138
139  it('should remove original property when `value` is null when `removePropWhenValueIsNull` is true', () => {
140    const gradleProperties: PropertiesItem[] = [
141      { type: 'property', key: 'foo', value: 'foo' },
142      { type: 'property', key: 'bar', value: 'bar' },
143    ];
144    expect(
145      updateAndroidBuildProperty(gradleProperties, 'bar', null, {
146        removePropWhenValueIsNull: true,
147      })
148    ).toEqual([{ type: 'property', key: 'foo', value: 'foo' }]);
149  });
150});
151