UNPKG

ipld-schema-validator

Version:
599 lines (563 loc) 14.1 kB
/* eslint-env mocha */ import { create } from 'ipld-schema-validator' import chai from 'chai' const { assert } = chai describe('Errors', () => { it('invalid schema definition', () => { // @ts-ignore assert.throws(() => create({}, 'blip'), /Invalid schema definition/) }) it('no root', () => { // @ts-ignore assert.throws(() => create({ types: {} }), /A root is required/) // @ts-ignore assert.throws(() => create({ types: {} }, ''), /A root is required/) // @ts-ignore assert.throws(() => create({ types: {} }, null), /A root is required/) // @ts-ignore assert.throws(() => create({ types: {} }, 100), /A root is required/) }) it('bad type kind', () => { assert.throws(() => create({ types: { $map: { // @ts-ignore blip: { keyType: 'String', valueType: 'Int' } } } }, '$map'), /type kind: "blip"/) }) it('multiple kinds', () => { assert.throws(() => create({ types: { boo: { bool: {}, int: {} } } }, 'boo'), /Malformed type definition: expected single kind key \("boo"\)/) }) it('no kind', () => { assert.throws(() => create({ types: { // @ts-ignore boo: { } } }, 'boo'), /Malformed type definition: empty \("boo"\)/) }) it('recursive map kind', () => { assert.throws(() => create({ types: { $map: { map: { keyType: 'String', valueType: '$map' } } } }, '$map'), /Recursive typedef in type "\$map"/) }) it('recursive list kind', () => { assert.throws(() => create({ types: { $list: { list: { valueType: '$list' } } } }, '$list'), /Recursive typedef in type "\$list"/) }) it('invalid map keyType', () => { assert.throws(() => create({ types: { $map: { map: { keyType: 'Bytes', valueType: 'Int' } } } }, '$map'), /Invalid keyType for Map "\$map", expected String, found "Bytes"/) }) it('invalid root', () => { assert.throws(() => create({ types: { $list: { list: { valueType: 'String' } } } }, 'blip'), /A type must match an existing type definition \("blip"\)/) }) describe('invalid typedef', () => { it('array', () => { assert.throws(() => create({ types: { // @ts-ignore $list: [] } }, '$list'), /Malformed type definition: not an object: \("\$list"\)/) }) it('null', () => { assert.throws(() => create({ types: { // @ts-ignore $list: null } }, '$list'), /Malformed type definition: not an object: \("\$list"\)/) }) it('other', () => { assert.throws(() => create({ types: { // @ts-ignore $list: true } }, '$list'), /Malformed type definition: not an object: \("\$list"\)/) }) }) it('invalid reference', () => { assert.throws(() => create({ types: { $list: { list: { valueType: 'boop' } } } }, '$list'), /A type must match an existing type definition \("boop"\)/) }) it('bad valueType', () => { assert.throws(() => create({ types: { AMap: { map: { keyType: 'String', // @ts-ignore valueType: [], representation: { map: {} } } } } }, 'AMap'), /Bad type for "valueType" in "AMap"/) assert.throws(() => create({ types: { AList: { list: { // @ts-ignore valueType: true } } } }, 'AList'), /Bad type for "valueType" in "AList"/) }) it('bad map representation', () => { assert.throws(() => create({ types: { AMap: { map: { keyType: 'String', valueType: 'String', // @ts-ignore representation: { blip: {} } } } } }, 'AMap'), /Unsupported map representation "blip"/) }) it('bad struct representation', () => { assert.throws(() => create({ types: { SimpleStruct: { struct: { fields: { foo: { type: 'Int', optional: true }, bar: { type: 'Bool' }, baz: { type: 'String', optional: true } }, // @ts-ignore representation: { blip: {} } } } } }, 'SimpleStruct'), /Unsupported struct representation for "SimpleStruct": "blip"/) }) it('non-map struct with optionals', () => { assert.throws(() => create({ types: { SimpleStruct: { struct: { fields: { foo: { type: 'Int', optional: true }, bar: { type: 'Bool' }, baz: { type: 'String', optional: true } }, representation: { tuple: {} } } } } }, 'SimpleStruct'), /Struct "SimpleStruct" includes "optional" fields for non-map struct/) }) it('bad union', () => { assert.throws(() => create({ types: { UnionUnknown: { // @ts-ignore union: {} } } }, 'UnionUnknown'), /Bad union definition for "UnionUnknown"/) }) it('bad envelope union', () => { assert.throws(() => create({ types: { UnionInline: { union: { representation: { // @ts-ignore inline: { discriminantKey: 'tag' } } } }, Foo: { struct: { fields: { froz: { type: 'Bool' } }, representation: { map: {} } } }, Bar: { struct: { fields: { bral: { type: 'String' } }, representation: { map: {} } } } } }, 'UnionInline'), /Expected "discriminantTable" for inline union "UnionInline"/) assert.throws(() => create({ types: { UnionInline: { union: { representation: { // @ts-ignore inline: { discriminantTable: { foo: 'Foo', bar: 'Bar' } } } } }, Foo: { struct: { fields: { froz: { type: 'Bool' } }, representation: { map: {} } } }, Bar: { struct: { fields: { bral: { type: 'String' } }, representation: { map: {} } } } } }, 'UnionInline'), /Expected "discriminantKey" for inline union "UnionInline"/) }) it('bad envelope union', () => { assert.throws(() => create({ types: { Bar: { bool: {} }, Baz: { string: {} }, Foo: { int: {} }, UnionEnvelope: { union: { representation: { // @ts-ignore envelope: { discriminantKey: 'bim', contentKey: 'bam' } } } } } }, 'UnionEnvelope'), /Expected "discriminantTable" for envelope union "UnionEnvelope"/) assert.throws(() => create({ types: { Bar: { bool: {} }, Baz: { string: {} }, Foo: { int: {} }, UnionEnvelope: { union: { representation: { // @ts-ignore envelope: { contentKey: 'bim', discriminantTable: { foo: 'Foo', bar: 'Bar', baz: 'Baz' } } } } } } }, 'UnionEnvelope'), /Expected "discriminantKey" for envelope union "UnionEnvelope"/) assert.throws(() => create({ types: { Bar: { bool: {} }, Baz: { string: {} }, Foo: { int: {} }, UnionEnvelope: { union: { representation: { // @ts-ignore envelope: { discriminantKey: 'bim', discriminantTable: { foo: 'Foo', bar: 'Bar', baz: 'Baz' } } } } } } }, 'UnionEnvelope'), /Expected "contentKey" for envelope union "UnionEnvelope"/) }) it('bad union type name', () => { assert.throws(() => create({ types: { Bar: { bool: {} }, Baz: { string: {} }, Foo: { int: {} }, UnionKinded: { union: { representation: { kinded: { map: 'Foo', list: 'Bar', // @ts-ignore int: {} } } } } } }, 'UnionKinded'), /Kinded union "UnionKinded refers to non-string type name: {}/) // @ts-ignore assert.throws(() => create({ types: { UnionKeyed: { union: { representation: { // @ts-ignore keyed: { bar: 'Bool', foo: 'Int', // @ts-ignore baz: ['nope'] } } } } } }, 'UnionKeyed'), /Keyed union "UnionKeyed refers to non-string type name: \["nope"\]/) assert.throws(() => create({ types: { UnionInline: { union: { representation: { inline: { discriminantKey: 'tag', // @ts-ignore discriminantTable: { foo: 'Foo', // @ts-ignore bar: 100 } } } } }, Foo: { struct: { fields: { froz: { type: 'Bool' } }, representation: { map: {} } } }, Bar: { struct: { fields: { bral: { type: 'String' } }, representation: { map: {} } } } } }, 'UnionInline'), /Inline union "UnionInline refers to non-string type name: 100/) assert.throws(() => create({ types: { Bar: { bool: {} }, Baz: { string: {} }, Foo: { int: {} }, UnionEnvelope: { union: { representation: { envelope: { discriminantKey: 'bim', contentKey: 'bam', discriminantTable: { foo: 'Foo', // @ts-ignore bar: true, baz: 'Baz' } } } } } } }, 'UnionEnvelope'), /Envelope union "UnionEnvelope refers to non-string type name: true/) }) it('bad bytesprefix byte', () => { assert.throws(() => create({ types: { Bls12_381Signature: { bytes: {} }, Secp256k1Signature: { bytes: {} }, Signature: { union: { members: [ 'Secp256k1Signature', 'Bls12_381Signature' ], representation: { bytesprefix: { Secp256k1Signature: '0', Bls12_381Signature: '-1' } } } } } }, 'Signature'), /Invalid bytesprefix byte for "Signature": "-1"/) }) it('bad union type', () => { assert.throws(() => create({ types: { UnionKeyed: { union: { representation: { // @ts-ignore blip: { } } } } } }, 'UnionKeyed'), /Unsupported union type for "UnionKeyed": "blip"/) }) it('bad enum descriptor', () => { assert.throws(() => create({ types: { SimpleEnum: { // @ts-ignore enum: {} } } }, 'SimpleEnum'), /Enum needs a "members" list/) }) it('bad string enum rename values', () => { assert.throws(() => create({ types: { SimpleEnum: { enum: { members: [ 'Foo', 'Bar', 'Baz' ], representation: { string: { Foo: 'str', // @ts-ignore Bar: 0 } } } } } }, 'SimpleEnum'), /Enum members must be strings/) }) it('bad int enum rename values', () => { assert.throws(() => create({ types: { SimpleEnum: { enum: { members: [ 'Foo', 'Bar', 'Baz' ], representation: { int: { // @ts-ignore Foo: 'str', Bar: 0 } } } } } }, 'SimpleEnum'), /Enum members must be ints/) }) it('no enum representation', () => { assert.throws(() => create({ types: { SimpleEnum: { // @ts-ignore enum: { members: [ 'Foo', 'Bar', 'Baz' ] } } } }, 'SimpleEnum'), /Enum doesn't have a valid representation/) }) it('bad enum representation type', () => { assert.throws(() => create({ types: { SimpleEnum: { enum: { members: [ 'Foo', 'Bar', 'Baz' ], representation: { // @ts-ignore nope: {} } } } } }, 'SimpleEnum'), /Enum doesn't have a valid representation/) }) })