1*082815dcSEvan Baconimport { vol } from 'memfs';
2*082815dcSEvan Bacon
3*082815dcSEvan Baconimport { writeXMLAsync } from '../../utils/XML';
4*082815dcSEvan Baconimport { buildResourceItem, readResourcesXMLAsync } from '../Resources';
5*082815dcSEvan Baconimport {
6*082815dcSEvan Bacon  getProjectStylesXMLPathAsync,
7*082815dcSEvan Bacon  getStyleParent,
8*082815dcSEvan Bacon  getStylesItem,
9*082815dcSEvan Bacon  removeStylesItem,
10*082815dcSEvan Bacon  setStylesItem,
11*082815dcSEvan Bacon} from '../Styles';
12*082815dcSEvan Baconjest.mock('fs');
13*082815dcSEvan Bacon
14*082815dcSEvan Baconconst mockStyles = `
15*082815dcSEvan Bacon<?xml
16*082815dcSEvan Bacon  version="1.0"
17*082815dcSEvan Bacon  encoding="UTF-8"
18*082815dcSEvan Bacon  standalone="yes"
19*082815dcSEvan Bacon?>
20*082815dcSEvan Bacon<resources>
21*082815dcSEvan Bacon  <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
22*082815dcSEvan Bacon    <item name="android:textColor">#000000</item>
23*082815dcSEvan Bacon    <item name="android:windowTranslucentStatus">true</item>
24*082815dcSEvan Bacon    <item name="colorPrimary">@color/colorPrimary</item>
25*082815dcSEvan Bacon  </style>
26*082815dcSEvan Bacon  <style name="Theme.App.SplashScreen" parent="AppTheme">
27*082815dcSEvan Bacon    <item name="android:windowBackground">@drawable/splashscreen</item>
28*082815dcSEvan Bacon  </style>
29*082815dcSEvan Bacon</resources>`;
30*082815dcSEvan Bacon
31*082815dcSEvan Bacondescribe('Styles', () => {
32*082815dcSEvan Bacon  beforeAll(async () => {
33*082815dcSEvan Bacon    const directoryJSON = {
34*082815dcSEvan Bacon      './app/android/app/src/main/res/values/styles.xml': mockStyles,
35*082815dcSEvan Bacon      './empty/android/app/src/main/res/values/styles.xml': '<resources></resources>',
36*082815dcSEvan Bacon    };
37*082815dcSEvan Bacon    vol.fromJSON(directoryJSON, '/');
38*082815dcSEvan Bacon  });
39*082815dcSEvan Bacon  afterAll(async () => {
40*082815dcSEvan Bacon    vol.reset();
41*082815dcSEvan Bacon  });
42*082815dcSEvan Bacon
43*082815dcSEvan Bacon  it(`sets a style on an empty resource item`, async () => {
44*082815dcSEvan Bacon    const stylesPath = await getProjectStylesXMLPathAsync('/empty')!;
45*082815dcSEvan Bacon    const xml = await readResourcesXMLAsync({ path: stylesPath });
46*082815dcSEvan Bacon    const parent = { name: 'AppTheme', parent: 'Theme.AppCompat.Light.NoActionBar' };
47*082815dcSEvan Bacon    setStylesItem({
48*082815dcSEvan Bacon      xml,
49*082815dcSEvan Bacon      parent,
50*082815dcSEvan Bacon      item: buildResourceItem({ name: 'android:textColor', value: '#fff000' }),
51*082815dcSEvan Bacon    });
52*082815dcSEvan Bacon    await writeXMLAsync({ path: stylesPath, xml });
53*082815dcSEvan Bacon
54*082815dcSEvan Bacon    const modifiedXml = await readResourcesXMLAsync({ path: stylesPath });
55*082815dcSEvan Bacon
56*082815dcSEvan Bacon    expect(getStyleParent(modifiedXml, parent)).toStrictEqual({
57*082815dcSEvan Bacon      $: { name: 'AppTheme', parent: 'Theme.AppCompat.Light.NoActionBar' },
58*082815dcSEvan Bacon      item: [{ $: { name: 'android:textColor' }, _: '#fff000' }],
59*082815dcSEvan Bacon    });
60*082815dcSEvan Bacon  });
61*082815dcSEvan Bacon  it(`changes the value of a style`, async () => {
62*082815dcSEvan Bacon    const stylesPath = await getProjectStylesXMLPathAsync('/app')!;
63*082815dcSEvan Bacon    const xml = await readResourcesXMLAsync({ path: stylesPath });
64*082815dcSEvan Bacon    const parent = { name: 'Theme.App.SplashScreen', parent: 'AppTheme' };
65*082815dcSEvan Bacon    setStylesItem({
66*082815dcSEvan Bacon      xml,
67*082815dcSEvan Bacon      parent,
68*082815dcSEvan Bacon      item: buildResourceItem({ name: 'android:textColor', value: '#ffffff' }),
69*082815dcSEvan Bacon    });
70*082815dcSEvan Bacon    await writeXMLAsync({ path: stylesPath, xml });
71*082815dcSEvan Bacon
72*082815dcSEvan Bacon    const modifiedXml = await readResourcesXMLAsync({ path: stylesPath });
73*082815dcSEvan Bacon
74*082815dcSEvan Bacon    expect(getStyleParent(modifiedXml, parent)).toStrictEqual({
75*082815dcSEvan Bacon      $: { name: 'Theme.App.SplashScreen', parent: 'AppTheme' },
76*082815dcSEvan Bacon      item: [
77*082815dcSEvan Bacon        { $: { name: 'android:windowBackground' }, _: '@drawable/splashscreen' },
78*082815dcSEvan Bacon        {
79*082815dcSEvan Bacon          $: {
80*082815dcSEvan Bacon            name: 'android:textColor',
81*082815dcSEvan Bacon          },
82*082815dcSEvan Bacon          _: '#ffffff',
83*082815dcSEvan Bacon        },
84*082815dcSEvan Bacon      ],
85*082815dcSEvan Bacon    });
86*082815dcSEvan Bacon  });
87*082815dcSEvan Bacon
88*082815dcSEvan Bacon  it(`removes a value`, async () => {
89*082815dcSEvan Bacon    const stylesPath = await getProjectStylesXMLPathAsync('/app')!;
90*082815dcSEvan Bacon    const xml = await readResourcesXMLAsync({ path: stylesPath });
91*082815dcSEvan Bacon    const parent = { name: 'Theme.App.SplashScreen', parent: 'AppTheme' };
92*082815dcSEvan Bacon    expect(getStylesItem({ xml, parent, name: 'android:textColor' })).toStrictEqual({
93*082815dcSEvan Bacon      $: {
94*082815dcSEvan Bacon        name: 'android:textColor',
95*082815dcSEvan Bacon      },
96*082815dcSEvan Bacon      _: '#ffffff',
97*082815dcSEvan Bacon    });
98*082815dcSEvan Bacon
99*082815dcSEvan Bacon    removeStylesItem({
100*082815dcSEvan Bacon      xml,
101*082815dcSEvan Bacon      parent,
102*082815dcSEvan Bacon      name: 'android:textColor',
103*082815dcSEvan Bacon    });
104*082815dcSEvan Bacon    expect(getStylesItem({ xml, parent, name: 'android:textColor' })).toBe(null);
105*082815dcSEvan Bacon  });
106*082815dcSEvan Bacon});
107