13af6ab5fSopenharmony_ci/*
23af6ab5fSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License.
53af6ab5fSopenharmony_ci * You may obtain a copy of the License at
63af6ab5fSopenharmony_ci *
73af6ab5fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83af6ab5fSopenharmony_ci *
93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and
133af6ab5fSopenharmony_ci * limitations under the License.
143af6ab5fSopenharmony_ci */
153af6ab5fSopenharmony_ci
163af6ab5fSopenharmony_ciimport { describe, it } from 'mocha';
173af6ab5fSopenharmony_ciimport { expect } from 'chai';
183af6ab5fSopenharmony_ciimport sinon from 'sinon';
193af6ab5fSopenharmony_ciimport proxyquire from 'proxyquire';
203af6ab5fSopenharmony_ciimport { constants } from 'fs';
213af6ab5fSopenharmony_ci
223af6ab5fSopenharmony_ciimport { IOptions } from '../../../src/configs/IOptions';
233af6ab5fSopenharmony_ci
243af6ab5fSopenharmony_ciconst fsStub = {
253af6ab5fSopenharmony_ci  existsSync: sinon.stub(),
263af6ab5fSopenharmony_ci  accessSync: sinon.stub(),
273af6ab5fSopenharmony_ci};
283af6ab5fSopenharmony_ci
293af6ab5fSopenharmony_ciconst fsExtraStub = {
303af6ab5fSopenharmony_ci  readJsonSync: sinon.stub()
313af6ab5fSopenharmony_ci};
323af6ab5fSopenharmony_ci
333af6ab5fSopenharmony_ciconst { FileUtils, IOptions } = proxyquire('../../../src/utils/FileUtils', {
343af6ab5fSopenharmony_ci  'fs': fsStub,
353af6ab5fSopenharmony_ci  'fs-extra': fsExtraStub
363af6ab5fSopenharmony_ci});
373af6ab5fSopenharmony_ci
383af6ab5fSopenharmony_cidescribe('FileUtils.readFileAsJson', () => {
393af6ab5fSopenharmony_ci  let consoleErrorStub:sinon.SinonStub;
403af6ab5fSopenharmony_ci  beforeEach(() => {
413af6ab5fSopenharmony_ci    consoleErrorStub = sinon.stub(console, 'error');
423af6ab5fSopenharmony_ci  });
433af6ab5fSopenharmony_ci
443af6ab5fSopenharmony_ci  afterEach(() => {
453af6ab5fSopenharmony_ci    sinon.restore();
463af6ab5fSopenharmony_ci  });
473af6ab5fSopenharmony_ci
483af6ab5fSopenharmony_ci  it('should return undefined if file does not exist', () => {
493af6ab5fSopenharmony_ci    fsStub.existsSync.returns(false);
503af6ab5fSopenharmony_ci    const result = FileUtils.readFileAsJson('fakePath.json');
513af6ab5fSopenharmony_ci    expect(result).to.be.undefined;
523af6ab5fSopenharmony_ci    expect(consoleErrorStub.calledWith('File <fakePath.json> is not found.')).to.be.true;
533af6ab5fSopenharmony_ci  });
543af6ab5fSopenharmony_ci
553af6ab5fSopenharmony_ci  it('should return undefined if readJsonSync throws an error', () => {
563af6ab5fSopenharmony_ci    fsStub.existsSync.returns(true);
573af6ab5fSopenharmony_ci    fsExtraStub.readJsonSync.throws(new Error('read error'));
583af6ab5fSopenharmony_ci    const result = FileUtils.readFileAsJson('fakePath.json');
593af6ab5fSopenharmony_ci    expect(result).to.be.undefined;
603af6ab5fSopenharmony_ci    expect(consoleErrorStub.calledWith('json file read error: fakePath.json')).to.be.true;
613af6ab5fSopenharmony_ci  });
623af6ab5fSopenharmony_ci
633af6ab5fSopenharmony_ci  it('should return JSON content if file exists and is valid', () => {
643af6ab5fSopenharmony_ci    const jsonContent: IOptions = { mCompact: true };
653af6ab5fSopenharmony_ci    fsStub.existsSync.returns(true);
663af6ab5fSopenharmony_ci    fsExtraStub.readJsonSync.returns(jsonContent);
673af6ab5fSopenharmony_ci    const result = FileUtils.readFileAsJson('validPath.json');
683af6ab5fSopenharmony_ci    expect(result).to.deep.equal(jsonContent);
693af6ab5fSopenharmony_ci  });
703af6ab5fSopenharmony_ci});
713af6ab5fSopenharmony_ci
723af6ab5fSopenharmony_cidescribe('FileUtils.getFileExtension', () => {
733af6ab5fSopenharmony_ci  it('should return undefined for empty string', () => {
743af6ab5fSopenharmony_ci    const result = FileUtils.getFileExtension('');
753af6ab5fSopenharmony_ci    expect(result).to.be.undefined;
763af6ab5fSopenharmony_ci  });
773af6ab5fSopenharmony_ci
783af6ab5fSopenharmony_ci  it('should return undefined for string without dot', () => {
793af6ab5fSopenharmony_ci    const result = FileUtils.getFileExtension('filename');
803af6ab5fSopenharmony_ci    expect(result).to.be.undefined;
813af6ab5fSopenharmony_ci  });
823af6ab5fSopenharmony_ci
833af6ab5fSopenharmony_ci  it('should return undefined for path string without dot', () => {
843af6ab5fSopenharmony_ci    const result = FileUtils.getFileExtension('path/to.test/filename');
853af6ab5fSopenharmony_ci    expect(result).to.be.undefined;
863af6ab5fSopenharmony_ci  });
873af6ab5fSopenharmony_ci
883af6ab5fSopenharmony_ci  it('should return undefined for string ending with a dot', () => {
893af6ab5fSopenharmony_ci    const result = FileUtils.getFileExtension('filename.');
903af6ab5fSopenharmony_ci    expect(result).to.equal('');
913af6ab5fSopenharmony_ci  });
923af6ab5fSopenharmony_ci
933af6ab5fSopenharmony_ci  it('should return extension for valid file path', () => {
943af6ab5fSopenharmony_ci    const result = FileUtils.getFileExtension('/path/to/file.txt');
953af6ab5fSopenharmony_ci    expect(result).to.equal('txt');
963af6ab5fSopenharmony_ci  });
973af6ab5fSopenharmony_ci
983af6ab5fSopenharmony_ci  it('should return extension for valid file name with multiple dots', () => {
993af6ab5fSopenharmony_ci    const result = FileUtils.getFileExtension('/path/to/file.name.with.dots.txt');
1003af6ab5fSopenharmony_ci    expect(result).to.equal('txt');
1013af6ab5fSopenharmony_ci  });
1023af6ab5fSopenharmony_ci});
1033af6ab5fSopenharmony_ci
1043af6ab5fSopenharmony_cidescribe('FileUtils.isRelativePath', () => {
1053af6ab5fSopenharmony_ci  it('should return true for relative paths starting with ./', () => {
1063af6ab5fSopenharmony_ci    const result = FileUtils.isRelativePath('./file.txt');
1073af6ab5fSopenharmony_ci    expect(result).to.be.true;
1083af6ab5fSopenharmony_ci  });
1093af6ab5fSopenharmony_ci
1103af6ab5fSopenharmony_ci  it('should return true for relative paths starting with ../', () => {
1113af6ab5fSopenharmony_ci    const result = FileUtils.isRelativePath('../file.txt');
1123af6ab5fSopenharmony_ci    expect(result).to.be.true;
1133af6ab5fSopenharmony_ci  });
1143af6ab5fSopenharmony_ci
1153af6ab5fSopenharmony_ci  it('should return true for relative paths starting with .\\', () => {
1163af6ab5fSopenharmony_ci    const result = FileUtils.isRelativePath('.\\file.txt');
1173af6ab5fSopenharmony_ci    expect(result).to.be.true;
1183af6ab5fSopenharmony_ci  });
1193af6ab5fSopenharmony_ci
1203af6ab5fSopenharmony_ci  it('should return true for relative paths starting with ..\\', () => {
1213af6ab5fSopenharmony_ci    const result = FileUtils.isRelativePath('..\\file.txt');
1223af6ab5fSopenharmony_ci    expect(result).to.be.true;
1233af6ab5fSopenharmony_ci  });
1243af6ab5fSopenharmony_ci
1253af6ab5fSopenharmony_ci  it('should return false for absolute paths', () => {
1263af6ab5fSopenharmony_ci    const result = FileUtils.isRelativePath('/absolute/path/to/file.txt');
1273af6ab5fSopenharmony_ci    expect(result).to.be.false;
1283af6ab5fSopenharmony_ci  });
1293af6ab5fSopenharmony_ci
1303af6ab5fSopenharmony_ci  it('should return false for Windows absolute paths', () => {
1313af6ab5fSopenharmony_ci    const result = FileUtils.isRelativePath('C:\\absolute\\path\\to\\file.txt');
1323af6ab5fSopenharmony_ci    expect(result).to.be.false;
1333af6ab5fSopenharmony_ci  });
1343af6ab5fSopenharmony_ci});
1353af6ab5fSopenharmony_ci
1363af6ab5fSopenharmony_cidescribe('FileUtils.isReadableFile', () => {
1373af6ab5fSopenharmony_ci  afterEach(() => {
1383af6ab5fSopenharmony_ci    sinon.restore();
1393af6ab5fSopenharmony_ci  });
1403af6ab5fSopenharmony_ci
1413af6ab5fSopenharmony_ci  it('should return true if file is readable', () => {
1423af6ab5fSopenharmony_ci    fsStub.accessSync.withArgs('readableFile.txt', constants.R_OK).returns(undefined);
1433af6ab5fSopenharmony_ci    const result = FileUtils.isReadableFile('readableFile.txt');
1443af6ab5fSopenharmony_ci    expect(result).to.be.true;
1453af6ab5fSopenharmony_ci  });
1463af6ab5fSopenharmony_ci
1473af6ab5fSopenharmony_ci  it('should return false if file is not readable', () => {
1483af6ab5fSopenharmony_ci    fsStub.accessSync.withArgs('unreadableFile.txt', constants.R_OK).throws(new Error('Not readable'));
1493af6ab5fSopenharmony_ci    const result = FileUtils.isReadableFile('unreadableFile.txt');
1503af6ab5fSopenharmony_ci    expect(result).to.be.false;
1513af6ab5fSopenharmony_ci  });
1523af6ab5fSopenharmony_ci});
1533af6ab5fSopenharmony_ci
1543af6ab5fSopenharmony_cidescribe('FileUtils.toUnixPath', () => {
1553af6ab5fSopenharmony_ci  let osStub: sinon.SinonStub;
1563af6ab5fSopenharmony_ci  let pathStub: sinon.SinonStub;
1573af6ab5fSopenharmony_ci
1583af6ab5fSopenharmony_ci  beforeEach(() => {
1593af6ab5fSopenharmony_ci    osStub = sinon.stub(require('os'), 'platform');
1603af6ab5fSopenharmony_ci    pathStub = sinon.stub(require('path'), 'sep').value('/'); // Default to Unix-like separator
1613af6ab5fSopenharmony_ci  });
1623af6ab5fSopenharmony_ci
1633af6ab5fSopenharmony_ci  afterEach(() => {
1643af6ab5fSopenharmony_ci    sinon.restore();
1653af6ab5fSopenharmony_ci  });
1663af6ab5fSopenharmony_ci
1673af6ab5fSopenharmony_ci  it('should convert Windows path to Unix path', () => {
1683af6ab5fSopenharmony_ci    osStub.returns('win32');
1693af6ab5fSopenharmony_ci    const proxyquireUtils = proxyquire('../../../src/utils/FileUtils', {
1703af6ab5fSopenharmony_ci      'os': {
1713af6ab5fSopenharmony_ci        platform: osStub
1723af6ab5fSopenharmony_ci      },
1733af6ab5fSopenharmony_ci      'path': {
1743af6ab5fSopenharmony_ci        sep: '\\',
1753af6ab5fSopenharmony_ci        posix: {
1763af6ab5fSopenharmony_ci          join: (...paths: string[]) => paths.join('/')
1773af6ab5fSopenharmony_ci        }
1783af6ab5fSopenharmony_ci      }
1793af6ab5fSopenharmony_ci    });
1803af6ab5fSopenharmony_ci    const result = proxyquireUtils.FileUtils.toUnixPath('C:\\path\\to\\file.txt');
1813af6ab5fSopenharmony_ci    expect(result).to.equal('C:/path/to/file.txt');
1823af6ab5fSopenharmony_ci  });
1833af6ab5fSopenharmony_ci
1843af6ab5fSopenharmony_ci  it('should return Unix path unchanged', () => {
1853af6ab5fSopenharmony_ci    osStub.returns('linux');
1863af6ab5fSopenharmony_ci    const result = FileUtils.toUnixPath('/path/to/file.txt');
1873af6ab5fSopenharmony_ci    expect(result).to.equal('/path/to/file.txt');
1883af6ab5fSopenharmony_ci  });
1893af6ab5fSopenharmony_ci});
1903af6ab5fSopenharmony_ci
1913af6ab5fSopenharmony_cidescribe('FileUtils.getAbsPathBaseConfigPath', () => {
1923af6ab5fSopenharmony_ci  it('should return absolute path', () => {
1933af6ab5fSopenharmony_ci    expect(FileUtils.getAbsPathBaseConfigPath('/abs/path/abc', 'file.txt')).to.equal('/abs/path/file.txt')
1943af6ab5fSopenharmony_ci  });
1953af6ab5fSopenharmony_ci
1963af6ab5fSopenharmony_ci  // Return non-absolute path? May need to be fixed.
1973af6ab5fSopenharmony_ci  it('should return non-absolute path', () => {
1983af6ab5fSopenharmony_ci    expect(FileUtils.getAbsPathBaseConfigPath('not_abs/path/abc', 'file.txt')).to.equal('not_abs/path/file.txt')
1993af6ab5fSopenharmony_ci  });
2003af6ab5fSopenharmony_ci
2013af6ab5fSopenharmony_ci  it('should handle empty paths', () => {
2023af6ab5fSopenharmony_ci    expect(FileUtils.getAbsPathBaseConfigPath('', '')).to.equal('.')
2033af6ab5fSopenharmony_ci  });
2043af6ab5fSopenharmony_ci});