Check Enum index before value on construct (#1329)

This commit is contained in:
Jaco Greeff
2019-08-21 09:52:56 +02:00
committed by GitHub
parent 16fe47ebb4
commit 3b71c0f64a
2 changed files with 80 additions and 17 deletions
+71 -9
View File
@@ -234,20 +234,82 @@ describe('Enum', (): void => {
new Enum(['foo', 'bar'], 1).eq('foo')
).toBe(false);
});
it('has isNone set, with correct index (i.e. no values are used)', (): void => {
const test = new Enum(['foo', 'bar'], 1);
expect(test.isNone).toBe(true);
expect(test.index).toEqual(1);
});
});
});
describe('toRawType', (): void => {
it('has a sane output for basic enums', (): void => {
expect(
new Enum(['foo', 'bar']).toRawType()
).toEqual(JSON.stringify({ _enum: ['foo', 'bar'] }));
describe('index construction', (): void => {
it('creates enum where index is specified', (): void => {
const Test = Enum.with({
A: U32,
B: U32
});
const test = new Test(new U32(123), 1);
expect(test.type).toEqual('B');
expect((test.value as U32).toNumber()).toEqual(123);
});
it('has a sane output for types enums', (): void => {
expect(
new Enum({ foo: Text, bar: U32 }).toRawType()
).toEqual(JSON.stringify({ _enum: { foo: 'Text', bar: 'u32' } }));
it('creates enum when value is an enum', (): void => {
const Test = Enum.with({
A: U32,
B: U32
});
const test = new Test(new Test(123, 1));
expect(test.type).toEqual('B');
expect((test.value as U32).toNumber()).toEqual(123);
});
it('creates via enum with nested enums as the value', (): void => {
const Nest = Enum.with({
C: U32,
D: U32
});
const Test = Enum.with({
A: U32,
B: Nest
});
const test = new Test(new Nest(123, 1), 1);
expect(test.type).toEqual('B');
expect((test.value as Enum).type).toEqual('D');
expect(((test.value as Enum).value as U32).toNumber()).toEqual(123);
});
});
describe('outputs', (): void => {
describe('toRawType', (): void => {
it('has a sane output for basic enums', (): void => {
expect(
new Enum(['foo', 'bar']).toRawType()
).toEqual(JSON.stringify({ _enum: ['foo', 'bar'] }));
});
it('has a sane output for typed enums', (): void => {
expect(
new Enum({ foo: Text, bar: U32 }).toRawType()
).toEqual(JSON.stringify({ _enum: { foo: 'Text', bar: 'u32' } }));
});
});
describe('toHex', (): void => {
it('has a proper hex representation & length', (): void => {
const Test = Enum.with({
A: Text,
B: U32
});
const test = new Test(123, 1);
expect(test.toHex()).toEqual('0x017b000000');
expect(test.encodedLength).toEqual(1 + 4);
});
});
});
});
+9 -8
View File
@@ -11,7 +11,8 @@ import { mapToTypeMap } from './utils';
import Base from './Base';
import Struct from './Struct';
interface EnumConstructor<T = Codec> {
// export interface, this is used in Enum.with, so required as public by TS
export interface EnumConstructor<T = Codec> {
new(value?: any, index?: number): T;
}
@@ -61,7 +62,7 @@ export default class Enum extends Base<Codec> {
private _isBasic: boolean;
public constructor (def: Record<string, InterfaceTypes | Constructor> | string[], value?: any, index?: number | Enum) {
public constructor (def: Record<string, InterfaceTypes | Constructor> | string[], value?: any, index?: number) {
const defInfo = extractDef(def);
const decoded = Enum.decodeEnum(defInfo.def, value, index);
@@ -73,13 +74,13 @@ export default class Enum extends Base<Codec> {
this._index = this._indexes.indexOf(decoded.index) || 0;
}
private static decodeEnum (def: TypesDef, value?: any, index?: number | Enum): Decoded {
if (value instanceof Enum) {
return Enum.createValue(def, value._index, value.raw);
} else if (index instanceof Enum) {
return Enum.createValue(def, index._index, index.raw);
} else if (isNumber(index)) {
private static decodeEnum (def: TypesDef, value?: any, index?: number): Decoded {
// NOTE We check the index path first, before looking at values - this allows treating
// the optional indexes before anything else, more-specific > less-specific
if (isNumber(index)) {
return Enum.createValue(def, index, value);
} else if (value instanceof Enum) {
return Enum.createValue(def, value._index, value.raw);
}
// Or else, we just look at `value`