mirror of https://github.com/artf/grapesjs.git
19 changed files with 898 additions and 859 deletions
@ -1,3 +1,4 @@ |
|||
docs/**/*.md |
|||
dist/ |
|||
pnpm-lock.yaml |
|||
pnpm-lock.yaml |
|||
packages/cli/src/template/**/*.* |
|||
@ -1,6 +1,3 @@ |
|||
module.exports = { |
|||
presets: [ |
|||
['@babel/preset-env', { targets: { node: 'current' } }], |
|||
'@babel/preset-typescript', |
|||
], |
|||
}; |
|||
presets: [['@babel/preset-env', { targets: { node: 'current' } }], '@babel/preset-typescript'], |
|||
}; |
|||
|
|||
@ -1,3 +1,3 @@ |
|||
export { default as init } from './init'; |
|||
export { default as build } from './build'; |
|||
export { default as serve } from './serve'; |
|||
export { default as serve } from './serve'; |
|||
|
|||
@ -1,338 +1,359 @@ |
|||
import { isFunction, isObject, isString, isUndefined, printRow, printError, log, ensureDir, normalizeJsonOpt, buildWebpackArgs, copyRecursiveSync, babelConfig, originalRequire, resolve, rootResolve } from "../src/utils"; |
|||
import { |
|||
isFunction, |
|||
isObject, |
|||
isString, |
|||
isUndefined, |
|||
printRow, |
|||
printError, |
|||
log, |
|||
ensureDir, |
|||
normalizeJsonOpt, |
|||
buildWebpackArgs, |
|||
copyRecursiveSync, |
|||
babelConfig, |
|||
originalRequire, |
|||
resolve, |
|||
rootResolve, |
|||
} from '../src/utils'; |
|||
import chalk from 'chalk'; |
|||
import fs from 'fs'; |
|||
import path from 'path'; |
|||
import * as process from 'process'; |
|||
|
|||
const typeTestValues = { |
|||
undefinedValue: undefined, |
|||
nullValue: null, |
|||
stringValue: 'hello', |
|||
emptyObject: {}, |
|||
nonEmptyObject: { key: 'value' }, |
|||
emptyArray: [], |
|||
functionValue: () => { }, |
|||
numberValue: 42, |
|||
booleanValue: true, |
|||
dateValue: new Date(), |
|||
undefinedValue: undefined, |
|||
nullValue: null, |
|||
stringValue: 'hello', |
|||
emptyObject: {}, |
|||
nonEmptyObject: { key: 'value' }, |
|||
emptyArray: [], |
|||
functionValue: () => {}, |
|||
numberValue: 42, |
|||
booleanValue: true, |
|||
dateValue: new Date(), |
|||
}; |
|||
|
|||
function runTypeCheck(typeCheckFunction: (value: any) => boolean) { |
|||
const keysWithPassingTypeChecks = Object.keys(typeTestValues).filter(key => { |
|||
const value = typeTestValues[key]; |
|||
return typeCheckFunction(value); |
|||
}); |
|||
const keysWithPassingTypeChecks = Object.keys(typeTestValues).filter((key) => { |
|||
const value = typeTestValues[key]; |
|||
return typeCheckFunction(value); |
|||
}); |
|||
|
|||
return keysWithPassingTypeChecks; |
|||
return keysWithPassingTypeChecks; |
|||
} |
|||
|
|||
jest.mock('fs'); |
|||
jest.mock('fs/promises'); |
|||
|
|||
describe('utils', () => { |
|||
afterEach(() => { |
|||
jest.clearAllMocks(); |
|||
afterEach(() => { |
|||
jest.clearAllMocks(); |
|||
}); |
|||
|
|||
describe('isString', () => { |
|||
it('should correctly identify strings', () => { |
|||
const result = runTypeCheck(isString); |
|||
expect(result).toEqual(['stringValue']); |
|||
}); |
|||
}); |
|||
|
|||
describe('isString', () => { |
|||
it('should correctly identify strings', () => { |
|||
const result = runTypeCheck(isString); |
|||
expect(result).toEqual(['stringValue']); |
|||
}); |
|||
describe('isUndefined', () => { |
|||
it('should correctly identify undefined values', () => { |
|||
const result = runTypeCheck(isUndefined); |
|||
expect(result).toEqual(['undefinedValue']); |
|||
}); |
|||
}); |
|||
|
|||
describe('isUndefined', () => { |
|||
it('should correctly identify undefined values', () => { |
|||
const result = runTypeCheck(isUndefined); |
|||
expect(result).toEqual(['undefinedValue']); |
|||
}); |
|||
describe('isFunction', () => { |
|||
it('should correctly identify functions', () => { |
|||
const result = runTypeCheck(isFunction); |
|||
expect(result).toEqual(['functionValue']); |
|||
}); |
|||
}); |
|||
|
|||
describe('isFunction', () => { |
|||
it('should correctly identify functions', () => { |
|||
const result = runTypeCheck(isFunction); |
|||
expect(result).toEqual(['functionValue']); |
|||
}); |
|||
describe('isObject', () => { |
|||
it('should correctly identify objects', () => { |
|||
const result = runTypeCheck(isObject); |
|||
expect(result).toEqual(['emptyObject', 'nonEmptyObject', 'dateValue']); |
|||
}); |
|||
}); |
|||
|
|||
describe('printRow', () => { |
|||
// TODO: We should refactor the function to make lineDown a boolean not a number
|
|||
it('should console.log the given string with the specified color and line breaks', () => { |
|||
const str = 'Test string'; |
|||
const color = 'blue'; |
|||
const lineDown = 1; |
|||
|
|||
console.log = jest.fn(); |
|||
|
|||
printRow(str, { color, lineDown }); |
|||
|
|||
describe('isObject', () => { |
|||
it('should correctly identify objects', () => { |
|||
const result = runTypeCheck(isObject); |
|||
expect(result).toEqual(['emptyObject', 'nonEmptyObject', 'dateValue']); |
|||
}); |
|||
expect(console.log).toHaveBeenCalledTimes(3); // 1 for empty line, 1 for colored string, 1 for line break
|
|||
expect(console.log.mock.calls[1][0]).toEqual(chalk[color].bold(str)); |
|||
}); |
|||
|
|||
it('should not add a line break if lineDown is false', () => { |
|||
const str = 'Test string'; |
|||
const color = 'green'; |
|||
const lineDown = 0; |
|||
|
|||
describe('printRow', () => { |
|||
// TODO: We should refactor the function to make lineDown a boolean not a number
|
|||
it('should console.log the given string with the specified color and line breaks', () => { |
|||
const str = 'Test string'; |
|||
const color = 'blue'; |
|||
const lineDown = 1; |
|||
console.log = jest.fn(); |
|||
|
|||
console.log = jest.fn(); |
|||
printRow(str, { color, lineDown }); |
|||
|
|||
printRow(str, { color, lineDown }); |
|||
expect(console.log).toHaveBeenCalledTimes(2); // 1 for empty line, 1 for colored string
|
|||
}); |
|||
}); |
|||
|
|||
describe('printError', () => { |
|||
it('should print the given string in red', () => { |
|||
const str = 'Error message'; |
|||
|
|||
expect(console.log).toHaveBeenCalledTimes(3); // 1 for empty line, 1 for colored string, 1 for line break
|
|||
expect(console.log.mock.calls[1][0]).toEqual(chalk[color].bold(str)); |
|||
}); |
|||
console.log = jest.fn(); |
|||
|
|||
it('should not add a line break if lineDown is false', () => { |
|||
const str = 'Test string'; |
|||
const color = 'green'; |
|||
const lineDown = 0; |
|||
printError(str); |
|||
|
|||
expect(console.log).toHaveBeenCalledTimes(3); // 1 for empty line, 1 for red string, 1 for line break
|
|||
expect(console.log.mock.calls[1][0]).toEqual(chalk.red.bold(str)); |
|||
}); |
|||
}); |
|||
|
|||
console.log = jest.fn(); |
|||
describe('log', () => { |
|||
it('should call console.log with the given arguments', () => { |
|||
const arg1 = 'Argument 1'; |
|||
const arg2 = 'Argument 2'; |
|||
|
|||
printRow(str, { color, lineDown }); |
|||
console.log = jest.fn(); |
|||
|
|||
expect(console.log).toHaveBeenCalledTimes(2); // 1 for empty line, 1 for colored string
|
|||
}); |
|||
log(arg1, arg2); |
|||
|
|||
expect(console.log).toHaveBeenCalledWith(arg1, arg2); |
|||
}); |
|||
}); |
|||
|
|||
describe('printError', () => { |
|||
it('should print the given string in red', () => { |
|||
const str = 'Error message'; |
|||
describe('ensureDir', () => { |
|||
it('should return true when the directory already exists', () => { |
|||
(fs.existsSync as jest.Mock).mockReturnValue(true); |
|||
|
|||
console.log = jest.fn(); |
|||
const result = ensureDir('/path/to/file.txt'); |
|||
expect(result).toBe(true); |
|||
expect(fs.existsSync).toHaveBeenCalledWith('/path/to'); |
|||
expect(fs.mkdirSync).not.toHaveBeenCalled(); |
|||
}); |
|||
|
|||
printError(str); |
|||
it('should create the directory when it does not exist', () => { |
|||
(fs.existsSync as jest.Mock).mockReturnValueOnce(false).mockReturnValueOnce(true); |
|||
|
|||
expect(console.log).toHaveBeenCalledTimes(3); // 1 for empty line, 1 for red string, 1 for line break
|
|||
expect(console.log.mock.calls[1][0]).toEqual(chalk.red.bold(str)); |
|||
}); |
|||
const result = ensureDir('/path/to/file.txt'); |
|||
expect(result).toBe(true); |
|||
expect(fs.existsSync).toHaveBeenCalledWith('/path/to'); |
|||
expect(fs.mkdirSync).toHaveBeenCalledWith('/path/to'); |
|||
}); |
|||
|
|||
describe('log', () => { |
|||
it('should call console.log with the given arguments', () => { |
|||
const arg1 = 'Argument 1'; |
|||
const arg2 = 'Argument 2'; |
|||
it('should create parent directories recursively when they do not exist', () => { |
|||
(fs.existsSync as jest.Mock) |
|||
.mockReturnValueOnce(false) // Check /path/to (does not exist)
|
|||
.mockReturnValueOnce(false) // Check /path (does not exist)
|
|||
.mockReturnValueOnce(true); // Check / (root, exists)
|
|||
|
|||
console.log = jest.fn(); |
|||
const result = ensureDir('/path/to/file.txt'); |
|||
expect(result).toBe(true); |
|||
expect(fs.existsSync).toHaveBeenCalledTimes(3); // /path/to, /path, /
|
|||
expect(fs.mkdirSync).toHaveBeenCalledTimes(2); // /path, /path/to
|
|||
}); |
|||
}); |
|||
|
|||
log(arg1, arg2); |
|||
describe('normalizeJsonOpt', () => { |
|||
it('should return the object if the option is already an object', () => { |
|||
const opts = { babel: { presets: ['@babel/preset-env'] } }; |
|||
const result = normalizeJsonOpt(opts, 'babel'); |
|||
expect(result).toEqual(opts.babel); |
|||
}); |
|||
|
|||
expect(console.log).toHaveBeenCalledWith(arg1, arg2); |
|||
}); |
|||
it('should parse and return the object if the option is a valid JSON string', () => { |
|||
const opts = { babel: '{"presets":["@babel/preset-env"]}' }; |
|||
const result = normalizeJsonOpt(opts, 'babel'); |
|||
expect(result).toEqual({ presets: ['@babel/preset-env'] }); |
|||
}); |
|||
|
|||
describe('ensureDir', () => { |
|||
it('should return true when the directory already exists', () => { |
|||
(fs.existsSync as jest.Mock).mockReturnValue(true); |
|||
|
|||
const result = ensureDir('/path/to/file.txt'); |
|||
expect(result).toBe(true); |
|||
expect(fs.existsSync).toHaveBeenCalledWith('/path/to'); |
|||
expect(fs.mkdirSync).not.toHaveBeenCalled(); |
|||
}); |
|||
|
|||
it('should create the directory when it does not exist', () => { |
|||
(fs.existsSync as jest.Mock).mockReturnValueOnce(false).mockReturnValueOnce(true); |
|||
|
|||
const result = ensureDir('/path/to/file.txt'); |
|||
expect(result).toBe(true); |
|||
expect(fs.existsSync).toHaveBeenCalledWith('/path/to'); |
|||
expect(fs.mkdirSync).toHaveBeenCalledWith('/path/to'); |
|||
}); |
|||
|
|||
it('should create parent directories recursively when they do not exist', () => { |
|||
(fs.existsSync as jest.Mock) |
|||
.mockReturnValueOnce(false) // Check /path/to (does not exist)
|
|||
.mockReturnValueOnce(false) // Check /path (does not exist)
|
|||
.mockReturnValueOnce(true); // Check / (root, exists)
|
|||
|
|||
const result = ensureDir('/path/to/file.txt'); |
|||
expect(result).toBe(true); |
|||
expect(fs.existsSync).toHaveBeenCalledTimes(3); // /path/to, /path, /
|
|||
expect(fs.mkdirSync).toHaveBeenCalledTimes(2); // /path, /path/to
|
|||
}); |
|||
it('should return an empty object if the option is an invalid JSON string', () => { |
|||
const opts = { babel: '{"presets":["@babel/preset-env"]' }; // Invalid JSON
|
|||
const result = normalizeJsonOpt(opts, 'babel'); |
|||
expect(result).toEqual({}); |
|||
}); |
|||
|
|||
describe('normalizeJsonOpt', () => { |
|||
it('should return the object if the option is already an object', () => { |
|||
const opts = { babel: { presets: ['@babel/preset-env'] } }; |
|||
const result = normalizeJsonOpt(opts, 'babel'); |
|||
expect(result).toEqual(opts.babel); |
|||
}); |
|||
|
|||
it('should parse and return the object if the option is a valid JSON string', () => { |
|||
const opts = { babel: '{"presets":["@babel/preset-env"]}' }; |
|||
const result = normalizeJsonOpt(opts, 'babel'); |
|||
expect(result).toEqual({ presets: ['@babel/preset-env'] }); |
|||
}); |
|||
|
|||
it('should return an empty object if the option is an invalid JSON string', () => { |
|||
const opts = { babel: '{"presets":["@babel/preset-env"]' }; // Invalid JSON
|
|||
const result = normalizeJsonOpt(opts, 'babel'); |
|||
expect(result).toEqual({}); |
|||
}); |
|||
|
|||
it('should return an empty object if the option is not provided', () => { |
|||
const opts = {}; |
|||
const result = normalizeJsonOpt(opts, 'babel'); |
|||
expect(result).toEqual({}); |
|||
}); |
|||
it('should return an empty object if the option is not provided', () => { |
|||
const opts = {}; |
|||
const result = normalizeJsonOpt(opts, 'babel'); |
|||
expect(result).toEqual({}); |
|||
}); |
|||
}); |
|||
|
|||
describe('buildWebpackArgs', () => { |
|||
it('should return the options with normalized JSON options for babel and htmlWebpack', () => { |
|||
const opts = { |
|||
babel: '{"presets":["@babel/preset-env"]}', |
|||
htmlWebpack: '{"template":"./src/index.html"}', |
|||
otherOption: 'someValue', |
|||
}; |
|||
|
|||
const result = buildWebpackArgs(opts); |
|||
expect(result).toEqual({ |
|||
babel: { presets: ['@babel/preset-env'] }, |
|||
htmlWebpack: { template: './src/index.html' }, |
|||
otherOption: 'someValue', |
|||
}); |
|||
}); |
|||
|
|||
describe('buildWebpackArgs', () => { |
|||
it('should return the options with normalized JSON options for babel and htmlWebpack', () => { |
|||
const opts = { |
|||
babel: '{"presets":["@babel/preset-env"]}', |
|||
htmlWebpack: '{"template":"./src/index.html"}', |
|||
otherOption: 'someValue' |
|||
}; |
|||
|
|||
const result = buildWebpackArgs(opts); |
|||
expect(result).toEqual({ |
|||
babel: { presets: ['@babel/preset-env'] }, |
|||
htmlWebpack: { template: './src/index.html' }, |
|||
otherOption: 'someValue', |
|||
}); |
|||
}); |
|||
|
|||
it('should return empty objects for babel and htmlWebpack if they are invalid JSON strings', () => { |
|||
const opts = { |
|||
babel: '{"presets":["@babel/preset-env"]', // Invalid JSON
|
|||
htmlWebpack: '{"template":"./src/index.html', // Invalid JSON
|
|||
}; |
|||
|
|||
const result = buildWebpackArgs(opts); |
|||
expect(result).toEqual({ |
|||
babel: {}, |
|||
htmlWebpack: {}, |
|||
}); |
|||
}); |
|||
|
|||
it('should return the original objects if babel and htmlWebpack are already objects', () => { |
|||
const opts = { |
|||
babel: { presets: ['@babel/preset-env'] }, |
|||
htmlWebpack: { template: './src/index.html' }, |
|||
}; |
|||
|
|||
const result = buildWebpackArgs(opts); |
|||
expect(result).toEqual({ |
|||
babel: opts.babel, |
|||
htmlWebpack: opts.htmlWebpack, |
|||
}); |
|||
}); |
|||
|
|||
it('should handle missing babel and htmlWebpack keys gracefully', () => { |
|||
const opts = { otherOption: 'someValue' }; |
|||
|
|||
const result = buildWebpackArgs(opts); |
|||
expect(result).toEqual({ |
|||
babel: {}, |
|||
htmlWebpack: {}, |
|||
otherOption: 'someValue', |
|||
}); |
|||
}); |
|||
it('should return empty objects for babel and htmlWebpack if they are invalid JSON strings', () => { |
|||
const opts = { |
|||
babel: '{"presets":["@babel/preset-env"]', // Invalid JSON
|
|||
htmlWebpack: '{"template":"./src/index.html', // Invalid JSON
|
|||
}; |
|||
|
|||
const result = buildWebpackArgs(opts); |
|||
expect(result).toEqual({ |
|||
babel: {}, |
|||
htmlWebpack: {}, |
|||
}); |
|||
}); |
|||
|
|||
describe('copyRecursiveSync', () => { |
|||
// TODO: Maybe this test case is a bit complex and we should think of an easier solution
|
|||
it('should copy a directory and its contents recursively', () => { |
|||
/** |
|||
* First call: Mock as a directory with two files |
|||
* Subsequent calls: Mock as a file |
|||
*/ |
|||
const existsSyncMock = (fs.existsSync as jest.Mock).mockReturnValue(true); |
|||
const statSyncMock = (fs.statSync as jest.Mock).mockReturnValueOnce({ isDirectory: () => true }).mockReturnValue({ isDirectory: () => false }); |
|||
const readdirSyncMock = (fs.readdirSync as jest.Mock).mockReturnValueOnce(['file1.txt', 'file2.txt']).mockReturnValue([]); |
|||
const copyFileSyncMock = (fs.copyFileSync as jest.Mock).mockImplementation(() => { }); |
|||
|
|||
copyRecursiveSync('/src', '/dest'); |
|||
|
|||
expect(existsSyncMock).toHaveBeenCalledWith('/src'); |
|||
expect(statSyncMock).toHaveBeenCalledWith('/src'); |
|||
expect(fs.mkdirSync).toHaveBeenCalledWith('/dest'); |
|||
expect(readdirSyncMock).toHaveBeenCalledWith('/src'); |
|||
expect(copyFileSyncMock).toHaveBeenCalledWith(path.normalize('/src/file1.txt'), path.normalize('/dest/file1.txt')); |
|||
expect(copyFileSyncMock).toHaveBeenCalledWith(path.normalize('/src/file2.txt'), path.normalize('/dest/file2.txt')); |
|||
}); |
|||
|
|||
it('should copy a file when source is a file', () => { |
|||
(fs.existsSync as jest.Mock).mockReturnValue(true); |
|||
(fs.statSync as jest.Mock).mockReturnValue({ isDirectory: () => false }); |
|||
|
|||
copyRecursiveSync('/src/file.txt', '/dest/file.txt'); |
|||
|
|||
expect(fs.existsSync).toHaveBeenCalledWith('/src/file.txt'); |
|||
expect(fs.statSync).toHaveBeenCalledWith('/src/file.txt'); |
|||
expect(fs.copyFileSync).toHaveBeenCalledWith('/src/file.txt', '/dest/file.txt'); |
|||
}); |
|||
|
|||
// Maybe we can change the behavior to throw an error if the `src` doesn't exist
|
|||
it('should do nothing when source does not exist', () => { |
|||
(fs.existsSync as jest.Mock).mockReturnValue(false); |
|||
|
|||
copyRecursiveSync('/src/file.txt', '/dest/file.txt'); |
|||
|
|||
expect(fs.existsSync).toHaveBeenCalledWith('/src/file.txt'); |
|||
expect(fs.statSync).not.toHaveBeenCalled(); |
|||
expect(fs.mkdirSync).not.toHaveBeenCalled(); |
|||
expect(fs.copyFileSync).not.toHaveBeenCalled(); |
|||
}); |
|||
it('should return the original objects if babel and htmlWebpack are already objects', () => { |
|||
const opts = { |
|||
babel: { presets: ['@babel/preset-env'] }, |
|||
htmlWebpack: { template: './src/index.html' }, |
|||
}; |
|||
|
|||
const result = buildWebpackArgs(opts); |
|||
expect(result).toEqual({ |
|||
babel: opts.babel, |
|||
htmlWebpack: opts.htmlWebpack, |
|||
}); |
|||
}); |
|||
|
|||
describe('rootResolve', () => { |
|||
it('should resolve a relative path to an absolute path', () => { |
|||
const result = rootResolve('src/index.js'); |
|||
it('should handle missing babel and htmlWebpack keys gracefully', () => { |
|||
const opts = { otherOption: 'someValue' }; |
|||
|
|||
expect(result).toBe(path.join(process.cwd(), 'src/index.js')); |
|||
}); |
|||
const result = buildWebpackArgs(opts); |
|||
expect(result).toEqual({ |
|||
babel: {}, |
|||
htmlWebpack: {}, |
|||
otherOption: 'someValue', |
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
describe('copyRecursiveSync', () => { |
|||
// TODO: Maybe this test case is a bit complex and we should think of an easier solution
|
|||
it('should copy a directory and its contents recursively', () => { |
|||
/** |
|||
* First call: Mock as a directory with two files |
|||
* Subsequent calls: Mock as a file |
|||
*/ |
|||
const existsSyncMock = (fs.existsSync as jest.Mock).mockReturnValue(true); |
|||
const statSyncMock = (fs.statSync as jest.Mock) |
|||
.mockReturnValueOnce({ isDirectory: () => true }) |
|||
.mockReturnValue({ isDirectory: () => false }); |
|||
const readdirSyncMock = (fs.readdirSync as jest.Mock) |
|||
.mockReturnValueOnce(['file1.txt', 'file2.txt']) |
|||
.mockReturnValue([]); |
|||
const copyFileSyncMock = (fs.copyFileSync as jest.Mock).mockImplementation(() => {}); |
|||
|
|||
copyRecursiveSync('/src', '/dest'); |
|||
|
|||
expect(existsSyncMock).toHaveBeenCalledWith('/src'); |
|||
expect(statSyncMock).toHaveBeenCalledWith('/src'); |
|||
expect(fs.mkdirSync).toHaveBeenCalledWith('/dest'); |
|||
expect(readdirSyncMock).toHaveBeenCalledWith('/src'); |
|||
expect(copyFileSyncMock).toHaveBeenCalledWith( |
|||
path.normalize('/src/file1.txt'), |
|||
path.normalize('/dest/file1.txt'), |
|||
); |
|||
expect(copyFileSyncMock).toHaveBeenCalledWith( |
|||
path.normalize('/src/file2.txt'), |
|||
path.normalize('/dest/file2.txt'), |
|||
); |
|||
}); |
|||
|
|||
describe('originalRequire', () => { |
|||
it('should return the original require.resolve function', () => { |
|||
const originalRequireMock = jest.fn(); |
|||
global.__non_webpack_require__ = originalRequireMock; |
|||
it('should copy a file when source is a file', () => { |
|||
(fs.existsSync as jest.Mock).mockReturnValue(true); |
|||
(fs.statSync as jest.Mock).mockReturnValue({ isDirectory: () => false }); |
|||
|
|||
const result = originalRequire(); |
|||
copyRecursiveSync('/src/file.txt', '/dest/file.txt'); |
|||
|
|||
expect(result).toBe(originalRequireMock); |
|||
}); |
|||
expect(fs.existsSync).toHaveBeenCalledWith('/src/file.txt'); |
|||
expect(fs.statSync).toHaveBeenCalledWith('/src/file.txt'); |
|||
expect(fs.copyFileSync).toHaveBeenCalledWith('/src/file.txt', '/dest/file.txt'); |
|||
}); |
|||
|
|||
describe('resolve', () => { |
|||
it('should resolve a module path using the original require.resolve', () => { |
|||
const originalRequireMock = { |
|||
resolve: jest.fn().mockReturnValue('resolved/path'), |
|||
}; |
|||
global.__non_webpack_require__ = originalRequireMock; |
|||
// Maybe we can change the behavior to throw an error if the `src` doesn't exist
|
|||
it('should do nothing when source does not exist', () => { |
|||
(fs.existsSync as jest.Mock).mockReturnValue(false); |
|||
|
|||
const result = resolve('my-module'); |
|||
copyRecursiveSync('/src/file.txt', '/dest/file.txt'); |
|||
|
|||
expect(result).toBe('resolved/path'); |
|||
expect(originalRequireMock.resolve).toHaveBeenCalledWith('my-module'); |
|||
}); |
|||
expect(fs.existsSync).toHaveBeenCalledWith('/src/file.txt'); |
|||
expect(fs.statSync).not.toHaveBeenCalled(); |
|||
expect(fs.mkdirSync).not.toHaveBeenCalled(); |
|||
expect(fs.copyFileSync).not.toHaveBeenCalled(); |
|||
}); |
|||
}); |
|||
|
|||
describe('rootResolve', () => { |
|||
it('should resolve a relative path to an absolute path', () => { |
|||
const result = rootResolve('src/index.js'); |
|||
|
|||
expect(result).toBe(path.join(process.cwd(), 'src/index.js')); |
|||
}); |
|||
}); |
|||
|
|||
describe('originalRequire', () => { |
|||
it('should return the original require.resolve function', () => { |
|||
const originalRequireMock = jest.fn(); |
|||
global.__non_webpack_require__ = originalRequireMock; |
|||
|
|||
const result = originalRequire(); |
|||
|
|||
expect(result).toBe(originalRequireMock); |
|||
}); |
|||
}); |
|||
|
|||
describe('resolve', () => { |
|||
it('should resolve a module path using the original require.resolve', () => { |
|||
const originalRequireMock = { |
|||
resolve: jest.fn().mockReturnValue('resolved/path'), |
|||
}; |
|||
global.__non_webpack_require__ = originalRequireMock; |
|||
|
|||
const result = resolve('my-module'); |
|||
|
|||
expect(result).toBe('resolved/path'); |
|||
expect(originalRequireMock.resolve).toHaveBeenCalledWith('my-module'); |
|||
}); |
|||
}); |
|||
|
|||
describe('babelConfig', () => { |
|||
afterEach(() => { |
|||
jest.restoreAllMocks(); |
|||
}); |
|||
|
|||
it('should return a Babel configuration object with specified presets and plugins', () => { |
|||
const result = babelConfig(); |
|||
|
|||
expect(result).toEqual({ |
|||
presets: [[resolve('@babel/preset-env'), { targets: undefined }]], |
|||
plugins: [resolve('@babel/plugin-transform-runtime')], |
|||
}); |
|||
}); |
|||
|
|||
it('should include the specified targets in the Babel configuration', () => { |
|||
const result = babelConfig({ targets: 'node 14' }); |
|||
|
|||
describe('babelConfig', () => { |
|||
afterEach(() => { |
|||
jest.restoreAllMocks(); |
|||
}); |
|||
|
|||
it('should return a Babel configuration object with specified presets and plugins', () => { |
|||
const result = babelConfig(); |
|||
|
|||
expect(result).toEqual({ |
|||
presets: [ |
|||
[resolve('@babel/preset-env'), { targets: undefined }], |
|||
], |
|||
plugins: [resolve('@babel/plugin-transform-runtime')], |
|||
}); |
|||
}); |
|||
|
|||
it('should include the specified targets in the Babel configuration', () => { |
|||
const result = babelConfig({ targets: 'node 14' }); |
|||
|
|||
expect(result).toEqual({ |
|||
presets: [ |
|||
[resolve('@babel/preset-env'), { targets: 'node 14' }], |
|||
], |
|||
plugins: [resolve('@babel/plugin-transform-runtime')], |
|||
}); |
|||
}); |
|||
expect(result).toEqual({ |
|||
presets: [[resolve('@babel/preset-env'), { targets: 'node 14' }]], |
|||
plugins: [resolve('@babel/plugin-transform-runtime')], |
|||
}); |
|||
}); |
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
Loading…
Reference in new issue