UNPKG

react-native-integrate

Version:

Automate integration of additional code into React Native projects

373 lines (372 loc) 15.5 kB
"use strict"; /* eslint-disable @typescript-eslint/no-unsafe-call */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const { mockFs } = require('../../mocks/mockAll'); const mockWaitForFile = jest.spyOn(require('../../../utils/waitForFile'), 'waitForFile'); const path_1 = __importDefault(require("path")); const fsTask_1 = require("../../../tasks/fsTask"); const getProjectPath_1 = require("../../../utils/getProjectPath"); const variables_1 = require("../../../variables"); const mockAll_1 = require("../../mocks/mockAll"); const projectFullPath = path_1.default.resolve(__dirname, '../../mock-project'); describe('fsTask', () => { beforeEach(() => { mockFs.writeFileSync('/test/file.json', 'test-content'); }); it('should handle upgrade when file is not in .upgrade folder', async () => { variables_1.variables.set('__UPGRADE__', true); mockAll_1.mockPrompter.text.mockReset(); const task = { task: 'fs', actions: [ { copyFile: 'file.json', destination: 'android/file.json', }, ], }; // enter mock file path mockAll_1.mockPrompter.text.mockImplementationOnce(() => '/test/file.json'); await (0, fsTask_1.fsTask)({ configPath: 'path/to/config', task: task, packageName: 'test-package', }); expect(mockAll_1.mockPrompter.text).toHaveBeenCalled(); expect(mockFs.readFileSync(path_1.default.join(projectFullPath, 'android', 'file.json'))).toEqual('test-content'); variables_1.variables.clear(); }); it('should handle upgrade when file is in upgrade.json but not in files folder', async () => { variables_1.variables.set('__UPGRADE__', true); mockFs.writeFileSync(path_1.default.join((0, getProjectPath_1.getProjectPath)(), '.upgrade', 'packages', 'test-package', 'upgrade.json'), JSON.stringify({ files: { 'android/file.json': 'file.json', }, }, null, 2)); mockAll_1.mockPrompter.text.mockReset(); const task = { task: 'fs', actions: [ { copyFile: 'file.json', destination: 'android/file.json', }, ], }; // enter mock file path mockAll_1.mockPrompter.text.mockImplementationOnce(() => '/test/file.json'); await (0, fsTask_1.fsTask)({ configPath: 'path/to/config', task: task, packageName: 'test-package', }); expect(mockAll_1.mockPrompter.text).toHaveBeenCalled(); expect(mockFs.readFileSync(path_1.default.join(projectFullPath, 'android', 'file.json'))).toEqual('test-content'); variables_1.variables.clear(); }); it('should handle upgrade when file is in upgrade.json and in files folder', async () => { variables_1.variables.set('__UPGRADE__', true); mockFs.writeFileSync(path_1.default.join((0, getProjectPath_1.getProjectPath)(), '.upgrade', 'packages', 'test-package', 'upgrade.json'), JSON.stringify({ files: { 'android/file.json': 'file.json', }, }, null, 2)); mockFs.writeFileSync(path_1.default.join((0, getProjectPath_1.getProjectPath)(), '.upgrade', 'packages', 'test-package', 'files', 'file.json'), 'test-upgrade-content'); mockAll_1.mockPrompter.text.mockReset(); const task = { task: 'fs', actions: [ { copyFile: 'file.json', destination: 'android/file.json', }, ], }; // enter mock file path mockAll_1.mockPrompter.text.mockImplementationOnce(() => '/test/file.json'); await (0, fsTask_1.fsTask)({ configPath: 'path/to/config', task: task, packageName: 'test-package', }); expect(mockAll_1.mockPrompter.text).not.toHaveBeenCalled(); expect(mockFs.readFileSync(path_1.default.join(projectFullPath, 'android', 'file.json'))).toEqual('test-upgrade-content'); variables_1.variables.clear(); }); it('should copy entered file to destination', async () => { mockAll_1.mockPrompter.text.mockReset(); const task = { task: 'fs', actions: [ { copyFile: 'file.json', destination: 'android/file.json', }, ], }; // enter mock file path mockAll_1.mockPrompter.text.mockImplementationOnce(() => '/test/file.json'); await (0, fsTask_1.fsTask)({ configPath: 'path/to/config', task: task, packageName: 'test-package', }); expect(mockAll_1.mockPrompter.text).toHaveBeenCalled(); expect(mockFs.readFileSync(path_1.default.join(projectFullPath, 'android', 'file.json'))).toEqual('test-content'); }); it('should throw when copy destination is out of project', async () => { mockAll_1.mockPrompter.text.mockReset(); const task = { task: 'fs', actions: [ { copyFile: 'file.json', destination: '../somewhere/file.json', }, ], }; // enter mock file path mockAll_1.mockPrompter.text.mockImplementationOnce(() => '/test/file.json'); await expect((0, fsTask_1.fsTask)({ configPath: 'path/to/config', task: task, packageName: 'test-package', })).rejects.toThrowError('invalid destination path'); }); it('should skip if condition not met', async () => { mockAll_1.mockPrompter.text.mockReset(); const task = { task: 'fs', actions: [ { when: { test: 'random' }, copyFile: 'file.json', destination: '../somewhere/file.json', }, ], }; // enter mock file path mockAll_1.mockPrompter.text.mockImplementationOnce(() => '/test/file.json'); await expect((0, fsTask_1.fsTask)({ configPath: 'path/to/config', task: task, packageName: 'test-package', })).resolves.not.toThrow(); }); it('should skip if waitForFile throws', async () => { mockAll_1.mockPrompter.text.mockReset(); mockAll_1.mockPrompter.confirm.mockReset(); mockAll_1.mockPrompter.log.message.mockReset(); // simulate file exists in path mockFs.writeFileSync(path_1.default.join(projectFullPath, 'android', 'file.json'), 'test-content'); const task = { task: 'fs', actions: [ { copyFile: 'file.json', destination: 'android/file.json', }, ], }; // enter empty string mockAll_1.mockPrompter.text.mockImplementationOnce(() => ''); mockAll_1.mockPrompter.confirm.mockImplementationOnce(() => true); mockWaitForFile.mockImplementationOnce(() => { return Promise.reject(new Error('skip')); }); await (0, fsTask_1.fsTask)({ configPath: 'path/to/config', task: task, packageName: 'test-package', }); expect(mockAll_1.mockPrompter.log.message).toHaveBeenCalledWith(expect.stringContaining('skipped copy operation')); }); it('should wait for user to copy file to destination when not exists', async () => { mockAll_1.mockPrompter.text.mockReset(); mockAll_1.mockPrompter.confirm.mockReset(); const task = { task: 'fs', actions: [ { copyFile: 'file.json', destination: 'android/file.json', }, ], }; // enter empty string mockAll_1.mockPrompter.text.mockImplementationOnce(() => ''); mockAll_1.mockPrompter.confirm.mockImplementationOnce(() => true); mockWaitForFile.mockImplementationOnce(() => { // simulate manually writing file mockFs.writeFileSync(path_1.default.join(projectFullPath, 'android', 'file.json'), 'test-content'); return Promise.resolve(true); }); await (0, fsTask_1.fsTask)({ configPath: 'path/to/config', task: task, packageName: 'test-package', }); expect(mockAll_1.mockPrompter.text).toHaveBeenCalled(); expect(mockFs.readFileSync(path_1.default.join(projectFullPath, 'android', 'file.json'))).toEqual('test-content'); }); it('should wait for user to copy file to destination when exists', async () => { mockAll_1.mockPrompter.text.mockReset(); mockAll_1.mockPrompter.confirm.mockReset(); mockAll_1.mockPrompter.log.message.mockReset(); // simulate file exists in path mockFs.writeFileSync(path_1.default.join(projectFullPath, 'android', 'file.json'), 'test-content'); const task = { task: 'fs', actions: [ { copyFile: 'file.json', destination: 'android/file.json', }, ], }; // enter empty string mockAll_1.mockPrompter.text.mockImplementationOnce(() => ''); mockAll_1.mockPrompter.confirm.mockImplementationOnce(() => true); mockWaitForFile.mockImplementationOnce(() => { return Promise.resolve(false); }); await (0, fsTask_1.fsTask)({ configPath: 'path/to/config', task: task, packageName: 'test-package', }); expect(mockAll_1.mockPrompter.text).toHaveBeenCalled(); expect(mockAll_1.mockPrompter.confirm).toHaveBeenCalled(); expect(mockAll_1.mockPrompter.log.message).toHaveBeenCalledWith(expect.stringContaining('file was updated')); expect(mockFs.readFileSync(path_1.default.join(projectFullPath, 'android', 'file.json'))).toEqual('test-content'); }); it('should handle when user skip copying a file to destination when exists', async () => { mockAll_1.mockPrompter.text.mockReset(); mockAll_1.mockPrompter.confirm.mockReset(); mockAll_1.mockPrompter.log.message.mockReset(); // simulate file exists in path mockFs.writeFileSync(path_1.default.join(projectFullPath, 'android', 'file.json'), 'test-content'); const task = { task: 'fs', actions: [ { copyFile: 'file.json', destination: 'android/file.json', }, ], }; // enter empty string mockAll_1.mockPrompter.text.mockImplementation(() => ''); mockAll_1.mockPrompter.confirm.mockImplementationOnce(() => false); mockWaitForFile.mockImplementationOnce(() => { return Promise.resolve(false); }); await (0, fsTask_1.fsTask)({ configPath: 'path/to/config', task: task, packageName: 'test-package', }); expect(mockAll_1.mockPrompter.text).toHaveBeenCalled(); expect(mockAll_1.mockPrompter.confirm).toHaveBeenCalled(); expect(mockAll_1.mockPrompter.confirm).toReturnWith(false); expect(mockAll_1.mockPrompter.log.message).toHaveBeenCalledWith(expect.stringContaining('skipped copy operation')); expect(mockFs.readFileSync(path_1.default.join(projectFullPath, 'android', 'file.json'))).toEqual('test-content'); }); it('should remove entered file', async () => { mockFs.writeFileSync(path_1.default.join(projectFullPath, 'android', 'file-to-delete.json'), 'test-content'); mockAll_1.mockPrompter.log.message.mockReset(); const task = { task: 'fs', actions: [ { removeFile: 'android/file-to-delete.json', }, ], }; // enter mock file path await (0, fsTask_1.fsTask)({ configPath: 'path/to/config', task: task, packageName: 'test-package', }); expect(mockFs.existsSync(path_1.default.join(projectFullPath, 'android', 'file-to-delete.json'))).toEqual(false); }); it('should skip remove entered file when not exists', async () => { mockAll_1.mockPrompter.log.message.mockReset(); expect(mockFs.existsSync(path_1.default.join(projectFullPath, 'android', 'file-to-delete.json'))).toEqual(false); const task = { task: 'fs', actions: [ { removeFile: 'file-to-delete.json', }, ], }; // enter mock file path await (0, fsTask_1.fsTask)({ configPath: 'path/to/config', task: task, packageName: 'test-package', }); expect(mockAll_1.mockPrompter.log.message).toHaveBeenCalledWith(expect.stringContaining('skipped remove operation')); }); it('should throw when strict remove file not exists', async () => { mockAll_1.mockPrompter.log.message.mockReset(); expect(mockFs.existsSync(path_1.default.join(projectFullPath, 'android', 'file-to-delete.json'))).toEqual(false); const task = { task: 'fs', actions: [ { removeFile: 'file-to-delete.json', strict: true, }, ], }; // enter mock file path await expect((0, fsTask_1.fsTask)({ configPath: 'path/to/config', task: task, packageName: 'test-package', })).rejects.toThrowError('does not exist'); }); it('should throw when remove destination is out of project', async () => { const task = { task: 'fs', actions: [ { removeFile: '../somewhere/file-to-delete.json', }, ], }; // enter mock file path await expect((0, fsTask_1.fsTask)({ configPath: 'path/to/config', task: task, packageName: 'test-package', })).rejects.toThrowError('invalid path to remove'); }); describe('runTask', () => { it('should run fs tasks', async () => { const task = { task: 'fs', actions: [ { copyFile: 'file.json', destination: 'android/file.json', }, ], }; // enter mock file path mockAll_1.mockPrompter.text.mockImplementationOnce(() => '/test/file.json'); await (0, fsTask_1.runTask)({ configPath: 'path/to/config', task: task, packageName: 'test-package', }); expect(mockFs.readFileSync(path_1.default.join(projectFullPath, 'android', 'file.json'))).toEqual('test-content'); }); }); });