-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(kitify): Add clone utilities and tests (#11)
Clone
- Loading branch information
Showing
12 changed files
with
734 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
//@ts-nocheck | ||
import clone from '../clone' | ||
|
||
describe('clone', () => { | ||
it('should return the same value for primitive types', () => { | ||
expect(clone(123)).toBe(123) | ||
expect(clone('abc')).toBe('abc') | ||
expect(clone(true)).toBe(true) | ||
expect(clone(null)).toBe(null) | ||
expect(clone(undefined)).toBe(undefined) | ||
|
||
const sym = Symbol('sym') | ||
expect(clone(sym)).toEqual(sym) | ||
}) | ||
|
||
it('should clone Date objects correctly', () => { | ||
const date = new Date() | ||
const clonedDate = clone(date) | ||
expect(clonedDate).toEqual(date) | ||
expect(clonedDate).not.toBe(date) | ||
}) | ||
|
||
it('should clone RegExp objects correctly', () => { | ||
const regex = /abc/gi | ||
const clonedRegex = clone(regex) | ||
expect(clonedRegex).toEqual(regex) | ||
expect(clonedRegex).not.toBe(regex) | ||
}) | ||
|
||
it('should handle circular references', () => { | ||
const obj: any = {} | ||
obj.self = obj | ||
const clonedObj = clone(obj) | ||
expect(clonedObj).not.toBe(obj) | ||
expect(clonedObj.self).toBe(clonedObj) | ||
}) | ||
|
||
it('should clone arrays correctly', () => { | ||
const arr = [1, 2, 3, [4, 5]] | ||
const clonedArr = clone(arr) | ||
expect(clonedArr).toEqual(arr) | ||
expect(clonedArr).not.toBe(arr) | ||
expect(clonedArr[3]).not.toBe(arr[3]) | ||
}) | ||
|
||
it('should clone objects with nested objects correctly', () => { | ||
const obj = { a: 1, b: { c: 2 } } | ||
const clonedObj = clone(obj) | ||
expect(clonedObj).toEqual(obj) | ||
expect(clonedObj).not.toBe(obj) | ||
expect(clonedObj.a).toBe(obj.a) | ||
expect(clonedObj.b).not.toBe(obj.b) | ||
}) | ||
|
||
it('should clone objects with prototype chain', () => { | ||
function Person(name) { | ||
this.name = name | ||
} | ||
|
||
Person.prototype.sayHello = function () { | ||
return 'Hello, ' + this.name | ||
} | ||
|
||
const person = new Person('John') | ||
const clonedPerson = clone(person) | ||
expect(clonedPerson).toEqual(person) | ||
expect(clonedPerson).not.toBe(person) | ||
expect(clonedPerson.sayHello()).toBe('Hello, John') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
//@ts-nocheck | ||
import cloneDeep from '../cloneDeep' | ||
|
||
describe('cloneDeep', () => { | ||
// 测试原始类型 | ||
test('should clone primitive types', () => { | ||
expect(cloneDeep(123)).toBe(123) | ||
expect(cloneDeep('abc')).toBe('abc') | ||
expect(cloneDeep(true)).toBe(true) | ||
expect(cloneDeep(null)).toBe(null) | ||
expect(cloneDeep(undefined)).toBe(undefined) | ||
|
||
const sym = Symbol('sym') | ||
expect(cloneDeep(sym)).toEqual(sym) | ||
}) | ||
|
||
// 测试日期 | ||
test('should clone Date', () => { | ||
const date = new Date() | ||
const clonedDate = cloneDeep(date) | ||
expect(clonedDate).toEqual(date) | ||
expect(clonedDate).not.toBe(date) | ||
}) | ||
|
||
// 测试正则表达式 | ||
test('should clone RegExp', () => { | ||
const regex = /abc/gi | ||
const clonedRegex = cloneDeep(regex) | ||
expect(clonedRegex).toEqual(regex) | ||
expect(clonedRegex).not.toBe(regex) | ||
}) | ||
|
||
// 测试ArrayBuffer | ||
test('should clone ArrayBuffer', () => { | ||
const buffer = new ArrayBuffer(8) | ||
const clonedBuffer = cloneDeep(buffer) | ||
expect(clonedBuffer).toEqual(buffer) | ||
expect(clonedBuffer).not.toBe(buffer) | ||
}) | ||
|
||
// 测试TypedArray | ||
test('should clone TypedArray', () => { | ||
const typedArray = new Uint8Array([1, 2, 3]) | ||
const clonedTypedArray = cloneDeep(typedArray) | ||
expect(clonedTypedArray).toEqual(typedArray) | ||
expect(clonedTypedArray).not.toBe(typedArray) | ||
}) | ||
|
||
// 测试DataView | ||
test('should clone DataView', () => { | ||
const buffer = new ArrayBuffer(8) | ||
const dataView = new DataView(buffer) | ||
const clonedDataView = cloneDeep(dataView) | ||
expect(clonedDataView).toEqual(dataView) | ||
expect(clonedDataView).not.toBe(dataView) | ||
}) | ||
|
||
// 测试Map | ||
test('should clone Map', () => { | ||
const map = new Map([ | ||
[1, 'a'], | ||
[2, 'b'], | ||
]) | ||
const clonedMap = cloneDeep(map) | ||
expect(clonedMap).toEqual(map) | ||
expect(clonedMap).not.toBe(map) | ||
}) | ||
|
||
// 测试Set | ||
test('should clone Set', () => { | ||
const set = new Set([1, 2, 3]) | ||
const clonedSet = cloneDeep(set) | ||
expect(clonedSet).toEqual(set) | ||
expect(clonedSet).not.toBe(set) | ||
}) | ||
|
||
// 测试数组 | ||
test('should clone Array', () => { | ||
const array = [1, 2, 3] | ||
const clonedArray = cloneDeep(array) | ||
expect(clonedArray).toEqual(array) | ||
expect(clonedArray).not.toBe(array) | ||
}) | ||
|
||
// 测试普通对象 | ||
test('should clone Object', () => { | ||
const obj = { a: 1, b: { c: 2 } } | ||
const clonedObj = cloneDeep(obj) | ||
expect(clonedObj).toEqual(obj) | ||
expect(clonedObj).not.toBe(obj) | ||
expect(clonedObj.b).not.toBe(obj.b) | ||
}) | ||
|
||
// 测试循环引用 | ||
test('should handle circular reference', () => { | ||
const obj: any = {} | ||
obj.a = obj | ||
const clonedObj = cloneDeep(obj) | ||
expect(clonedObj).toEqual(obj) | ||
expect(clonedObj).not.toBe(obj) | ||
expect(clonedObj.a).toBe(clonedObj) | ||
}) | ||
|
||
// 测试Symbol属性 | ||
test('should clone Symbol properties', () => { | ||
const sym = Symbol('sym') | ||
const obj = { [sym]: 'value' } | ||
const clonedObj = cloneDeep(obj) | ||
expect(clonedObj).toEqual(obj) | ||
expect(clonedObj).not.toBe(obj) | ||
expect(clonedObj[sym]).toBe(obj[sym]) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { afterEach } from 'node:test' | ||
import cloneJSON from '../cloneJSON' | ||
|
||
describe('cloneJSON', () => { | ||
afterEach(() => { | ||
jest.resetAllMocks() | ||
}) | ||
|
||
test('should clone a simple object', () => { | ||
const obj = { name: 'John', age: 30 } | ||
const clonedObj = cloneJSON(obj) | ||
expect(clonedObj).toEqual(obj) | ||
}) | ||
|
||
test('should handle circular references', () => { | ||
const consoleSpy = jest.spyOn(console, 'error').mockImplementation() | ||
|
||
const obj = { name: 'John', age: 30 } as any | ||
obj.self = obj | ||
|
||
try { | ||
cloneJSON(obj) | ||
} catch (error) {} | ||
|
||
expect(consoleSpy).toHaveBeenCalled() | ||
consoleSpy.mockRestore() | ||
}) | ||
|
||
test('should handle invalid JSON', () => { | ||
expect(cloneJSON(123)).toEqual(123) | ||
expect(cloneJSON('123')).toEqual('123') | ||
expect(cloneJSON(undefined)).toEqual({}) | ||
}) | ||
|
||
test('should handle empty object', () => { | ||
const obj = {} | ||
const clonedObj = cloneJSON(obj) | ||
expect(clonedObj).toEqual(obj) | ||
}) | ||
}) |
Oops, something went wrong.