silphius/app/ecs/schema.test.js
2024-07-26 19:28:28 -05:00

195 lines
4.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {expect, test} from 'vitest';
import Schema from './schema.js';
const compare = (specification, value) => {
expect(new Schema(specification).defaultValue())
.to.deep.equal(value);
};
test('defaults values', () => {
[
'uint8',
'int8',
'uint16',
'int16',
'uint32',
'int32',
'float32',
'float64',
].forEach((type) => {
compare({type}, 0);
});
[
'uint64',
'int64',
].forEach((type) => {
compare({type}, 0n);
});
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'}}}},
},
},
{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'}}}},
},
},
},
{},
);
});
test.todo('defaults nested values', () => {
compare(
{
type: 'array',
subtype: {
type: 'object',
properties: {
foo: {defaultValue: 'bar', type: 'string'},
},
},
},
[{}],
[{foo: 'bar'}],
);
});
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}}});
new Schema({type: 'map', value: {type}});
})
.to.not.throw();
});
});
test('calculates the size of concrete instances', () => {
expect(
(new Schema({type: 'string'}))
.sizeOf('hi')
)
.to.equal(4 + (new TextEncoder().encode('hi')).length);
expect(
(new Schema(
{
type: 'object',
properties: {
foo: {type: 'uint8'},
bar: {type: 'uint32'},
baz: {type: 'string'},
},
},
))
.sizeOf({foo: 69, bar: 420, baz: 'aα'})
)
.to.equal(
1
+ 4
+ 4 + (new TextEncoder().encode('aα')).length
);
expect(
(new Schema({type: 'array', subtype: {type: 'string'}}))
.sizeOf(['hallo', 'hαllo'])
)
.to.equal(
4
+ 4 + (new TextEncoder().encode('hallo')).length
+ 4 + (new TextEncoder().encode('hαllo')).length
);
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
);
});
test('encodes and decodes', () => {
const entries = [
[{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']],
[{type: 'map', value: {type: 'object', properties: {foo: {type: 'uint8'}, bar: {type: 'string'}}}}, {one: {foo: 64, bar: 'baz'}, two: {foo: 128, bar: 'baw'}}],
[{type: 'object', properties: {foo: {type: 'uint8'}, bar: {type: 'string'}}}, {foo: 64, bar: 'baz'}],
[{type: 'object', properties: {foo: {type: 'uint8'}}}, {foo: 64}],
];
entries.forEach(([specification, instance]) => {
const schema = new Schema(specification);
const view = new DataView(new ArrayBuffer(schema.sizeOf(instance)));
schema.serialize(instance, view);
expect(instance)
.to.deep.equal(schema.deserialize(view));
});
});