2024-06-10 22:42:30 -05:00
|
|
|
|
import {expect, test} from 'vitest';
|
|
|
|
|
|
|
|
|
|
import Schema from './schema.js';
|
|
|
|
|
|
2024-07-26 19:28:28 -05:00
|
|
|
|
const compare = (specification, value) => {
|
|
|
|
|
expect(new Schema(specification).defaultValue())
|
|
|
|
|
.to.deep.equal(value);
|
|
|
|
|
};
|
|
|
|
|
|
2024-06-12 01:38:05 -05:00
|
|
|
|
test('defaults values', () => {
|
|
|
|
|
[
|
|
|
|
|
'uint8',
|
|
|
|
|
'int8',
|
|
|
|
|
'uint16',
|
|
|
|
|
'int16',
|
|
|
|
|
'uint32',
|
|
|
|
|
'int32',
|
|
|
|
|
'float32',
|
|
|
|
|
'float64',
|
|
|
|
|
].forEach((type) => {
|
2024-06-24 04:19:54 -05:00
|
|
|
|
compare({type}, 0);
|
2024-06-12 01:38:05 -05:00
|
|
|
|
});
|
2024-07-23 10:10:32 -05:00
|
|
|
|
[
|
|
|
|
|
'uint64',
|
|
|
|
|
'int64',
|
|
|
|
|
].forEach((type) => {
|
|
|
|
|
compare({type}, 0n);
|
|
|
|
|
});
|
2024-06-24 04:19:54 -05:00
|
|
|
|
compare({type: 'string'}, '');
|
|
|
|
|
compare({type: 'array', subtype: {type: 'string'}}, []);
|
|
|
|
|
compare(
|
|
|
|
|
{
|
|
|
|
|
type: 'object',
|
|
|
|
|
properties: {
|
|
|
|
|
foo: {type: 'uint8'},
|
|
|
|
|
bar: {type: 'string'},
|
|
|
|
|
baz: {type: 'object', properties: {blah: {type: 'array', subtype: {type: 'string'}}}},
|
|
|
|
|
},
|
2024-06-12 01:38:05 -05:00
|
|
|
|
},
|
2024-06-24 04:19:54 -05:00
|
|
|
|
{foo: 0, bar: '', baz: {blah: []}},
|
|
|
|
|
);
|
|
|
|
|
compare(
|
|
|
|
|
{
|
|
|
|
|
type: 'map',
|
|
|
|
|
value: {
|
|
|
|
|
type: 'object',
|
|
|
|
|
properties: {
|
|
|
|
|
foo: {type: 'uint8'},
|
|
|
|
|
bar: {type: 'string'},
|
|
|
|
|
baz: {type: 'object', properties: {blah: {type: 'array', subtype: {type: 'string'}}}},
|
|
|
|
|
},
|
|
|
|
|
},
|
2024-06-12 01:38:05 -05:00
|
|
|
|
},
|
2024-06-24 04:19:54 -05:00
|
|
|
|
{},
|
|
|
|
|
);
|
2024-06-12 01:38:05 -05:00
|
|
|
|
});
|
2024-06-10 22:42:30 -05:00
|
|
|
|
|
2024-07-26 19:28:28 -05:00
|
|
|
|
test.todo('defaults nested values', () => {
|
|
|
|
|
compare(
|
|
|
|
|
{
|
|
|
|
|
type: 'array',
|
|
|
|
|
subtype: {
|
|
|
|
|
type: 'object',
|
|
|
|
|
properties: {
|
|
|
|
|
foo: {defaultValue: 'bar', type: 'string'},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
[{}],
|
|
|
|
|
[{foo: 'bar'}],
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
2024-06-12 01:38:05 -05:00
|
|
|
|
test('validates a schema', () => {
|
|
|
|
|
[
|
|
|
|
|
'uint8',
|
|
|
|
|
'int8',
|
|
|
|
|
'uint16',
|
|
|
|
|
'int16',
|
|
|
|
|
'uint32',
|
|
|
|
|
'int32',
|
|
|
|
|
'uint64',
|
|
|
|
|
'int64',
|
|
|
|
|
'float32',
|
|
|
|
|
'float64',
|
|
|
|
|
'string',
|
|
|
|
|
].forEach((type) => {
|
|
|
|
|
expect(() => {
|
|
|
|
|
new Schema({type});
|
|
|
|
|
new Schema({type: 'array', subtype: {type}});
|
|
|
|
|
new Schema({type: 'object', properties: {foo: {type}}});
|
2024-06-24 04:19:54 -05:00
|
|
|
|
new Schema({type: 'map', value: {type}});
|
2024-06-12 01:38:05 -05:00
|
|
|
|
})
|
|
|
|
|
.to.not.throw();
|
|
|
|
|
});
|
2024-06-10 22:42:30 -05:00
|
|
|
|
});
|
|
|
|
|
|
2024-06-12 01:38:05 -05:00
|
|
|
|
test('calculates the size of concrete instances', () => {
|
|
|
|
|
expect(
|
|
|
|
|
(new Schema({type: 'string'}))
|
|
|
|
|
.sizeOf('hi')
|
|
|
|
|
)
|
|
|
|
|
.to.equal(4 + (new TextEncoder().encode('hi')).length);
|
2024-06-11 21:00:03 -05:00
|
|
|
|
expect(
|
2024-06-12 01:38:05 -05:00
|
|
|
|
(new Schema(
|
2024-06-24 04:19:54 -05:00
|
|
|
|
{
|
|
|
|
|
type: 'object',
|
|
|
|
|
properties: {
|
|
|
|
|
foo: {type: 'uint8'},
|
|
|
|
|
bar: {type: 'uint32'},
|
|
|
|
|
baz: {type: 'string'},
|
|
|
|
|
},
|
|
|
|
|
},
|
2024-06-12 01:38:05 -05:00
|
|
|
|
))
|
|
|
|
|
.sizeOf({foo: 69, bar: 420, baz: 'aα'})
|
2024-06-11 21:00:03 -05:00
|
|
|
|
)
|
2024-06-12 01:38:05 -05:00
|
|
|
|
.to.equal(
|
|
|
|
|
1
|
|
|
|
|
+ 4
|
|
|
|
|
+ 4 + (new TextEncoder().encode('aα')).length
|
|
|
|
|
);
|
2024-06-11 21:00:03 -05:00
|
|
|
|
expect(
|
2024-06-12 01:38:05 -05:00
|
|
|
|
(new Schema({type: 'array', subtype: {type: 'string'}}))
|
|
|
|
|
.sizeOf(['hallo', 'hαllo'])
|
2024-06-11 21:00:03 -05:00
|
|
|
|
)
|
2024-06-12 01:38:05 -05:00
|
|
|
|
.to.equal(
|
|
|
|
|
4
|
|
|
|
|
+ 4 + (new TextEncoder().encode('hallo')).length
|
|
|
|
|
+ 4 + (new TextEncoder().encode('hαllo')).length
|
|
|
|
|
);
|
2024-06-24 04:19:54 -05:00
|
|
|
|
expect(
|
|
|
|
|
(new Schema(
|
|
|
|
|
{
|
|
|
|
|
type: 'map',
|
|
|
|
|
value: {
|
|
|
|
|
type: 'object',
|
|
|
|
|
properties: {
|
|
|
|
|
foo: {type: 'uint8'},
|
|
|
|
|
bar: {type: 'uint32'},
|
|
|
|
|
baz: {type: 'string'},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
))
|
|
|
|
|
.sizeOf({
|
|
|
|
|
foo: {foo: 69, bar: 420, baz: 'aα'},
|
|
|
|
|
'aα': {foo: 69, bar: 420, baz: 'meow'},
|
|
|
|
|
})
|
|
|
|
|
)
|
|
|
|
|
.to.equal(
|
|
|
|
|
4
|
|
|
|
|
+ 4 + (new TextEncoder().encode('foo')).length
|
|
|
|
|
+ 1
|
|
|
|
|
+ 4
|
|
|
|
|
+ 4 + (new TextEncoder().encode('aα')).length
|
|
|
|
|
+ 4 + (new TextEncoder().encode('aα')).length
|
|
|
|
|
+ 1
|
|
|
|
|
+ 4
|
|
|
|
|
+ 4 + (new TextEncoder().encode('meow')).length
|
|
|
|
|
);
|
2024-06-10 22:42:30 -05:00
|
|
|
|
});
|
2024-06-11 21:00:03 -05:00
|
|
|
|
|
2024-06-12 01:38:05 -05:00
|
|
|
|
test('encodes and decodes', () => {
|
2024-06-11 21:00:03 -05:00
|
|
|
|
const entries = [
|
2024-06-12 01:38:05 -05:00
|
|
|
|
[{type: 'uint8'}, 255],
|
|
|
|
|
[{type: 'int8'}, -128],
|
|
|
|
|
[{type: 'int8'}, 127],
|
|
|
|
|
[{type: 'uint16'}, 65535],
|
|
|
|
|
[{type: 'int16'}, -32768],
|
|
|
|
|
[{type: 'int16'}, 32767],
|
|
|
|
|
[{type: 'uint32'}, 4294967295],
|
|
|
|
|
[{type: 'int32'}, -2147483648],
|
|
|
|
|
[{type: 'int32'}, 2147483647],
|
|
|
|
|
[{type: 'uint64'}, 18446744073709551615n],
|
|
|
|
|
[{type: 'int64'}, -9223372036854775808n],
|
|
|
|
|
[{type: 'int64'}, 9223372036854775807n],
|
|
|
|
|
[{type: 'float32'}, 0.5],
|
|
|
|
|
[{type: 'float64'}, 1.234],
|
|
|
|
|
[{type: 'string'}, 'hello world'],
|
|
|
|
|
[{type: 'string'}, 'α'],
|
|
|
|
|
[{type: 'array', subtype: {type: 'uint8'}}, [1, 2, 3, 4]],
|
|
|
|
|
[{type: 'array', subtype: {type: 'string'}}, ['one', 'two', 'three', 'four']],
|
2024-06-24 04:19:54 -05:00
|
|
|
|
[{type: 'map', value: {type: 'object', properties: {foo: {type: 'uint8'}, bar: {type: 'string'}}}}, {one: {foo: 64, bar: 'baz'}, two: {foo: 128, bar: 'baw'}}],
|
2024-06-12 01:38:05 -05:00
|
|
|
|
[{type: 'object', properties: {foo: {type: 'uint8'}, bar: {type: 'string'}}}, {foo: 64, bar: 'baz'}],
|
2024-06-24 04:19:54 -05:00
|
|
|
|
[{type: 'object', properties: {foo: {type: 'uint8'}}}, {foo: 64}],
|
2024-06-11 21:00:03 -05:00
|
|
|
|
];
|
2024-07-23 10:10:32 -05:00
|
|
|
|
entries.forEach(([specification, instance]) => {
|
2024-06-12 01:38:05 -05:00
|
|
|
|
const schema = new Schema(specification);
|
2024-07-23 10:10:32 -05:00
|
|
|
|
const view = new DataView(new ArrayBuffer(schema.sizeOf(instance)));
|
|
|
|
|
schema.serialize(instance, view);
|
|
|
|
|
expect(instance)
|
2024-06-12 01:38:05 -05:00
|
|
|
|
.to.deep.equal(schema.deserialize(view));
|
|
|
|
|
});
|
2024-06-11 21:00:03 -05:00
|
|
|
|
});
|