mirror of
https://github.com/dolthub/dolt.git
synced 2026-04-26 11:39:05 -05:00
Implement Enum encode/decode + a bunch of tests
This commit is contained in:
+13
-3
@@ -6,7 +6,7 @@ import Struct from './struct.js';
|
||||
import type {ChunkStore} from './chunk_store.js';
|
||||
import type {NomsKind} from './noms_kind.js';
|
||||
import {decode as decodeBase64} from './base64.js';
|
||||
import {Field, makeCompoundType, makePrimitiveType, makeStructType, makeType, makeUnresolvedType, StructDesc, Type} from './type.js';
|
||||
import {Field, makeCompoundType, makeEnumType, makePrimitiveType, makeStructType, makeType, makeUnresolvedType, StructDesc, Type} from './type.js';
|
||||
import {invariant, notNull} from './assert.js';
|
||||
import {isPrimitiveKind, Kind} from './noms_kind.js';
|
||||
import {lookupPackage, Package, readPackage} from './package.js';
|
||||
@@ -134,6 +134,10 @@ class JsonArrayReader {
|
||||
return m;
|
||||
}
|
||||
|
||||
readEnum(): number {
|
||||
return this.readNumber();
|
||||
}
|
||||
|
||||
readPackage(t: Type, pkg: ?Package): Package {
|
||||
let r2 = new JsonArrayReader(this.readArray(), this._cs);
|
||||
let types = [];
|
||||
@@ -222,7 +226,7 @@ class JsonArrayReader {
|
||||
pkg = notNull(pkg);
|
||||
let typeDef = pkg.types[ordinal];
|
||||
if (typeDef.kind === Kind.Enum) {
|
||||
throw new Error('Not implemented');
|
||||
return this.readEnum();
|
||||
}
|
||||
|
||||
invariant(typeDef.kind === Kind.Struct);
|
||||
@@ -234,7 +238,13 @@ class JsonArrayReader {
|
||||
|
||||
switch (k) {
|
||||
case Kind.Enum:
|
||||
throw new Error('Not implemented');
|
||||
let name = this.readString();
|
||||
let r2 = new JsonArrayReader(this.readArray(), this._cs);
|
||||
let ids = [];
|
||||
while (!r2.atEnd()) {
|
||||
ids.push(r2.readString());
|
||||
}
|
||||
return makeEnumType(name, ids);
|
||||
case Kind.List:
|
||||
case Kind.Map:
|
||||
case Kind.Ref:
|
||||
|
||||
+161
-2
@@ -8,7 +8,7 @@ import test from './async_test.js';
|
||||
import type {TypeDesc} from './type.js';
|
||||
import {assert} from 'chai';
|
||||
import {decodeNomsValue, JsonArrayReader, readValue} from './decode.js';
|
||||
import {Field, makeCompoundType, makePrimitiveType, makeStructType, makeType, Type} from './type.js';
|
||||
import {Field, makeCompoundType, makeEnumType, makePrimitiveType, makeStructType, makeType, Type} from './type.js';
|
||||
import {invariant} from './assert.js';
|
||||
import {Kind} from './noms_kind.js';
|
||||
import {registerPackage, Package} from './package.js';
|
||||
@@ -172,7 +172,7 @@ suite('Decode', () => {
|
||||
assert.deepEqual(desc, s.desc);
|
||||
|
||||
for (let key in data) {
|
||||
assert.strictEqual(data[key], s.get(key));
|
||||
assert.deepEqual(data[key], s.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,6 +198,165 @@ suite('Decode', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('test read struct union', async () => {
|
||||
let ms = new MemoryStore();
|
||||
let tr = makeStructType('A2', [
|
||||
new Field('x', makePrimitiveType(Kind.Float32), false)
|
||||
], [
|
||||
new Field('b', makePrimitiveType(Kind.Bool), false),
|
||||
new Field('s', makePrimitiveType(Kind.String), false)
|
||||
]);
|
||||
|
||||
let pkg = new Package([tr], []);
|
||||
registerPackage(pkg);
|
||||
|
||||
let a = [Kind.Unresolved, pkg.ref.toString(), 0, 42, 1, 'hi'];
|
||||
let r = new JsonArrayReader(a, ms);
|
||||
let v = await r.readTopLevelValue();
|
||||
|
||||
assertStruct(v, tr.desc, {
|
||||
x: 42,
|
||||
s: 'hi'
|
||||
});
|
||||
});
|
||||
|
||||
test('test read struct optional', async () => {
|
||||
let ms = new MemoryStore();
|
||||
let tr = makeStructType('A3', [
|
||||
new Field('x', makePrimitiveType(Kind.Float32), false),
|
||||
new Field('s', makePrimitiveType(Kind.String), true),
|
||||
new Field('b', makePrimitiveType(Kind.Bool), true)
|
||||
], []);
|
||||
|
||||
let pkg = new Package([tr], []);
|
||||
registerPackage(pkg);
|
||||
|
||||
let a = [Kind.Unresolved, pkg.ref.toString(), 0, 42, false, true, false];
|
||||
let r = new JsonArrayReader(a, ms);
|
||||
let v = await r.readTopLevelValue();
|
||||
|
||||
assertStruct(v, tr.desc, {
|
||||
x: 42,
|
||||
b: false
|
||||
});
|
||||
});
|
||||
|
||||
test('test read struct with list', async () => {
|
||||
let ms = new MemoryStore();
|
||||
let tr = makeStructType('A4', [
|
||||
new Field('b', makePrimitiveType(Kind.Bool), false),
|
||||
new Field('l', makeCompoundType(Kind.List, makePrimitiveType(Kind.Int32)), false),
|
||||
new Field('s', makePrimitiveType(Kind.String), false)
|
||||
], []);
|
||||
|
||||
let pkg = new Package([tr], []);
|
||||
registerPackage(pkg);
|
||||
|
||||
let a = [Kind.Unresolved, pkg.ref.toString(), 0, true, [0, 1, 2], 'hi'];
|
||||
let r = new JsonArrayReader(a, ms);
|
||||
let v = await r.readTopLevelValue();
|
||||
|
||||
assertStruct(v, tr.desc, {
|
||||
b: true,
|
||||
l: [0, 1, 2],
|
||||
s: 'hi'
|
||||
});
|
||||
});
|
||||
|
||||
test('test read struct with value', async () => {
|
||||
let ms = new MemoryStore();
|
||||
let tr = makeStructType('A5', [
|
||||
new Field('b', makePrimitiveType(Kind.Bool), false),
|
||||
new Field('v', makePrimitiveType(Kind.Value), false),
|
||||
new Field('s', makePrimitiveType(Kind.String), false)
|
||||
], []);
|
||||
|
||||
let pkg = new Package([tr], []);
|
||||
registerPackage(pkg);
|
||||
|
||||
let a = [Kind.Unresolved, pkg.ref.toString(), 0, true, Kind.UInt8, 42, 'hi'];
|
||||
let r = new JsonArrayReader(a, ms);
|
||||
let v = await r.readTopLevelValue();
|
||||
|
||||
assertStruct(v, tr.desc, {
|
||||
b: true,
|
||||
v: 42,
|
||||
s: 'hi'
|
||||
});
|
||||
});
|
||||
|
||||
test('test read value struct', async () => {
|
||||
let ms = new MemoryStore();
|
||||
let tr = makeStructType('A1', [
|
||||
new Field('x', makePrimitiveType(Kind.Int16), false),
|
||||
new Field('s', makePrimitiveType(Kind.String), false),
|
||||
new Field('b', makePrimitiveType(Kind.Bool), false)
|
||||
], []);
|
||||
|
||||
let pkg = new Package([tr], []);
|
||||
registerPackage(pkg);
|
||||
|
||||
let a = [Kind.Value, Kind.Unresolved, pkg.ref.toString(), 0, 42, 'hi', true];
|
||||
let r = new JsonArrayReader(a, ms);
|
||||
let v = await r.readTopLevelValue();
|
||||
|
||||
assertStruct(v, tr.desc, {
|
||||
x: 42,
|
||||
s: 'hi',
|
||||
b: true
|
||||
});
|
||||
});
|
||||
|
||||
test('test read enum', async () => {
|
||||
let ms = new MemoryStore();
|
||||
|
||||
let tr = makeEnumType('E', ['a', 'b', 'c']);
|
||||
let pkg = new Package([tr], []);
|
||||
registerPackage(pkg);
|
||||
|
||||
let a = [Kind.Unresolved, pkg.ref.toString(), 0, 1];
|
||||
let r = new JsonArrayReader(a, ms);
|
||||
let v = await r.readTopLevelValue();
|
||||
|
||||
assert.deepEqual(1, v);
|
||||
});
|
||||
|
||||
test('test read value enum', async () => {
|
||||
let ms = new MemoryStore();
|
||||
|
||||
let tr = makeEnumType('E', ['a', 'b', 'c']);
|
||||
let pkg = new Package([tr], []);
|
||||
registerPackage(pkg);
|
||||
|
||||
let a = [Kind.Value, Kind.Unresolved, pkg.ref.toString(), 0, 1];
|
||||
let r = new JsonArrayReader(a, ms);
|
||||
let v = await r.readTopLevelValue();
|
||||
|
||||
assert.deepEqual(1, v);
|
||||
});
|
||||
|
||||
test('test read struct with', async () => {
|
||||
let ms = new MemoryStore();
|
||||
let tr = makeStructType('A1', [
|
||||
new Field('x', makePrimitiveType(Kind.Int16), false),
|
||||
new Field('e', makeType(new Ref(), 1), false),
|
||||
new Field('b', makePrimitiveType(Kind.Bool), false)
|
||||
], []);
|
||||
let enumTref = makeEnumType('E', ['a', 'b', 'c']);
|
||||
let pkg = new Package([tr, enumTref], []);
|
||||
registerPackage(pkg);
|
||||
|
||||
let a = [Kind.Unresolved, pkg.ref.toString(), 0, 42, 1, true];
|
||||
let r = new JsonArrayReader(a, ms);
|
||||
let v = await r.readTopLevelValue();
|
||||
|
||||
assertStruct(v, tr.desc, {
|
||||
x: 42,
|
||||
e: 1,
|
||||
b: true
|
||||
});
|
||||
});
|
||||
|
||||
test('test read map of string to struct', async () => {
|
||||
let ms = new MemoryStore();
|
||||
let tr = makeStructType('s', [
|
||||
|
||||
+17
-3
@@ -9,7 +9,7 @@ import {encode as encodeBase64} from './base64.js';
|
||||
import {invariant, notNull} from './assert.js';
|
||||
import {isPrimitiveKind, Kind} from './noms_kind.js';
|
||||
import {lookupPackage, Package} from './package.js';
|
||||
import {makePrimitiveType, StructDesc, Type} from './type.js';
|
||||
import {makePrimitiveType, EnumDesc, StructDesc, Type} from './type.js';
|
||||
|
||||
const typedTag = 't ';
|
||||
|
||||
@@ -166,7 +166,15 @@ class JsonArrayWriter {
|
||||
this.writeKind(k);
|
||||
switch (k) {
|
||||
case Kind.Enum:
|
||||
throw new Error('Not implemented');
|
||||
let desc = t.desc;
|
||||
invariant(desc instanceof EnumDesc);
|
||||
this.write(t.name);
|
||||
let w2 = new JsonArrayWriter(this._cs);
|
||||
for (let i = 0; i < desc.ids.length; i++) {
|
||||
w2.write(desc.ids[i]);
|
||||
}
|
||||
this.write(w2.array);
|
||||
break;
|
||||
case Kind.List:
|
||||
case Kind.Map:
|
||||
case Kind.Ref:
|
||||
@@ -224,7 +232,9 @@ class JsonArrayWriter {
|
||||
let typeDef = pkg.types[t.ordinal];
|
||||
switch (typeDef.kind) {
|
||||
case Kind.Enum:
|
||||
throw new Error('Not implemented');
|
||||
invariant(typeof v === 'number');
|
||||
this.writeEnum(v);
|
||||
break;
|
||||
case Kind.Struct: {
|
||||
invariant(v instanceof Struct);
|
||||
this.writeStruct(v, t, typeDef, pkg);
|
||||
@@ -263,6 +273,10 @@ class JsonArrayWriter {
|
||||
this.writeValue(s.get(unionField.name), unionField.t, pkg);
|
||||
}
|
||||
}
|
||||
|
||||
writeEnum(v: number) {
|
||||
this.writeNumber(v);
|
||||
}
|
||||
}
|
||||
|
||||
function orderValuesByRef(t: Type, a: Array<any>): Array<any> {
|
||||
|
||||
+62
-1
@@ -7,7 +7,7 @@ import MemoryStore from './memory_store.js';
|
||||
import Ref from './ref.js';
|
||||
import Struct from './struct.js';
|
||||
import test from './async_test.js';
|
||||
import {Field, makeCompoundType, makePrimitiveType, makeStructType, makeType} from './type.js';
|
||||
import {Field, makeCompoundType, makeEnumType, makePrimitiveType, makeStructType, makeType, Type} from './type.js';
|
||||
import {JsonArrayWriter, encodeNomsValue} from './encode.js';
|
||||
import {Kind} from './noms_kind.js';
|
||||
import {Package, registerPackage} from './package.js';
|
||||
@@ -239,6 +239,67 @@ suite('Encode', () => {
|
||||
assert.deepEqual([Kind.Unresolved, pkgRef.toString(), 1, 42], w.array);
|
||||
});
|
||||
|
||||
test('write enum', async () => {
|
||||
let ms = new MemoryStore();
|
||||
let w = new JsonArrayWriter(ms);
|
||||
|
||||
let pkg = new Package([makeEnumType('E', ['a', 'b', 'c'])], []);
|
||||
registerPackage(pkg);
|
||||
let pkgRef = pkg.ref;
|
||||
let typ = makeType(pkgRef, 0);
|
||||
|
||||
w.writeTopLevel(typ, 1);
|
||||
assert.deepEqual([Kind.Unresolved, pkgRef.toString(), 0, 1], w.array);
|
||||
});
|
||||
|
||||
test('write list of enum', async () => {
|
||||
let ms = new MemoryStore();
|
||||
let w = new JsonArrayWriter(ms);
|
||||
|
||||
let pkg = new Package([makeEnumType('E', ['a', 'b', 'c'])], []);
|
||||
registerPackage(pkg);
|
||||
let pkgRef = pkg.ref;
|
||||
let typ = makeType(pkgRef, 0);
|
||||
let listType = makeCompoundType(Kind.List, typ);
|
||||
let l = [0, 1, 2];
|
||||
|
||||
w.writeTopLevel(listType, l);
|
||||
assert.deepEqual([Kind.List, Kind.Unresolved, pkgRef.toString(), 0, [0, 1, 2]], w.array);
|
||||
});
|
||||
|
||||
test('write type value', async () => {
|
||||
let ms = new MemoryStore();
|
||||
|
||||
let test = (expected: Array<any>, v: Type) => {
|
||||
let w = new JsonArrayWriter(ms);
|
||||
w.writeTopLevel(v.type, v);
|
||||
assert.deepEqual(expected, w.array);
|
||||
};
|
||||
|
||||
test([Kind.Type, Kind.Int32], makePrimitiveType(Kind.Int32));
|
||||
test([Kind.Type, Kind.List, [Kind.Bool]], makeCompoundType(Kind.List, makePrimitiveType(Kind.Bool)));
|
||||
test([Kind.Type, Kind.Map, [Kind.Bool, Kind.String]], makeCompoundType(Kind.Map, makePrimitiveType(Kind.Bool), makePrimitiveType(Kind.String)));
|
||||
test([Kind.Type, Kind.Enum, 'E', ['a', 'b', 'c']], makeEnumType('E', ['a', 'b', 'c']));
|
||||
test([Kind.Type, Kind.Struct, 'S', ['x', Kind.Int16, false, 'v', Kind.Value, true], []], makeStructType('S', [
|
||||
new Field('x', makePrimitiveType(Kind.Int16), false),
|
||||
new Field('v', makePrimitiveType(Kind.Value), true)
|
||||
], []));
|
||||
test([Kind.Type, Kind.Struct, 'S', [], ['x', Kind.Int16, false, 'v', Kind.Value, false]], makeStructType('S', [], [
|
||||
new Field('x', makePrimitiveType(Kind.Int16), false),
|
||||
new Field('v', makePrimitiveType(Kind.Value), false)
|
||||
]));
|
||||
|
||||
let pkgRef = Ref.parse('sha1-0123456789abcdef0123456789abcdef01234567');
|
||||
test([Kind.Type, Kind.Unresolved, pkgRef.toString(), 123], makeType(pkgRef, 123));
|
||||
|
||||
test([Kind.Type, Kind.Struct, 'S', ['e', Kind.Unresolved, pkgRef.toString(), 123, false, 'x', Kind.Int64, false], []], makeStructType('S', [
|
||||
new Field('e', makeType(pkgRef, 123), false),
|
||||
new Field('x', makePrimitiveType(Kind.Int64), false)
|
||||
], []));
|
||||
|
||||
// test([Kind.Type, Kind.Unresolved, new Ref().toString(), -1, 'ns', 'n'], makeUnresolvedType('ns', 'n'));
|
||||
});
|
||||
|
||||
test('top level blob', () => {
|
||||
function stringToBuffer(s) {
|
||||
let bytes = new Uint8Array(s.length);
|
||||
|
||||
+62
-20
@@ -37,8 +37,12 @@ class UnresolvedDesc {
|
||||
}
|
||||
|
||||
equals(other: TypeDesc): boolean {
|
||||
return other instanceof UnresolvedDesc && other._pkgRef.equals(this._pkgRef)
|
||||
&& other._ordinal === this._ordinal;
|
||||
if (other.kind !== this.kind) {
|
||||
return false;
|
||||
}
|
||||
invariant(other instanceof UnresolvedDesc);
|
||||
|
||||
return other._pkgRef.equals(this._pkgRef) && other._ordinal === this._ordinal;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +75,37 @@ class CompoundDesc {
|
||||
}
|
||||
}
|
||||
|
||||
class EnumDesc {
|
||||
ids: Array<string>;
|
||||
|
||||
constructor(ids: Array<string>) {
|
||||
this.ids = ids;
|
||||
}
|
||||
|
||||
get kind(): NomsKind {
|
||||
return Kind.Enum;
|
||||
}
|
||||
|
||||
equals(other: TypeDesc): boolean {
|
||||
if (other.kind !== this.kind) {
|
||||
return false;
|
||||
}
|
||||
invariant(other instanceof EnumDesc);
|
||||
|
||||
if (other.ids.length !== this.ids.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.ids.length; i++) {
|
||||
if (this.ids[i] !== other.id[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class StructDesc {
|
||||
fields: Array<Field>;
|
||||
union: Array<Field>;
|
||||
@@ -85,27 +120,28 @@ class StructDesc {
|
||||
}
|
||||
|
||||
equals(other: TypeDesc): boolean {
|
||||
if (other instanceof StructDesc) {
|
||||
if (this.fields.length !== other.fields.length || this.union.length !== other.union.length) {
|
||||
return false;
|
||||
}
|
||||
if (other.kind !== this.kind) {
|
||||
return false;
|
||||
}
|
||||
invariant(other instanceof StructDesc);
|
||||
|
||||
for (let i = 0; i < this.fields.length; i++) {
|
||||
if (!this.fields[i].equals(other.fields[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.union.length; i++) {
|
||||
if (!this.union[i].equals(other.union[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
if (this.fields.length !== other.fields.length || this.union.length !== other.union.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
for (let i = 0; i < this.fields.length; i++) {
|
||||
if (!this.fields[i].equals(other.fields[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.union.length; i++) {
|
||||
if (!this.union[i].equals(other.union[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,6 +273,10 @@ function makeCompoundType(k: NomsKind, ...elemTypes: Array<Type>): Type {
|
||||
return buildType('', new CompoundDesc(k, elemTypes));
|
||||
}
|
||||
|
||||
function makeEnumType(name: string, ids: Array<string>): Type {
|
||||
return buildType(name, new EnumDesc(ids));
|
||||
}
|
||||
|
||||
function makeStructType(name: string, fields: Array<Field>, choices: Array<Field>): Type {
|
||||
return buildType(name, new StructDesc(fields, choices));
|
||||
}
|
||||
@@ -254,8 +294,10 @@ let packageType = makePrimitiveType(Kind.Package);
|
||||
|
||||
export {
|
||||
CompoundDesc,
|
||||
EnumDesc,
|
||||
Field,
|
||||
makeCompoundType,
|
||||
makeEnumType,
|
||||
makePrimitiveType,
|
||||
makeStructType,
|
||||
makeType,
|
||||
|
||||
Reference in New Issue
Block a user