1/*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import {describe, it} from 'mocha';
17import {expect} from 'chai';
18import {FileUtils} from '../../../src/utils/FileUtils';
19import {
20  writeCache,
21  spaceOfNameCache,
22  readCache,
23  getMapFromJson,
24  deleteLineInfoForNameString,
25  UpdateMemberMethodName,
26  MEM_METHOD_CACHE
27} from '../../../src/utils/NameCacheUtil';
28
29describe('test for NameCacheUtils', () => {
30  const destFileName = 'test/ut/utils/testWriteReadCache.json';
31
32  describe('writeCache', () => {
33    it('should write cache to file', function () {
34      const cache = new Map([
35        ['key1', 'value1'],
36        ['key2', 'value2'],
37      ]);
38
39      writeCache(cache, destFileName);
40
41      const content = FileUtils.readFile(destFileName);
42      expect(content).to.equal(JSON.stringify({ key1: 'value1', key2: 'value2' }, null, spaceOfNameCache));
43      FileUtils.deleteFile(destFileName);
44    });
45
46    it('should not write if cache is empty', function () {
47      const cache = undefined;
48
49      writeCache(cache, destFileName);
50
51      const content = FileUtils.readFile(destFileName);
52      expect(content).to.be.undefined;
53      FileUtils.deleteFile(destFileName);
54    });
55  });
56
57  describe('readCache', () => {
58    it('should return undefined when file does not exist', () => {
59      const result = readCache(destFileName);
60      expect(result).to.be.undefined;
61    });
62
63    it('should return parsed JSON object when file exists', () => {
64      const testData = { key: 'value' };
65      FileUtils.writeFile(destFileName, JSON.stringify(testData));
66
67      const result = readCache(destFileName);
68      expect(result).to.deep.equal(testData);
69
70      FileUtils.deleteFile(destFileName);
71    });
72  });
73
74  describe('getMapFromJson', () => {
75    it('should return an empty Map when input is undefined', () => {
76      const result = getMapFromJson(undefined);
77      expect(result).to.be.an.instanceof(Map);
78      expect(result.size).to.equal(0);
79    });
80
81    it('should convert a JSON object to a Map with string keys and values', () => {
82      const jsonObj = { key1: 'value1', key2: 'value2' };
83      const expectedMap = new Map([
84        ['key1', 'value1'],
85        ['key2', 'value2']
86      ]);
87      const result = getMapFromJson(jsonObj);
88      expect(result).to.deep.equal(expectedMap);
89    });
90  });
91
92  describe('deleteLineInfoForNameString', () => {
93    it('should update historyNameCache with new keys from identifierCache', () => {
94      const historyNameCache = new Map([
95        ['#key1', 'value1'],
96        ['#key2', 'value2']
97      ]);
98      const identifierCache = {
99        '#key3:112:110': 'newValue3',
100        '#key4': 'newValue4'
101      };
102
103      deleteLineInfoForNameString(historyNameCache, identifierCache);
104
105      expect(historyNameCache.get('#key1')).to.equal('value1');
106      expect(historyNameCache.get('#key2')).to.equal('value2');
107      expect(historyNameCache.get('#key3')).to.equal('newValue3');
108      expect(historyNameCache.get('#key4')).to.equal('newValue4');
109    });
110
111    it('should not modify historyNameCache if identifierCache is undefined', () => {
112      const historyNameCache = new Map([
113        ['#key1:11:2', 'value1'],
114        ['#key2:11:3', 'value2']
115      ]);
116
117      deleteLineInfoForNameString(historyNameCache, undefined);
118
119      expect(historyNameCache.get('#key1:11:2')).to.equal('value1');
120      expect(historyNameCache.get('#key2:11:3')).to.equal('value2');
121    });
122  });
123
124  describe('UpdateMemberMethodName', () => {
125    it('should update member method names in the cache', () => {
126      const nameCache = new Map();
127      const globalMangledTable = new Map([['originalName', 'mangledName']]);
128      const classInfoInMemberMethodCache = new Set(['class1']);
129
130      nameCache.set(MEM_METHOD_CACHE, new Map([['method1', 'originalName']]));
131
132      UpdateMemberMethodName(nameCache, globalMangledTable, classInfoInMemberMethodCache);
133
134      const updatedMemberMethodCache = nameCache.get(MEM_METHOD_CACHE) as Map<string, string>;
135      expect(updatedMemberMethodCache.get('method1')).to.equal('mangledName');
136    });
137
138    it('should not update member method names if they are in classInfoInMemberMethodCache', () => {
139      const nameCache = new Map();
140      const globalMangledTable = new Map([['originalName', 'mangledName']]);
141      const classInfoInMemberMethodCache = new Set(['method1']);
142
143      nameCache.set(MEM_METHOD_CACHE, new Map([['method1', 'originalName']]));
144
145      UpdateMemberMethodName(nameCache, globalMangledTable, classInfoInMemberMethodCache);
146
147      const updatedMemberMethodCache = nameCache.get(MEM_METHOD_CACHE) as Map<string, string>;
148      expect(updatedMemberMethodCache.get('method1')).to.equal('originalName');
149    });
150
151    it('do nothing if we do not set MEM_METHOD_CACHE', () => {
152      const nameCache = new Map();
153      const globalMangledTable = new Map([['originalName', 'mangledName']]);
154      const classInfoInMemberMethodCache = new Set(['method1']);
155
156      nameCache.set('testKey', new Map([['method1', 'originalName']]));
157
158      UpdateMemberMethodName(nameCache, globalMangledTable, classInfoInMemberMethodCache);
159
160      const updatedMemberMethodCache = nameCache.get('testKey') as Map<string, string>;
161      expect(updatedMemberMethodCache.get('method1')).to.equal('originalName');
162    });
163  });
164})