Check Enum index before value on construct (#1329)
This commit is contained in:
@@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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`
|
||||
|
||||
Reference in New Issue
Block a user