Skip to content

Instantly share code, notes, and snippets.

@molekilla
Last active June 9, 2022 13:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save molekilla/3ec64736c1cf690029c6985380b13e25 to your computer and use it in GitHub Desktop.
Save molekilla/3ec64736c1cf690029c6985380b13e25 to your computer and use it in GitHub Desktop.
beeson schema builder
import { DnaManager, BeeSon, Type } from '../../src'
import { encodeFeedReference, encodeManifestReference } from '@ethersphere/swarm-cid'
import { SwarmFeedCid, SwarmManifestCid } from '../../src/marshalling/address-serializer'
import { randomByteArray } from './utils'
class SchemaBuilder {
constructor(private node: BeeSon<unknown> = new BeeSon<unknown>({ json: {} })) {}
makeComplexNode(node: object): SchemaBuilder {
this.node.json = node
return this
}
setInt32({ value, key = null }: { key?: string; value: number }) {
if (key) {
this.node.json[key] = value
expect(this.node.dnaManager.type).toBe(Type.object)
} else {
this.node.json = value
expect(this.node.dnaManager.type).toBe(Type.int32)
}
}
setFloat64({ value, key = null }: { key?: string; value: number }) {
if (key) {
this.node.json[key] = value
expect(this.node.dnaManager.type).toBe(Type.object)
} else {
this.node.json = value
expect(this.node.dnaManager.type).toBe(Type.float64)
}
}
setString({ value, key = null }: { key?: string; value: string }) {
if (key) {
this.node.json[key] = value
expect(this.node.dnaManager.type).toBe(Type.object)
} else {
this.node.json = value
expect(this.node.dnaManager.type).toBe(Type.string)
}
}
get dna() {
return this.node.dnaManager
}
json<T>(): T {
return this.node.json as T
}
get beeson() {
return this.node
}
}
describe('beeson', () => {
// Example
it('should build simple types', () => {
const json = 123
const builder = new SchemaBuilder()
builder.setInt32({ value: 123 })
expect(builder.dna.type).toBe(Type.int32)
expect(builder.json<number>()).toBe(json)
// serialisation correctness
const beesonAgain = BeeSon.deserialize(builder.beeson.serialize())
expect(beesonAgain.json).toBe(json)
// modificiation correctness
builder.setInt32({ value: 345 })
builder.setInt32({ value: builder.json<number>() * -1 })
})
it('should build complex types', () => {
const json = 123
const builder = new SchemaBuilder()
builder.makeComplexNode({
name: 'complex',
source: 'dapp.registry.fds',
blobRef: '....',
timestamp: new Date().getTime(),
})
expect(builder.dna.type).toBe(Type.object)
expect(builder.json<object>()).toBe(json)
// serialisation correctness
const beesonAgain = BeeSon.deserialize(builder.beeson.serialize())
expect(beesonAgain.json).toBe(json)
// modificiation correctness
builder.setInt32({ key: 'timestamp', value: new Date().getTime() })
builder.setString({
key: 'blobRef',
value: 'bah5qcgzaymd4255atbv6kkelx75ezqaq64n7vhxgbkw64bjfjedougktli6q',
})
})
it('should work with integer type', () => {
const json = 123
const beeson = new BeeSon<number>({ json })
expect(beeson.dnaManager.type).toBe(Type.int32)
expect(beeson.json).toBe(json)
// serialisation correctness
const beesonAgain = BeeSon.deserialize(beeson.serialize())
expect(beesonAgain.json).toBe(json)
// modificiation correctness
beeson.json = 345
beeson.json = beeson.json * -1
expect(beeson.json).toBe(-345)
expect(() => (beeson.json = 'john coke' as unknown as number)).toThrowError()
expect(() => (beeson.json = 12.45)).toThrowError()
})
it('should work with floating type', () => {
const json = 123.123
const beeson = new BeeSon<number>({ json })
expect(beeson.dnaManager.type).toBe(Type.float64)
expect(beeson.json).toBe(json)
// serialisation correctness
const beesonAgain = BeeSon.deserialize(beeson.serialize())
expect(beesonAgain.json).toBe(json)
// modificiation correctness
// test whether it accepts integer
beeson.json = 456
expect(() => (beeson.json = 'john coke' as unknown as number)).toThrowError()
})
it('should work with string type', () => {
const json = 'john coke'
const beeson = new BeeSon<string>({ json })
expect(beeson.json).toBe(json)
expect(beeson.dnaManager.type).toBe(Type.string)
// serialisation correctness
const beesonAgain = BeeSon.deserialize(beeson.serialize())
expect(beesonAgain.json).toBe(json)
// modificiation correctness
beeson.json = 'jeez'
expect(() => (beeson.json = 42 as unknown as string)).toThrowError()
})
it('should work with boolean type', () => {
const json = false
const beeson = new BeeSon<boolean>({ json })
expect(beeson.dnaManager.type).toBe(Type.boolean)
expect(beeson.json).toBe(json)
// serialisation correctness
const beesonAgain = BeeSon.deserialize(beeson.serialize())
expect(beesonAgain.json).toBe(json)
// modificiation correctness
beeson.json = true
expect(() => (beeson.json = 0 as unknown as boolean)).toThrowError()
expect(() => (beeson.json = 'john coke' as unknown as boolean)).toThrowError()
expect(() => (beeson.json = null as unknown as boolean)).toThrowError()
})
it('should work with BigInt type', () => {
const json = 1n
const beeson = new BeeSon<BigInt>({ json })
expect(beeson.dnaManager.type).toBe(Type.int64)
expect(beeson.json).toBe(json)
// serialisation correctness
const beesonAgain = BeeSon.deserialize(beeson.serialize())
expect(beesonAgain.json).toBe(json)
// modificiation correctness
beeson.json = -2n
expect(() => (beeson.json = 0 as unknown as BigInt)).toThrowError()
expect(() => (beeson.json = 'john coke' as unknown as BigInt)).toThrowError()
expect(() => (beeson.json = null as unknown as BigInt)).toThrowError()
})
it('should work with manifest CID', () => {
const json = 'bah5acgzadxcwdayt52nxhygvpou6e63p2vsl23m4kc63f2hyk2avg4joafoq'
const beeson = new BeeSon<SwarmManifestCid>({ json })
expect(beeson.dnaManager.type).toBe(Type.swarmCac)
expect(beeson.json).toBe(json)
// serialisation correctness
const beesonAgain = BeeSon.deserialize(beeson.serialize())
expect(beesonAgain.json.toString()).toBe(json) // // by default CID string are provided as CID objects
// modificiation correctness
// test whether it works with CID object as well
beeson.json = encodeManifestReference('1dc5618313ee9b73e0d57ba9e27b6fd564bd6d9c50bdb2e8f8568153712e015d')
expect(
() => (beeson.json = 'bah5qcgzaymd4255atbv6kkelx75ezqaq64n7vhxgbkw64bjfjedougktli6q'),
).toThrowError()
expect(() => (beeson.json = 'john coke')).toThrowError()
})
it('should work with feed CID', () => {
const json = 'bah5qcgzaymd4255atbv6kkelx75ezqaq64n7vhxgbkw64bjfjedougktli6q'
const beeson = new BeeSon<SwarmFeedCid>({ json })
expect(beeson.dnaManager.type).toBe(Type.swarmSoc)
expect(beeson.json).toBe(json)
// serialisation correctness
const serialized = beeson.serialize()
const beesonAgain = BeeSon.deserialize(serialized)
expect(beesonAgain.json.toString()).toBe(json) // by default CID string are provided as CID objects
// obfuscation key change
beesonAgain.dnaManager.obfuscationKey = randomByteArray(32)
const serialized2 = beesonAgain.serialize()
const beesonAgain2 = BeeSon.deserialize(serialized2)
expect(beesonAgain2.json).toStrictEqual(beesonAgain.json)
expect(serialized2).not.toStrictEqual(serialized)
// modificiation correctness
// test whether it works with CID object as well
beeson.json = encodeFeedReference('1dc5618313ee9b73e0d57ba9e27b6fd564bd6d9c50bdb2e8f8568153712e015d')
expect(
() => (beeson.json = 'bah5acgzadxcwdayt52nxhygvpou6e63p2vsl23m4kc63f2hyk2avg4joafoq'),
).toThrowError()
expect(() => (beeson.json = 'john coke')).toThrowError()
})
it('should work with typed arrays', () => {
const json = [0, 1, 2, 3, 5, 6]
const beeson = new BeeSon({ json })
expect(beeson.dnaManager.type).toBe(Type.array)
expect(beeson.json).toStrictEqual(json)
// serialisation correctness
const bytes = beeson.dnaManager.dna()
const beeSonManager = DnaManager.spawn(bytes).dnaManager
expect(bytes).toStrictEqual(beeSonManager.dna())
const serialised = beeson.serialize()
const beesonAgain = BeeSon.deserialize(serialised)
expect(beesonAgain.json).toStrictEqual(json)
// obfuscation key change
beesonAgain.dnaManager.obfuscationKey = randomByteArray(32)
const serialised2 = beesonAgain.serialize()
const beesonAgain2 = BeeSon.deserialize(serialised2)
expect(beesonAgain2.json).toStrictEqual(beesonAgain.json)
expect(serialised2).not.toStrictEqual(serialised)
// modificiation correctness
beeson.json = [3, 4, 5, 0, 0, 0]
expect(() => (beeson.json = { name: 'john coke' } as unknown as number[])).toThrowError(
/^Wrong value for type array. Got value has type: object./,
)
expect(() => (beeson.json = 'john coke' as unknown as number[])).toThrowError(
/^Wrong value for type array. Got value has type: string. Value: john coke/,
)
expect(() => (beeson.json = [0, 1, 2])).toThrowError(
/^Given JSON array has 3 length, when the dna defines 6 length/,
)
expect(() => (beeson.json = [3, 4, 5, 'john', 'coke', 0] as unknown as number[])).toThrowError(
'BeeSon Array assertion problem at index 3: Wrong value for type number (integer). Got value has type: string. Value: john',
)
})
it('should work with 1 level object', () => {
let json = { name: 'john coke', age: 48, id: 'ID2' }
const beeson = new BeeSon({ json })
expect(beeson.dnaManager.type).toStrictEqual(Type.object)
expect(beeson.json).toStrictEqual(json)
// serialisation correctness
const bytes = beeson.dnaManager.dna()
const beeSonManager = DnaManager.spawn(bytes).dnaManager
expect(bytes).toStrictEqual(beeSonManager.dna())
const serialised = beeson.serialize()
const beesonAgain = BeeSon.deserialize(serialised)
expect(beesonAgain.json).toStrictEqual(json)
// obfuscation key change
beesonAgain.dnaManager.obfuscationKey = randomByteArray(32)
const serialised2 = beesonAgain.serialize()
const beesonAgain2 = BeeSon.deserialize(serialised2)
expect(beesonAgain2.json).toStrictEqual(beesonAgain.json)
expect(serialised2).not.toStrictEqual(serialised)
// modificiation correctness
json = { name: 'john coke', age: 49, id: 'ID2' }
beeson.json = json
expect(beeson.json).toStrictEqual(json)
expect(
() =>
(beeson.json = {
name: 123 as unknown as string,
age: 50,
id: 'ID3',
}),
).toThrowError(
/BeeSon Object assertion problem at index name: Wrong value for type string. Got value has type: number. Value: 123/,
)
})
it('should work with polimorfic arrays', () => {
let json = [0, '1', false, { name: 'john coke' }, 5]
const beeson = new BeeSon({ json })
expect(beeson.dnaManager.type).toStrictEqual(Type.array)
expect(beeson.json).toStrictEqual(json)
// serialisation correctness
const bytes = beeson.dnaManager.dna()
const beeSonManager = DnaManager.spawn(bytes).dnaManager
expect(bytes).toStrictEqual(beeSonManager.dna())
const serialised = beeson.serialize()
const beesonAgain = BeeSon.deserialize(serialised)
expect(beesonAgain.json).toStrictEqual(json)
// obfuscation key change
beesonAgain.dnaManager.obfuscationKey = randomByteArray(32)
const serialised2 = beesonAgain.serialize()
const beesonAgain2 = BeeSon.deserialize(serialised2)
expect(beesonAgain2.json).toStrictEqual(beesonAgain.json)
expect(serialised2).not.toStrictEqual(serialised)
// modificiation correctness
json = [1, '0', true, { name: 'gipsz jakab' }, -6]
beeson.json = json
expect(beeson.json).toStrictEqual(json)
expect(() => (beeson.json = { name: 'john coke' } as unknown as number[])).toThrowError(
/^Wrong value for type array. Got value has type: object./,
)
expect(() => (beeson.json = 'john coke' as unknown as number[])).toThrowError(
/^Wrong value for type array. Got value has type: string. Value: john coke/,
)
expect(() => (beeson.json = [0, 1, 2])).toThrowError(
/^Given JSON array has 3 length, when the dna defines 5 length/,
)
expect(() => (beeson.json = [0, 1, 2])).toThrowError(
/^Given JSON array has 3 length, when the dna defines 5 length/,
)
})
it('should work with complex object', () => {
let json = { name: 'john coke', age: 48, id: 'ID2', buddies: [{ name: 'jesus', age: 33, id: 'ID1' }] }
const beeson = new BeeSon({ json })
expect(beeson.dnaManager.type).toStrictEqual(Type.object)
expect(beeson.json).toStrictEqual(json)
// serialisation correctness
const bytes = beeson.dnaManager.dna()
const beeSonManager = DnaManager.spawn(bytes).dnaManager
expect(bytes).toStrictEqual(beeSonManager.dna())
const serialised = beeson.serialize()
const beesonAgain = BeeSon.deserialize(serialised)
expect(beesonAgain.json).toStrictEqual(json)
// obfuscation key change
beesonAgain.dnaManager.obfuscationKey = randomByteArray(32)
const serialised2 = beesonAgain.serialize()
const beesonAgain2 = BeeSon.deserialize(serialised2)
expect(beesonAgain2.json).toStrictEqual(beesonAgain.json)
expect(serialised2).not.toStrictEqual(serialised)
// modificiation correctness
json = { name: 'john coke', age: 49, id: 'ID2', buddies: [{ name: 'buddha', age: 0, id: 'ID-NOPE' }] }
beeson.json = json
expect(beeson.json).toStrictEqual(json)
expect(
() =>
(beeson.json = {
name: 123 as unknown as string,
age: 50,
id: 'ID3',
buddies: [{ name: 'buddha', age: 0, id: 'ID-NOPE' }],
}),
).toThrowError(
/BeeSon Object assertion problem at index name: Wrong value for type string. Got value has type: number. Value: 123/,
)
expect(
() =>
(beeson.json = {
name: 'john coke',
age: 50,
id: 'ID3',
buddies: [],
}),
).toThrowError(
'BeeSon Object assertion problem at index buddies: Given JSON array has 0 length, when the dna defines 1 length',
)
})
})
@molekilla
Copy link
Author

schema builder

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment