Skip to content

Commit

Permalink
refactor: rewrite
Browse files Browse the repository at this point in the history
BREAKING CHANGE: The library has been rewritten
  • Loading branch information
BlackGlory committed Dec 27, 2023
1 parent a2d89b6 commit cba0cdc
Show file tree
Hide file tree
Showing 26 changed files with 334 additions and 612 deletions.
5 changes: 1 addition & 4 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ module.exports = {
, 'plugin:@typescript-eslint/recommended'
]
, rules: {
'no-useless-escape': 'off'
, '@typescript-eslint/no-explicit-any': 'off'
, '@typescript-eslint/ban-ts-comment': 'off'
, '@typescript-eslint/ban-types': 'off'
'@typescript-eslint/no-this-alias': 'off'
}
}
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,22 @@ yarn add brave-json
```

## API
### BraveJSON
```ts
interface IConverter<Raw, JSON extends JSONValue = JSONValue> {
toJSON(value: Raw): JSON
fromJSON(value: JSON): Raw
}

class BraveJSON {
static readonly DEFAULT_SYMBOL = '$brave-json'

constructor(
converter: IConverter<unknown, JSONValue>
, options?: { symbol?: string = BraveJSON.DEFAULT_SYMBOL }
)

stringify(value: unknown, space?: string | number): string
parse<T>(text: string): T
}
```
310 changes: 56 additions & 254 deletions __tests__/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,284 +1,86 @@
'use strict'

import getType from 'type-detect'
import { stringify, parse } from '@src/index.js'

describe('stringify & parse', () => {
test('Circular structure', () => {
const a = {}
// @ts-ignore
a.a = a
const result = parse(stringify(a))

expect(result.a).toEqual(result)
})

test('Date', () => {
const date = new Date()
const result = parse(stringify(date))

expect(getType(result)).toEqual('Date')
expect(result).toEqual(date)
})

test('String', () => {
const str = new String('str')
const result = parse(stringify(str))

expect(getType(result)).toEqual('String')
expect(result.toString()).toEqual('str')
})

test('Set', () => {
const set = new Set([1, 2, 3])
const result = parse(stringify(set))

expect(getType(result)).toEqual('Set')
expect(result).toEqual(set)
})

test('Map', () => {
const map = new Map([[1, 2]])
const result = parse(stringify(map))

expect(getType(result)).toEqual('Map')
expect(result).toEqual(map)
})

describe('function', () => {
test('function', () => {
function fn() {
return 'Hi Lisa'
import { describe, test, expect } from 'vitest'
import { BraveJSON, IConverter } from '@src/index.js'

describe('BraveJSON', () => {
const converter: IConverter<Buffer, [type: string, value: string]> = {
toJSON(raw) {
if (raw instanceof Buffer) {
return ['buffer', raw.toString()]
}
const result = parse(stringify(fn))

expect(getType(result)).toEqual('function')
expect(result()).toEqual('Hi Lisa')
})

test('function with options', () => {
function fn() {
return `Hi ${ name }`
throw new Error('Unknown raw value')
}
, fromJSON([type, value]) {
switch (type) {
case 'buffer': return Buffer.from(value)
default: throw new Error('Unknown json value')
}
}
}

const result = parse(stringify(fn), undefined, {
FunctionContext: {
name: 'Lisa'
}
})
test('stringify', () => {
const brave = new BraveJSON(converter)
const raw = Buffer.from('foo')

expect(getType(result)).toEqual('function')
expect(result()).toEqual('Hi Lisa')
})
})

describe('RegExp', () => {
test('RegExp literal', () => {
const re = /\w/g
const result = parse(stringify(re))

expect(getType(result)).toEqual('RegExp')
expect(result).toEqual(re)
})
const result = brave.stringify(raw)

test('RegExp', () => {
const re = new RegExp('\w', 'g')
const result = parse(stringify(re))

expect(getType(result)).toEqual('RegExp')
expect(result).toEqual(re)
})
expect(result).toStrictEqual(
JSON.stringify([BraveJSON.DEFAULT_SYMBOL, ['buffer', 'foo']])
)
})

describe('number', () => {
test('number', () => {
const num = 10
const result = parse(stringify(num))
test('parse', () => {
const brave = new BraveJSON(converter)
const json = JSON.stringify([BraveJSON.DEFAULT_SYMBOL, ['buffer', 'foo']])

expect(getType(result)).toEqual('number')
expect(result).toEqual(num)
})

test('NaN', () => {
expect(parse(stringify(NaN))).toEqual(NaN)
})
const result = brave.parse<Buffer>(json)

test('Infinity', () => {
expect(parse(stringify(Infinity))).toEqual(Infinity)
})
expect(result).toStrictEqual(Buffer.from('foo'))
})

describe('Number', () => {
test('Number', () => {
const num = new Number(10)
const result = parse(stringify(num))
describe('raw in object', () => {
test('stringify', () => {
const brave = new BraveJSON(converter)
const raw = { key: Buffer.from('foo') }

expect(getType(result)).toEqual('Number')
expect(result).toEqual(num)
})
const result = brave.stringify(raw)

test('Number(NaN)', () => {
const nan = new Number(NaN)
expect(parse(stringify(nan))).toEqual(nan)
expect(result).toStrictEqual(
JSON.stringify({ key: [BraveJSON.DEFAULT_SYMBOL, ['buffer', 'foo']] })
)
})

test('Number(Infinity)', () => {
const infinity = new Number(Infinity)
expect(parse(stringify(infinity))).toEqual(infinity)
})
})

describe('TypedArray', () => {
test('Int8Array', () => {
const arr = new Int8Array([1, 2, 3])
const result = parse(stringify(arr))

expect(getType(result)).toEqual('Int8Array')
expect(result).toEqual(arr)
})

test('Uint8Array', () => {
const arr = new Uint8Array([1, 2, 3])
const result = parse(stringify(arr))

expect(getType(result)).toEqual('Uint8Array')
expect(result).toEqual(arr)
})

test('Uint8ClampedArray', () => {
const arr = new Uint8ClampedArray([1, 2, 3])
const result = parse(stringify(arr))

expect(getType(result)).toEqual('Uint8ClampedArray')
expect(result).toEqual(arr)
})

test('Int16Array', () => {
const arr = new Int16Array([1, 2, 3])
const result = parse(stringify(arr))

expect(getType(result)).toEqual('Int16Array')
expect(result).toEqual(arr)
})

test('Uint16Array', () => {
const arr = new Uint16Array([1, 2, 3])
const result = parse(stringify(arr))

expect(getType(result)).toEqual('Uint16Array')
expect(result).toEqual(arr)
})

test('Int32Array', () => {
const arr = new Int32Array([1, 2, 3])
const result = parse(stringify(arr))

expect(getType(result)).toEqual('Int32Array')
expect(result).toEqual(arr)
})

test('Uint32Array', () => {
const arr = new Uint32Array([1, 2, 3])
const result = parse(stringify(arr))

expect(getType(result)).toEqual('Uint32Array')
expect(result).toEqual(arr)
})

test('Float32Array', () => {
const arr = new Float32Array([1, 2, 3])
const result = parse(stringify(arr))

expect(getType(result)).toEqual('Float32Array')
expect(result).toEqual(arr)
})
test('parse', () => {
const brave = new BraveJSON(converter)
const json = JSON.stringify({
key: [BraveJSON.DEFAULT_SYMBOL, ['buffer', 'foo']]
})

test('Float64Array', () => {
const arr = new Float64Array([1, 2, 3])
const result = parse(stringify(arr))
const result = brave.parse<Buffer>(json)

expect(getType(result)).toEqual('Float64Array')
expect(result).toEqual(arr)
expect(result).toStrictEqual({ key: Buffer.from('foo') })
})
})

describe('Error', () => {
test('Error', () => {
const err = new Error('err')
const result = parse(stringify(err))

expect(getType(result)).toEqual('Error')
expect(result).toEqual(err)
})

test('EvalError', () => {
const err = new EvalError('err')
const result = parse(stringify(err))

expect(getType(result)).toEqual('Error')
expect(result instanceof EvalError).toBeTruthy()
expect(result).toEqual(err)
})
describe('raw in array', () => {
test('stringify', () => {
const brave = new BraveJSON(converter)
const raw = [Buffer.from('foo')]

test('RangeError', () => {
const err = new RangeError('err')
const result = parse(stringify(err))
const result = brave.stringify(raw)

expect(getType(result)).toEqual('Error')
expect(result instanceof RangeError).toBeTruthy()
expect(result).toEqual(err)
expect(result).toStrictEqual(
JSON.stringify([[BraveJSON.DEFAULT_SYMBOL, ['buffer', 'foo']]])
)
})

test('ReferenceError', () => {
const err = new ReferenceError('err')
const result = parse(stringify(err))

expect(getType(result)).toEqual('Error')
expect(result instanceof ReferenceError).toBeTruthy()
expect(result).toEqual(err)
})

test('SyntaxError', () => {
const err = new SyntaxError('err')
const result = parse(stringify(err))

expect(getType(result)).toEqual('Error')
expect(result instanceof SyntaxError).toBeTruthy()
expect(result).toEqual(err)
})

test('TypeError', () => {
const err = new TypeError('err')
const result = parse(stringify(err))

expect(getType(result)).toEqual('Error')
expect(result instanceof TypeError).toBeTruthy()
expect(result).toEqual(err)
})

test('URIError', () => {
const err = new URIError('err')
const result = parse(stringify(err))

expect(getType(result)).toEqual('Error')
expect(result instanceof URIError).toBeTruthy()
expect(result).toEqual(err)
})

test('CustomError', () => {
class CustomError extends Error {
constructor(...args: string[]) {
super(...args)
this.name = 'CustomError'
}
}
test('parse', () => {
const brave = new BraveJSON(converter)
const json = JSON.stringify([[BraveJSON.DEFAULT_SYMBOL, ['buffer', 'foo']]])

const err = new CustomError('err')
const result = parse(stringify(err))
const result = brave.parse<Buffer>(json)

expect(getType(result)).toEqual('Error')
expect(result.name).toEqual('CustomError')
expect(result).toEqual(err)
expect(result).toStrictEqual([Buffer.from('foo')])
})
})
})
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@
"vitest": "^0.34.1"
},
"dependencies": {
"circular-json-es6": "^2.0.2",
"dynamic-scope": "^0.1.2",
"type-detect": "^4.0.8"
"@blackglory/prelude": "^0.3.4"
}
}
5 changes: 0 additions & 5 deletions src/circular-json-es6.d.ts

This file was deleted.

Loading

0 comments on commit cba0cdc

Please sign in to comment.