Tests for Address

This commit is contained in:
Greg Hysen 2018-11-19 11:18:34 -08:00
parent a630312074
commit a2ad15be0d
4 changed files with 66 additions and 16 deletions

View File

@ -248,7 +248,7 @@ export class Calldata {
private selector: string; private selector: string;
private rules: EncodingRules; private rules: EncodingRules;
private sizeInBytes: number; private sizeInBytes: number;
private root: MemberCalldataBlock | undefined; private root: CalldataBlock | undefined;
constructor(rules: EncodingRules) { constructor(rules: EncodingRules) {
this.selector = ''; this.selector = '';
@ -257,8 +257,17 @@ export class Calldata {
this.root = undefined; this.root = undefined;
} }
private createQueue(memberBlock: MemberCalldataBlock): Queue<CalldataBlock> { private createQueue(block: CalldataBlock): Queue<CalldataBlock> {
const blockQueue = new Queue<CalldataBlock>(); const blockQueue = new Queue<CalldataBlock>();
// Base Case
if (block instanceof MemberCalldataBlock === false) {
blockQueue.push(block);
return blockQueue;
}
// This is a Member Block
const memberBlock = block as MemberCalldataBlock;
_.eachRight(memberBlock.getMembers(), (member: CalldataBlock) => { _.eachRight(memberBlock.getMembers(), (member: CalldataBlock) => {
if (member instanceof MemberCalldataBlock) { if (member instanceof MemberCalldataBlock) {
blockQueue.mergeFront(this.createQueue(member)); blockQueue.mergeFront(this.createQueue(member));
@ -429,7 +438,7 @@ export class Calldata {
return ""; return "";
} }
public setRoot(block: MemberCalldataBlock) { public setRoot(block: CalldataBlock) {
this.root = block; this.root = block;
this.sizeInBytes += block.getSizeInBytes(); this.sizeInBytes += block.getSizeInBytes();
} }

View File

@ -35,7 +35,7 @@ export abstract class DataType {
const calldata = new Calldata(rules_); const calldata = new Calldata(rules_);
if (selector) calldata.setSelector(selector); if (selector) calldata.setSelector(selector);
const block = this.generateCalldataBlock(value); const block = this.generateCalldataBlock(value);
calldata.setRoot(block as MemberCalldataBlock); // @TODO CHANGE calldata.setRoot(block); // @TODO CHANGE
const calldataHex = calldata.toHexString(); const calldataHex = calldata.toHexString();
return calldataHex; return calldataHex;
} }

View File

@ -20,6 +20,8 @@ export interface DataTypeStaticInterface {
export class Address extends PayloadDataType { export class Address extends PayloadDataType {
private static SIZE_KNOWN_AT_COMPILE_TIME: boolean = true; private static SIZE_KNOWN_AT_COMPILE_TIME: boolean = true;
public static ERROR_MESSAGE_ADDRESS_MUST_START_WITH_0X = "Address must start with '0x'";
public static ERROR_MESSAGE_ADDRESS_MUST_BE_20_BYTES = "Address must be 20 bytes";
constructor(dataItem: DataItem) { constructor(dataItem: DataItem) {
super(dataItem, EvmDataTypeFactory.getInstance(), Address.SIZE_KNOWN_AT_COMPILE_TIME); super(dataItem, EvmDataTypeFactory.getInstance(), Address.SIZE_KNOWN_AT_COMPILE_TIME);
@ -36,9 +38,16 @@ export class Address extends PayloadDataType {
return type === 'address'; return type === 'address';
} }
public encodeValue(value: boolean): Buffer { public encodeValue(value: string): Buffer {
if (value.startsWith('0x') === false) {
throw new Error(Address.ERROR_MESSAGE_ADDRESS_MUST_START_WITH_0X);
}
const valueAsBuffer = ethUtil.toBuffer(value);
if (valueAsBuffer.byteLength !== 20) {
throw new Error(Address.ERROR_MESSAGE_ADDRESS_MUST_BE_20_BYTES);
}
const evmWordWidth = 32; const evmWordWidth = 32;
const encodedValueBuf = ethUtil.setLengthLeft(ethUtil.toBuffer(value), evmWordWidth); const encodedValueBuf = ethUtil.setLengthLeft(valueAsBuffer, evmWordWidth);
return encodedValueBuf; return encodedValueBuf;
} }

View File

@ -725,7 +725,7 @@ describe.only('ABI Encoder', () => {
}); });
}); });
describe('Array', () => { describe.only('Array', () => {
it('Fixed size; Static elements', async () => { it('Fixed size; Static elements', async () => {
// Create DataType object // Create DataType object
const testDataItem = { name: 'testArray', type: 'int[2]' }; const testDataItem = { name: 'testArray', type: 'int[2]' };
@ -793,6 +793,9 @@ describe.only('ABI Encoder', () => {
const argsAsJson = JSON.stringify(args); const argsAsJson = JSON.stringify(args);
expect(decodedArgsAsJson).to.be.equal(argsAsJson); expect(decodedArgsAsJson).to.be.equal(argsAsJson);
}); });
// @TODO: Add test that fails if we pass in the wrong number of elements
// @TODO: Add test that fails if we pass in an element of incorrecrt type
}); });
describe.only('Tuple', () => { describe.only('Tuple', () => {
@ -849,22 +852,51 @@ describe.only('ABI Encoder', () => {
const argsAsJson = JSON.stringify(args); const argsAsJson = JSON.stringify(args);
expect(decodedArgsAsJson).to.be.equal(argsAsJson); expect(decodedArgsAsJson).to.be.equal(argsAsJson);
}); });
// @TODO: Add test that fails if we pass in the wrong number of elements
// @TODO: Add test that fails if we pass in arguments in wrong order
}); });
/* describe.only('Address', () => {
describe('Address', () => {
const testAddressDataItem = { name: 'testAddress', type: 'address' };
it('Valid Address', async () => { it('Valid Address', async () => {
const addressDataType = new AbiEncoder.Address(testAddressDataItem); // Create DataType object
addressDataType.assignValue('0xe41d2489571d322189246dafa5ebde1f4699f498'); const testDataItem = { name: 'Address', type: 'address' };
const expectedAbiEncodedAddress = '0x000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f498'; const dataType = new AbiEncoder.Address(testDataItem);
// Construct args to be encoded
const args = '0xe41d2489571d322189246dafa5ebde1f4699f498';
// Encode Args and validate result
const encodedArgs = dataType.encode(args);
const expectedEncodedArgs = '0x000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f498';
expect(encodedArgs).to.be.equal(expectedEncodedArgs);
// Decode Encoded Args and validate result
const decodedArgs = dataType.decode(encodedArgs);
const decodedArgsAsJson = JSON.stringify(decodedArgs);
const argsAsJson = JSON.stringify(args);
expect(decodedArgsAsJson).to.be.equal(argsAsJson);
});
console.log(addressDataType.getHexValue()); it('Invalid Address - input is not valid hex', async () => {
console.log(expectedAbiEncodedAddress); // Create DataType object
expect(addressDataType.getHexValue()).to.be.equal(expectedAbiEncodedAddress); const testDataItem = { name: 'Address', type: 'address' };
const dataType = new AbiEncoder.Address(testDataItem);
// Construct args to be encoded
const args = 'e4';
// Encode Args and validate result
expect(() => { dataType.encode(args) }).to.throw(AbiEncoder.Address.ERROR_MESSAGE_ADDRESS_MUST_START_WITH_0X);
});
it('Invalid Address - input is not 20 bytes', async () => {
// Create DataType object
const testDataItem = { name: 'Address', type: 'address' };
const dataType = new AbiEncoder.Address(testDataItem);
// Construct args to be encoded
const args = '0xe4';
// Encode Args and validate result
expect(() => { dataType.encode(args) }).to.throw(AbiEncoder.Address.ERROR_MESSAGE_ADDRESS_MUST_BE_20_BYTES);
}); });
}); });
/*
describe('Bool', () => { describe('Bool', () => {
const testBoolDataItem = { name: 'testBool', type: 'bool' }; const testBoolDataItem = { name: 'testBool', type: 'bool' };
it('True', async () => { it('True', async () => {