silphius/app/ecs/schema.test.js

195 lines
4.6 KiB
JavaScript
Raw Normal View History

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
});