From 09c0fc94fc91134acfdee1017d7a50e2047b019b Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Thu, 2 Aug 2018 13:22:04 -0700 Subject: Implement first round of tests for findOrdersThatCoverMakerAssetFillAmount --- packages/order-utils/test/market_utils_test.ts | 146 +++++++++++++++++++++ .../order-utils/test/utils/test_order_factory.ts | 63 +++++++++ 2 files changed, 209 insertions(+) create mode 100644 packages/order-utils/test/market_utils_test.ts create mode 100644 packages/order-utils/test/utils/test_order_factory.ts (limited to 'packages/order-utils/test') diff --git a/packages/order-utils/test/market_utils_test.ts b/packages/order-utils/test/market_utils_test.ts new file mode 100644 index 000000000..93779d035 --- /dev/null +++ b/packages/order-utils/test/market_utils_test.ts @@ -0,0 +1,146 @@ +import { OrderRelevantState, SignedOrder } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; +import * as chai from 'chai'; +import * as _ from 'lodash'; +import 'mocha'; + +import { constants, marketUtils, orderFactory } from '../src'; + +import { chaiSetup } from './utils/chai_setup'; +import { testOrderFactory } from './utils/test_order_factory'; + +chaiSetup.configure(); +const expect = chai.expect; + +// tslint:disable: no-unused-expression +describe('marketUtils', () => { + describe.only('#findOrdersThatCoverMakerAssetFillAmount', () => { + describe('no orders', () => { + it('returns empty and unchanged remainingFillAmount', async () => { + const fillAmount = new BigNumber(10); + const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount( + [], + [], + fillAmount, + ); + expect(resultOrders).to.be.empty; + expect(remainingFillAmount).to.be.bignumber.equal(fillAmount); + }); + }); + describe('orders are all completely fillable', () => { + // generate three signed orders each with 10 units of makerAsset, 30 total + const testOrderCount = 3; + const makerAssetAmount = new BigNumber(10); + const inputOrders = testOrderFactory.generateTestSignedOrders( + { + makerAssetAmount, + }, + testOrderCount, + ); + // generate order states that cover the required fill amount + const inputOrderStates = testOrderFactory.generateTestOrderRelevantStates( + { + remainingFillableMakerAssetAmount: makerAssetAmount, + }, + testOrderCount, + ); + it('returns input orders and zero remainingFillAmount when input exactly matches requested fill amount', async () => { + // try to fill 30 units of makerAsset + const fillAmount = new BigNumber(30); + const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount( + inputOrders, + inputOrderStates, + fillAmount, + ); + expect(resultOrders).to.be.deep.equal(inputOrders); + expect(remainingFillAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT); + }); + it('returns input orders and zero remainingFillAmount when input has more than requested fill amount', async () => { + // try to fill 25 units of makerAsset + const fillAmount = new BigNumber(25); + const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount( + inputOrders, + inputOrderStates, + fillAmount, + ); + expect(resultOrders).to.be.deep.equal(inputOrders); + expect(remainingFillAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT); + }); + it('returns input orders and non-zero remainingFillAmount when input has less than requested fill amount', async () => { + // try to fill 35 units of makerAsset + const fillAmount = new BigNumber(35); + const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount( + inputOrders, + inputOrderStates, + fillAmount, + ); + expect(resultOrders).to.be.deep.equal(inputOrders); + expect(remainingFillAmount).to.be.bignumber.equal(new BigNumber(5)); + }); + it('returns first order and zero remainingFillAmount when requested fill amount is exactly covered by the first order', async () => { + // try to fill 10 units of makerAsset + const fillAmount = new BigNumber(10); + const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount( + inputOrders, + inputOrderStates, + fillAmount, + ); + expect(resultOrders).to.be.deep.equal([inputOrders[0]]); + expect(remainingFillAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT); + }); + it('returns first two orders and zero remainingFillAmount when requested fill amount is over covered by the first two order', async () => { + // try to fill 15 units of makerAsset + const fillAmount = new BigNumber(15); + const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount( + inputOrders, + inputOrderStates, + fillAmount, + ); + expect(resultOrders).to.be.deep.equal([inputOrders[0], inputOrders[1]]); + expect(remainingFillAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT); + }); + }); + describe('orders are partially fillable', () => { + // generate three signed orders each with 10 units of makerAsset, 30 total + const testOrderCount = 3; + const makerAssetAmount = new BigNumber(10); + const inputOrders = testOrderFactory.generateTestSignedOrders( + { + makerAssetAmount, + }, + testOrderCount, + ); + // generate order states that cover different scenarios + // 1. order is completely filled already + // 2. order is partially fillable + // 3. order is completely fillable + const partialOrderStates: Array> = [ + { + remainingFillableMakerAssetAmount: constants.ZERO_AMOUNT, + }, + { + remainingFillableMakerAssetAmount: new BigNumber(5), + }, + { + remainingFillableMakerAssetAmount: makerAssetAmount, + }, + ]; + const inputOrderStates: OrderRelevantState[] = _.map( + partialOrderStates, + testOrderFactory.generateTestOrderRelevantState, + ); + it('returns last 2 orders and non-zero remainingFillAmount when trying to fill original makerAssetAmounts', async () => { + // try to fill 30 units of makerAsset + const fillAmount = new BigNumber(30); + const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount( + inputOrders, + inputOrderStates, + fillAmount, + ); + expect(resultOrders).to.be.deep.equal([inputOrders[1], inputOrders[2]]); + expect(remainingFillAmount).to.be.bignumber.equal(new BigNumber(15)); + }); + }); + }); + describe('#findFeeOrdersThatCoverFeesForTargetOrders', () => {}); +}); diff --git a/packages/order-utils/test/utils/test_order_factory.ts b/packages/order-utils/test/utils/test_order_factory.ts new file mode 100644 index 000000000..2c5d8cf61 --- /dev/null +++ b/packages/order-utils/test/utils/test_order_factory.ts @@ -0,0 +1,63 @@ +import { Order, OrderRelevantState, SignedOrder } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; +import * as _ from 'lodash'; + +import { constants, orderFactory } from '../../src'; + +const BASE_TEST_ORDER: Order = orderFactory.createOrder( + constants.NULL_ADDRESS, + constants.NULL_ADDRESS, + constants.NULL_ADDRESS, + constants.ZERO_AMOUNT, + constants.ZERO_AMOUNT, + constants.ZERO_AMOUNT, + constants.NULL_BYTES, + constants.ZERO_AMOUNT, + constants.NULL_BYTES, + constants.NULL_ADDRESS, + constants.NULL_ADDRESS, +); +const BASE_TEST_SIGNED_ORDER: SignedOrder = { + ...BASE_TEST_ORDER, + signature: constants.NULL_BYTES, +}; +const BASE_TEST_ORDER_RELEVANT_STATE: OrderRelevantState = { + makerBalance: constants.ZERO_AMOUNT, + makerProxyAllowance: constants.ZERO_AMOUNT, + makerFeeBalance: constants.ZERO_AMOUNT, + makerFeeProxyAllowance: constants.ZERO_AMOUNT, + filledTakerAssetAmount: constants.ZERO_AMOUNT, + remainingFillableMakerAssetAmount: constants.ZERO_AMOUNT, + remainingFillableTakerAssetAmount: constants.ZERO_AMOUNT, +}; + +export const testOrderFactory = { + generateTestSignedOrder(partialOrder: Partial): SignedOrder { + return transformObject(BASE_TEST_SIGNED_ORDER, partialOrder); + }, + generateTestSignedOrders(partialOrder: Partial, numOrders: number): SignedOrder[] { + const baseTestOrders = generateArrayOfInput(BASE_TEST_SIGNED_ORDER, numOrders); + return transformObjects(baseTestOrders, partialOrder); + }, + generateTestOrderRelevantState(partialOrderRelevantState: Partial): OrderRelevantState { + return transformObject(BASE_TEST_ORDER_RELEVANT_STATE, partialOrderRelevantState); + }, + generateTestOrderRelevantStates( + partialOrderRelevantState: Partial, + numOrderStates: number, + ): OrderRelevantState[] { + const baseTestOrderStates = generateArrayOfInput(BASE_TEST_ORDER_RELEVANT_STATE, numOrderStates); + return transformObjects(baseTestOrderStates, partialOrderRelevantState); + }, +}; + +function generateArrayOfInput(input: T, rangeLength: number): T[] { + return _.map(_.range(rangeLength), () => input); +} +function transformObject(input: T, transformation: Partial): T { + const copy = _.cloneDeep(input); + return _.assign(copy, transformation); +} +function transformObjects(inputs: T[], transformation: Partial): T[] { + return _.map(inputs, input => transformObject(input, transformation)); +} -- cgit From bc5f8e52de9dfe920ce1d0e6b44c90a5a5826cbe Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Thu, 2 Aug 2018 15:47:29 -0700 Subject: Change orderStates param name to remaingFillableMakerAssetAmounts --- packages/order-utils/test/market_utils_test.ts | 43 ++++++---------------- .../order-utils/test/utils/test_order_factory.ts | 32 ++-------------- 2 files changed, 14 insertions(+), 61 deletions(-) (limited to 'packages/order-utils/test') diff --git a/packages/order-utils/test/market_utils_test.ts b/packages/order-utils/test/market_utils_test.ts index 93779d035..ac3fb9b93 100644 --- a/packages/order-utils/test/market_utils_test.ts +++ b/packages/order-utils/test/market_utils_test.ts @@ -1,10 +1,8 @@ -import { OrderRelevantState, SignedOrder } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; -import * as _ from 'lodash'; import 'mocha'; -import { constants, marketUtils, orderFactory } from '../src'; +import { constants, marketUtils } from '../src'; import { chaiSetup } from './utils/chai_setup'; import { testOrderFactory } from './utils/test_order_factory'; @@ -37,19 +35,14 @@ describe('marketUtils', () => { }, testOrderCount, ); - // generate order states that cover the required fill amount - const inputOrderStates = testOrderFactory.generateTestOrderRelevantStates( - { - remainingFillableMakerAssetAmount: makerAssetAmount, - }, - testOrderCount, - ); + // generate remainingFillableMakerAssetAmounts that equal the makerAssetAmount + const remainingFillableMakerAssetAmounts = [makerAssetAmount, makerAssetAmount, makerAssetAmount]; it('returns input orders and zero remainingFillAmount when input exactly matches requested fill amount', async () => { // try to fill 30 units of makerAsset const fillAmount = new BigNumber(30); const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount( inputOrders, - inputOrderStates, + remainingFillableMakerAssetAmounts, fillAmount, ); expect(resultOrders).to.be.deep.equal(inputOrders); @@ -60,7 +53,7 @@ describe('marketUtils', () => { const fillAmount = new BigNumber(25); const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount( inputOrders, - inputOrderStates, + remainingFillableMakerAssetAmounts, fillAmount, ); expect(resultOrders).to.be.deep.equal(inputOrders); @@ -71,7 +64,7 @@ describe('marketUtils', () => { const fillAmount = new BigNumber(35); const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount( inputOrders, - inputOrderStates, + remainingFillableMakerAssetAmounts, fillAmount, ); expect(resultOrders).to.be.deep.equal(inputOrders); @@ -82,7 +75,7 @@ describe('marketUtils', () => { const fillAmount = new BigNumber(10); const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount( inputOrders, - inputOrderStates, + remainingFillableMakerAssetAmounts, fillAmount, ); expect(resultOrders).to.be.deep.equal([inputOrders[0]]); @@ -93,7 +86,7 @@ describe('marketUtils', () => { const fillAmount = new BigNumber(15); const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount( inputOrders, - inputOrderStates, + remainingFillableMakerAssetAmounts, fillAmount, ); expect(resultOrders).to.be.deep.equal([inputOrders[0], inputOrders[1]]); @@ -110,31 +103,17 @@ describe('marketUtils', () => { }, testOrderCount, ); - // generate order states that cover different scenarios + // generate remainingFillableMakerAssetAmounts that cover different partial fill scenarios // 1. order is completely filled already // 2. order is partially fillable // 3. order is completely fillable - const partialOrderStates: Array> = [ - { - remainingFillableMakerAssetAmount: constants.ZERO_AMOUNT, - }, - { - remainingFillableMakerAssetAmount: new BigNumber(5), - }, - { - remainingFillableMakerAssetAmount: makerAssetAmount, - }, - ]; - const inputOrderStates: OrderRelevantState[] = _.map( - partialOrderStates, - testOrderFactory.generateTestOrderRelevantState, - ); + const remainingFillableMakerAssetAmounts = [constants.ZERO_AMOUNT, new BigNumber(5), makerAssetAmount]; it('returns last 2 orders and non-zero remainingFillAmount when trying to fill original makerAssetAmounts', async () => { // try to fill 30 units of makerAsset const fillAmount = new BigNumber(30); const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount( inputOrders, - inputOrderStates, + remainingFillableMakerAssetAmounts, fillAmount, ); expect(resultOrders).to.be.deep.equal([inputOrders[1], inputOrders[2]]); diff --git a/packages/order-utils/test/utils/test_order_factory.ts b/packages/order-utils/test/utils/test_order_factory.ts index 2c5d8cf61..611e777ea 100644 --- a/packages/order-utils/test/utils/test_order_factory.ts +++ b/packages/order-utils/test/utils/test_order_factory.ts @@ -1,5 +1,4 @@ -import { Order, OrderRelevantState, SignedOrder } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; +import { Order, SignedOrder } from '@0xproject/types'; import * as _ from 'lodash'; import { constants, orderFactory } from '../../src'; @@ -21,43 +20,18 @@ const BASE_TEST_SIGNED_ORDER: SignedOrder = { ...BASE_TEST_ORDER, signature: constants.NULL_BYTES, }; -const BASE_TEST_ORDER_RELEVANT_STATE: OrderRelevantState = { - makerBalance: constants.ZERO_AMOUNT, - makerProxyAllowance: constants.ZERO_AMOUNT, - makerFeeBalance: constants.ZERO_AMOUNT, - makerFeeProxyAllowance: constants.ZERO_AMOUNT, - filledTakerAssetAmount: constants.ZERO_AMOUNT, - remainingFillableMakerAssetAmount: constants.ZERO_AMOUNT, - remainingFillableTakerAssetAmount: constants.ZERO_AMOUNT, -}; export const testOrderFactory = { generateTestSignedOrder(partialOrder: Partial): SignedOrder { return transformObject(BASE_TEST_SIGNED_ORDER, partialOrder); }, generateTestSignedOrders(partialOrder: Partial, numOrders: number): SignedOrder[] { - const baseTestOrders = generateArrayOfInput(BASE_TEST_SIGNED_ORDER, numOrders); - return transformObjects(baseTestOrders, partialOrder); - }, - generateTestOrderRelevantState(partialOrderRelevantState: Partial): OrderRelevantState { - return transformObject(BASE_TEST_ORDER_RELEVANT_STATE, partialOrderRelevantState); - }, - generateTestOrderRelevantStates( - partialOrderRelevantState: Partial, - numOrderStates: number, - ): OrderRelevantState[] { - const baseTestOrderStates = generateArrayOfInput(BASE_TEST_ORDER_RELEVANT_STATE, numOrderStates); - return transformObjects(baseTestOrderStates, partialOrderRelevantState); + const baseTestOrders = _.map(_.range(numOrders), () => BASE_TEST_SIGNED_ORDER); + return _.map(baseTestOrders, order => transformObject(order, partialOrder)); }, }; -function generateArrayOfInput(input: T, rangeLength: number): T[] { - return _.map(_.range(rangeLength), () => input); -} function transformObject(input: T, transformation: Partial): T { const copy = _.cloneDeep(input); return _.assign(copy, transformation); } -function transformObjects(inputs: T[], transformation: Partial): T[] { - return _.map(inputs, input => transformObject(input, transformation)); -} -- cgit From 8382161f7553539ed6f436be88df8672b00bf35e Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Sun, 5 Aug 2018 20:48:56 -0400 Subject: Add tests for findFeeOrdersThatCoverFeesForTargetOrders --- packages/order-utils/test/market_utils_test.ts | 162 ++++++++++++++++++++- .../order-utils/test/utils/test_order_factory.ts | 7 +- 2 files changed, 155 insertions(+), 14 deletions(-) (limited to 'packages/order-utils/test') diff --git a/packages/order-utils/test/market_utils_test.ts b/packages/order-utils/test/market_utils_test.ts index ac3fb9b93..03f86c581 100644 --- a/packages/order-utils/test/market_utils_test.ts +++ b/packages/order-utils/test/market_utils_test.ts @@ -12,7 +12,7 @@ const expect = chai.expect; // tslint:disable: no-unused-expression describe('marketUtils', () => { - describe.only('#findOrdersThatCoverMakerAssetFillAmount', () => { + describe('#findOrdersThatCoverMakerAssetFillAmount', () => { describe('no orders', () => { it('returns empty and unchanged remainingFillAmount', async () => { const fillAmount = new BigNumber(10); @@ -25,15 +25,14 @@ describe('marketUtils', () => { expect(remainingFillAmount).to.be.bignumber.equal(fillAmount); }); }); - describe('orders are all completely fillable', () => { + describe('orders are completely fillable', () => { // generate three signed orders each with 10 units of makerAsset, 30 total - const testOrderCount = 3; const makerAssetAmount = new BigNumber(10); const inputOrders = testOrderFactory.generateTestSignedOrders( { makerAssetAmount, }, - testOrderCount, + 3, ); // generate remainingFillableMakerAssetAmounts that equal the makerAssetAmount const remainingFillableMakerAssetAmounts = [makerAssetAmount, makerAssetAmount, makerAssetAmount]; @@ -95,20 +94,19 @@ describe('marketUtils', () => { }); describe('orders are partially fillable', () => { // generate three signed orders each with 10 units of makerAsset, 30 total - const testOrderCount = 3; const makerAssetAmount = new BigNumber(10); const inputOrders = testOrderFactory.generateTestSignedOrders( { makerAssetAmount, }, - testOrderCount, + 3, ); // generate remainingFillableMakerAssetAmounts that cover different partial fill scenarios // 1. order is completely filled already // 2. order is partially fillable // 3. order is completely fillable const remainingFillableMakerAssetAmounts = [constants.ZERO_AMOUNT, new BigNumber(5), makerAssetAmount]; - it('returns last 2 orders and non-zero remainingFillAmount when trying to fill original makerAssetAmounts', async () => { + it('returns last two orders and non-zero remainingFillAmount when trying to fill original makerAssetAmounts', async () => { // try to fill 30 units of makerAsset const fillAmount = new BigNumber(30); const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount( @@ -121,5 +119,153 @@ describe('marketUtils', () => { }); }); }); - describe('#findFeeOrdersThatCoverFeesForTargetOrders', () => {}); + describe('#findFeeOrdersThatCoverFeesForTargetOrders', () => { + // generate three signed fee orders each with 10 units of ZRX, 30 total + const zrxAmount = new BigNumber(10); + const inputFeeOrders = testOrderFactory.generateTestSignedOrders( + { + makerAssetAmount: zrxAmount, + }, + 3, + ); + // generate remainingFillableFeeAmounts that equal the zrxAmount + const remainingFillableFeeAmounts = [zrxAmount, zrxAmount, zrxAmount]; + describe('no target orders', () => { + it('returns empty and zero remainingFeeAmount', async () => { + const { resultOrders, remainingFeeAmount } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders( + [], + [], + inputFeeOrders, + remainingFillableFeeAmounts, + ); + expect(resultOrders).to.be.empty; + expect(remainingFeeAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT); + }); + }); + describe('no fee orders', () => { + // generate three signed orders each with 10 units of makerAsset, 30 total + // each signed order requires 10 units of takerFee + const makerAssetAmount = new BigNumber(10); + const takerFee = new BigNumber(10); + const inputOrders = testOrderFactory.generateTestSignedOrders( + { + makerAssetAmount, + takerFee, + }, + 3, + ); + // generate remainingFillableMakerAssetAmounts that equal the makerAssetAmount + const remainingFillableMakerAssetAmounts = [makerAssetAmount, makerAssetAmount, makerAssetAmount]; + it('returns empty and non-zero remainingFeeAmount', async () => { + const { resultOrders, remainingFeeAmount } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders( + inputOrders, + remainingFillableMakerAssetAmounts, + [], + [], + ); + expect(resultOrders).to.be.empty; + expect(remainingFeeAmount).to.be.bignumber.equal(new BigNumber(30)); + }); + }); + describe('target orders have no fees', () => { + // generate three signed orders each with 10 units of makerAsset, 30 total + const makerAssetAmount = new BigNumber(10); + const inputOrders = testOrderFactory.generateTestSignedOrders( + { + makerAssetAmount, + }, + 3, + ); + // generate remainingFillableMakerAssetAmounts that equal the makerAssetAmount + const remainingFillableMakerAssetAmounts = [makerAssetAmount, makerAssetAmount, makerAssetAmount]; + it('returns empty and zero remainingFeeAmount', async () => { + const { resultOrders, remainingFeeAmount } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders( + inputOrders, + remainingFillableMakerAssetAmounts, + inputFeeOrders, + remainingFillableFeeAmounts, + ); + expect(resultOrders).to.be.empty; + expect(remainingFeeAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT); + }); + }); + describe('target orders require fees and are completely fillable', () => { + // generate three signed orders each with 10 units of makerAsset, 30 total + // each signed order requires 10 units of takerFee + const makerAssetAmount = new BigNumber(10); + const takerFee = new BigNumber(10); + const inputOrders = testOrderFactory.generateTestSignedOrders( + { + makerAssetAmount, + takerFee, + }, + 3, + ); + // generate remainingFillableMakerAssetAmounts that equal the makerAssetAmount + const remainingFillableMakerAssetAmounts = [makerAssetAmount, makerAssetAmount, makerAssetAmount]; + it('returns input fee orders and zero remainingFeeAmount', async () => { + const { resultOrders, remainingFeeAmount } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders( + inputOrders, + remainingFillableMakerAssetAmounts, + inputFeeOrders, + remainingFillableFeeAmounts, + ); + expect(resultOrders).to.be.deep.equal(inputFeeOrders); + expect(remainingFeeAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT); + }); + }); + describe('target orders require fees and are partially fillable', () => { + // generate three signed orders each with 10 units of makerAsset, 30 total + // each signed order requires 10 units of takerFee + const makerAssetAmount = new BigNumber(10); + const takerFee = new BigNumber(10); + const inputOrders = testOrderFactory.generateTestSignedOrders( + { + makerAssetAmount, + takerFee, + }, + 3, + ); + // generate remainingFillableMakerAssetAmounts that cover different partial fill scenarios + // 1. order is completely filled already + // 2. order is partially fillable + // 3. order is completely fillable + const remainingFillableMakerAssetAmounts = [constants.ZERO_AMOUNT, new BigNumber(5), makerAssetAmount]; + it('returns first two input fee orders and zero remainingFeeAmount', async () => { + const { resultOrders, remainingFeeAmount } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders( + inputOrders, + remainingFillableMakerAssetAmounts, + inputFeeOrders, + remainingFillableFeeAmounts, + ); + expect(resultOrders).to.be.deep.equal([inputFeeOrders[0], inputFeeOrders[1]]); + expect(remainingFeeAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT); + }); + }); + describe('target orders require more fees than available', () => { + // generate three signed orders each with 10 units of makerAsset, 30 total + // each signed order requires 20 units of takerFee + const makerAssetAmount = new BigNumber(10); + const takerFee = new BigNumber(20); + const inputOrders = testOrderFactory.generateTestSignedOrders( + { + makerAssetAmount, + takerFee, + }, + 3, + ); + // generate remainingFillableMakerAssetAmounts that equal the makerAssetAmount + const remainingFillableMakerAssetAmounts = [makerAssetAmount, makerAssetAmount, makerAssetAmount]; + it('returns input fee orders and non-zero remainingFeeAmount', async () => { + const { resultOrders, remainingFeeAmount } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders( + inputOrders, + remainingFillableMakerAssetAmounts, + inputFeeOrders, + remainingFillableFeeAmounts, + ); + expect(resultOrders).to.be.deep.equal(inputFeeOrders); + expect(remainingFeeAmount).to.be.bignumber.equal(new BigNumber(30)); + }); + }); + }); }); diff --git a/packages/order-utils/test/utils/test_order_factory.ts b/packages/order-utils/test/utils/test_order_factory.ts index 611e777ea..75dc6f1f2 100644 --- a/packages/order-utils/test/utils/test_order_factory.ts +++ b/packages/order-utils/test/utils/test_order_factory.ts @@ -5,14 +5,9 @@ import { constants, orderFactory } from '../../src'; const BASE_TEST_ORDER: Order = orderFactory.createOrder( constants.NULL_ADDRESS, - constants.NULL_ADDRESS, - constants.NULL_ADDRESS, - constants.ZERO_AMOUNT, constants.ZERO_AMOUNT, + constants.NULL_ADDRESS, constants.ZERO_AMOUNT, - constants.NULL_BYTES, - constants.ZERO_AMOUNT, - constants.NULL_BYTES, constants.NULL_ADDRESS, constants.NULL_ADDRESS, ); -- cgit From 7d0bec9b2a9960390b0b3b19e5ed4d84a679669b Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Sun, 5 Aug 2018 20:54:29 -0400 Subject: Add some test cases that stress slippageBufferAmount param --- packages/order-utils/test/market_utils_test.ts | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'packages/order-utils/test') diff --git a/packages/order-utils/test/market_utils_test.ts b/packages/order-utils/test/market_utils_test.ts index 03f86c581..21c0a4802 100644 --- a/packages/order-utils/test/market_utils_test.ts +++ b/packages/order-utils/test/market_utils_test.ts @@ -37,34 +37,43 @@ describe('marketUtils', () => { // generate remainingFillableMakerAssetAmounts that equal the makerAssetAmount const remainingFillableMakerAssetAmounts = [makerAssetAmount, makerAssetAmount, makerAssetAmount]; it('returns input orders and zero remainingFillAmount when input exactly matches requested fill amount', async () => { - // try to fill 30 units of makerAsset - const fillAmount = new BigNumber(30); + // try to fill 20 units of makerAsset + // include 10 units of slippageBufferAmount + const fillAmount = new BigNumber(20); + const slippageBufferAmount = new BigNumber(10); const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount( inputOrders, remainingFillableMakerAssetAmounts, fillAmount, + slippageBufferAmount, ); expect(resultOrders).to.be.deep.equal(inputOrders); expect(remainingFillAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT); }); it('returns input orders and zero remainingFillAmount when input has more than requested fill amount', async () => { - // try to fill 25 units of makerAsset - const fillAmount = new BigNumber(25); + // try to fill 15 units of makerAsset + // include 10 units of slippageBufferAmount + const fillAmount = new BigNumber(15); + const slippageBufferAmount = new BigNumber(10); const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount( inputOrders, remainingFillableMakerAssetAmounts, fillAmount, + slippageBufferAmount, ); expect(resultOrders).to.be.deep.equal(inputOrders); expect(remainingFillAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT); }); it('returns input orders and non-zero remainingFillAmount when input has less than requested fill amount', async () => { - // try to fill 35 units of makerAsset - const fillAmount = new BigNumber(35); + // try to fill 30 units of makerAsset + // include 5 units of slippageBufferAmount + const fillAmount = new BigNumber(30); + const slippageBufferAmount = new BigNumber(5); const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount( inputOrders, remainingFillableMakerAssetAmounts, fillAmount, + slippageBufferAmount, ); expect(resultOrders).to.be.deep.equal(inputOrders); expect(remainingFillAmount).to.be.bignumber.equal(new BigNumber(5)); -- cgit From 6a5965d73bb542634631d7af76c150795d899744 Mon Sep 17 00:00:00 2001 From: Alex Browne Date: Thu, 26 Jul 2018 14:11:03 -0700 Subject: Add strictArgumentEncodingCheck to BaseContract and use it in contract templates --- packages/order-utils/test/signature_utils_test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'packages/order-utils/test') diff --git a/packages/order-utils/test/signature_utils_test.ts b/packages/order-utils/test/signature_utils_test.ts index 5714f9671..baae2b414 100644 --- a/packages/order-utils/test/signature_utils_test.ts +++ b/packages/order-utils/test/signature_utils_test.ts @@ -22,7 +22,8 @@ describe('Signature utils', () => { let address = '0x5409ed021d9299bf6814279a6a1411a7e866a631'; it("should return false if the data doesn't pertain to the signature & address", async () => { - expect(await isValidSignatureAsync(provider, '0x0', ethSignSignature, address)).to.be.false(); + const bytes32Zeros = '0x0000000000000000000000000000000000000000000000000000000000000000'; + expect(await isValidSignatureAsync(provider, bytes32Zeros, ethSignSignature, address)).to.be.false(); }); it("should return false if the address doesn't pertain to the signature & data", async () => { const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42'; -- cgit From 45e9fbe8f93f68f3786629fff1861b1a66b90635 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Tue, 31 Jul 2018 17:24:19 +0800 Subject: Introduce SignerProviderType This allows the developer to indicate the nuanced signer provider. Some have different implementations (trezor, ledger) and others have different implementations (metamask). Breaking the abstraction of eth_sign. EthSign assumes a spec compliant implementation and can be used as a default --- packages/order-utils/test/signature_utils_test.ts | 117 ++++++++++++++-------- 1 file changed, 78 insertions(+), 39 deletions(-) (limited to 'packages/order-utils/test') diff --git a/packages/order-utils/test/signature_utils_test.ts b/packages/order-utils/test/signature_utils_test.ts index baae2b414..179905b18 100644 --- a/packages/order-utils/test/signature_utils_test.ts +++ b/packages/order-utils/test/signature_utils_test.ts @@ -1,3 +1,4 @@ +import { SignerProviderType } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; import { JSONRPCErrorCallback, JSONRPCRequestPayload } from 'ethereum-types'; @@ -5,7 +6,7 @@ import * as _ from 'lodash'; import 'mocha'; import * as Sinon from 'sinon'; -import { ecSignOrderHashAsync, generatePseudoRandomSalt, MessagePrefixType } from '../src'; +import { ecSignOrderHashAsync, generatePseudoRandomSalt } from '../src'; import { isValidECSignature, isValidSignatureAsync } from '../src/signature_utils'; import { chaiSetup } from './utils/chai_setup'; @@ -119,32 +120,28 @@ describe('Signature utils', () => { _.each(stubs, s => s.restore()); stubs = []; }); - it('Should return the correct ECSignature', async () => { + it('Should return the correct Signature', async () => { const orderHash = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0'; - const expectedECSignature = { - v: 27, - r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33', - s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', - }; - const messagePrefixOpts = { - prefixType: MessagePrefixType.EthSign, - shouldAddPrefixBeforeCallingEthSign: false, - }; - const ecSignature = await ecSignOrderHashAsync(provider, orderHash, makerAddress, messagePrefixOpts); - expect(ecSignature).to.deep.equal(expectedECSignature); - }); - it('should return the correct ECSignature for signatureHex concatenated as R + S + V', async () => { + const expectedSignature = + '0x1b61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace225403'; + const ecSignature = await ecSignOrderHashAsync( + provider, + orderHash, + makerAddress, + SignerProviderType.EthSign, + ); + expect(ecSignature).to.equal(expectedSignature); + }); + it('should return the correct Signature for signatureHex concatenated as R + S + V', async () => { const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004'; - const expectedECSignature = { - v: 27, - r: '0x117902c86dfb95fe0d1badd983ee166ad259b27acb220174cbb4460d87287113', - s: '0x7feabdfe76e05924b484789f79af4ee7fa29ec006cedce1bbf369320d034e10b', - }; + const expectedSignature = + '0x1b117902c86dfb95fe0d1badd983ee166ad259b27acb220174cbb4460d872871137feabdfe76e05924b484789f79af4ee7fa29ec006cedce1bbf369320d034e10b03'; const fakeProvider = { async sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback): Promise { if (payload.method === 'eth_sign') { const [address, message] = payload.params; + expect(message).to.equal(orderHash); const signature = await web3Wrapper.signMessageAsync(address, message); // tslint:disable-next-line:custom-no-magic-numbers const rsvHex = `0x${signature.substr(130)}${signature.substr(2, 128)}`; @@ -158,21 +155,18 @@ describe('Signature utils', () => { } }, }; - - const messagePrefixOpts = { - prefixType: MessagePrefixType.EthSign, - shouldAddPrefixBeforeCallingEthSign: false, - }; - const ecSignature = await ecSignOrderHashAsync(fakeProvider, orderHash, makerAddress, messagePrefixOpts); - expect(ecSignature).to.deep.equal(expectedECSignature); - }); - it('should return the correct ECSignature for signatureHex concatenated as V + R + S', async () => { + const ecSignature = await ecSignOrderHashAsync( + fakeProvider, + orderHash, + makerAddress, + SignerProviderType.EthSign, + ); + expect(ecSignature).to.equal(expectedSignature); + }); + it('should return the correct Signature for signatureHex concatenated as V + R + S', async () => { const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004'; - const expectedECSignature = { - v: 27, - r: '0x117902c86dfb95fe0d1badd983ee166ad259b27acb220174cbb4460d87287113', - s: '0x7feabdfe76e05924b484789f79af4ee7fa29ec006cedce1bbf369320d034e10b', - }; + const expectedSignature = + '0x1b117902c86dfb95fe0d1badd983ee166ad259b27acb220174cbb4460d872871137feabdfe76e05924b484789f79af4ee7fa29ec006cedce1bbf369320d034e10b03'; const fakeProvider = { async sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback): Promise { if (payload.method === 'eth_sign') { @@ -189,12 +183,57 @@ describe('Signature utils', () => { }, }; - const messagePrefixOpts = { - prefixType: MessagePrefixType.EthSign, - shouldAddPrefixBeforeCallingEthSign: false, + const ecSignature = await ecSignOrderHashAsync( + fakeProvider, + orderHash, + makerAddress, + SignerProviderType.EthSign, + ); + expect(ecSignature).to.equal(expectedSignature); + }); + // Note this is due to a bug in Metamask where it does not prefix before signing, this is a known issue and is to be fixed in the future + it('should receive a payload modified with a prefix when Metamask is SignerProviderType', async () => { + const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004'; + const orderHashPrefixed = '0xae70f31d26096291aa681b26cb7574563956221d0b4213631e1ef9df675d4cba'; + const expectedSignature = + '0x1b117902c86dfb95fe0d1badd983ee166ad259b27acb220174cbb4460d872871137feabdfe76e05924b484789f79af4ee7fa29ec006cedce1bbf369320d034e10b03'; + const fakeProvider = { + async sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback): Promise { + if (payload.method === 'eth_sign') { + const [address, message] = payload.params; + expect(message).to.equal(orderHashPrefixed); + const signature = + '0x1b117902c86dfb95fe0d1badd983ee166ad259b27acb220174cbb4460d872871137feabdfe76e05924b484789f79af4ee7fa29ec006cedce1bbf369320d034e10b'; + callback(null, { + id: 42, + jsonrpc: '2.0', + result: signature, + }); + } else { + callback(null, { id: 42, jsonrpc: '2.0', result: [makerAddress] }); + } + }, }; - const ecSignature = await ecSignOrderHashAsync(fakeProvider, orderHash, makerAddress, messagePrefixOpts); - expect(ecSignature).to.deep.equal(expectedECSignature); + + const ecSignature = await ecSignOrderHashAsync( + fakeProvider, + orderHash, + makerAddress, + SignerProviderType.Metamask, + ); + expect(ecSignature).to.equal(expectedSignature); + }); + it('should return a valid signature', async () => { + const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004'; + const ecSignature = await ecSignOrderHashAsync( + provider, + orderHash, + makerAddress, + SignerProviderType.EthSign, + ); + + const isValidSignature = await isValidSignatureAsync(provider, orderHash, ecSignature, makerAddress); + expect(isValidSignature).to.be.true(); }); }); }); -- cgit From 9dd6ba78250d8bbde1d5023ce4ac4254884f4115 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Fri, 3 Aug 2018 11:35:03 +0800 Subject: Update jsdoc --- packages/order-utils/test/signature_utils_test.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'packages/order-utils/test') diff --git a/packages/order-utils/test/signature_utils_test.ts b/packages/order-utils/test/signature_utils_test.ts index 179905b18..de76e82ac 100644 --- a/packages/order-utils/test/signature_utils_test.ts +++ b/packages/order-utils/test/signature_utils_test.ts @@ -192,6 +192,7 @@ describe('Signature utils', () => { expect(ecSignature).to.equal(expectedSignature); }); // Note this is due to a bug in Metamask where it does not prefix before signing, this is a known issue and is to be fixed in the future + // Source: https://github.com/MetaMask/metamask-extension/commit/a9d36860bec424dcee8db043d3e7da6a5ff5672e it('should receive a payload modified with a prefix when Metamask is SignerProviderType', async () => { const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004'; const orderHashPrefixed = '0xae70f31d26096291aa681b26cb7574563956221d0b4213631e1ef9df675d4cba'; -- cgit From ca4905c3436931684d113ec66882836a4d0b265b Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Thu, 9 Aug 2018 12:24:52 +1000 Subject: Rename from SignerProviderType.EthSign to SignerType.Default --- packages/order-utils/test/signature_utils_test.ts | 87 +++++++++++++---------- 1 file changed, 50 insertions(+), 37 deletions(-) (limited to 'packages/order-utils/test') diff --git a/packages/order-utils/test/signature_utils_test.ts b/packages/order-utils/test/signature_utils_test.ts index de76e82ac..a25d2afd6 100644 --- a/packages/order-utils/test/signature_utils_test.ts +++ b/packages/order-utils/test/signature_utils_test.ts @@ -1,4 +1,4 @@ -import { SignerProviderType } from '@0xproject/types'; +import { SignerType } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; import { JSONRPCErrorCallback, JSONRPCRequestPayload } from 'ethereum-types'; @@ -7,7 +7,7 @@ import 'mocha'; import * as Sinon from 'sinon'; import { ecSignOrderHashAsync, generatePseudoRandomSalt } from '../src'; -import { isValidECSignature, isValidSignatureAsync } from '../src/signature_utils'; +import { convertECSignatureToSignatureHex, isValidECSignature, isValidSignatureAsync } from '../src/signature_utils'; import { chaiSetup } from './utils/chai_setup'; import { provider, web3Wrapper } from './utils/web3_wrapper'; @@ -124,12 +124,7 @@ describe('Signature utils', () => { const orderHash = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0'; const expectedSignature = '0x1b61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace225403'; - const ecSignature = await ecSignOrderHashAsync( - provider, - orderHash, - makerAddress, - SignerProviderType.EthSign, - ); + const ecSignature = await ecSignOrderHashAsync(provider, orderHash, makerAddress, SignerType.Default); expect(ecSignature).to.equal(expectedSignature); }); it('should return the correct Signature for signatureHex concatenated as R + S + V', async () => { @@ -155,12 +150,7 @@ describe('Signature utils', () => { } }, }; - const ecSignature = await ecSignOrderHashAsync( - fakeProvider, - orderHash, - makerAddress, - SignerProviderType.EthSign, - ); + const ecSignature = await ecSignOrderHashAsync(fakeProvider, orderHash, makerAddress, SignerType.Default); expect(ecSignature).to.equal(expectedSignature); }); it('should return the correct Signature for signatureHex concatenated as V + R + S', async () => { @@ -183,32 +173,28 @@ describe('Signature utils', () => { }, }; - const ecSignature = await ecSignOrderHashAsync( - fakeProvider, - orderHash, - makerAddress, - SignerProviderType.EthSign, - ); + const ecSignature = await ecSignOrderHashAsync(fakeProvider, orderHash, makerAddress, SignerType.Default); expect(ecSignature).to.equal(expectedSignature); }); // Note this is due to a bug in Metamask where it does not prefix before signing, this is a known issue and is to be fixed in the future // Source: https://github.com/MetaMask/metamask-extension/commit/a9d36860bec424dcee8db043d3e7da6a5ff5672e - it('should receive a payload modified with a prefix when Metamask is SignerProviderType', async () => { + it('should receive a payload modified with a prefix when Metamask is SignerType', async () => { const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004'; const orderHashPrefixed = '0xae70f31d26096291aa681b26cb7574563956221d0b4213631e1ef9df675d4cba'; const expectedSignature = '0x1b117902c86dfb95fe0d1badd983ee166ad259b27acb220174cbb4460d872871137feabdfe76e05924b484789f79af4ee7fa29ec006cedce1bbf369320d034e10b03'; + // Generated from a MM eth_sign request from 0x5409ed021d9299bf6814279a6a1411a7e866a631 signing 0xae70f31d26096291aa681b26cb7574563956221d0b4213631e1ef9df675d4cba + const metamaskSignature = + '0x117902c86dfb95fe0d1badd983ee166ad259b27acb220174cbb4460d872871137feabdfe76e05924b484789f79af4ee7fa29ec006cedce1bbf369320d034e10b1b'; const fakeProvider = { async sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback): Promise { if (payload.method === 'eth_sign') { - const [address, message] = payload.params; + const [, message] = payload.params; expect(message).to.equal(orderHashPrefixed); - const signature = - '0x1b117902c86dfb95fe0d1badd983ee166ad259b27acb220174cbb4460d872871137feabdfe76e05924b484789f79af4ee7fa29ec006cedce1bbf369320d034e10b'; callback(null, { id: 42, jsonrpc: '2.0', - result: signature, + result: metamaskSignature, }); } else { callback(null, { id: 42, jsonrpc: '2.0', result: [makerAddress] }); @@ -216,25 +202,52 @@ describe('Signature utils', () => { }, }; - const ecSignature = await ecSignOrderHashAsync( - fakeProvider, - orderHash, - makerAddress, - SignerProviderType.Metamask, - ); + const ecSignature = await ecSignOrderHashAsync(fakeProvider, orderHash, makerAddress, SignerType.Metamask); expect(ecSignature).to.equal(expectedSignature); }); it('should return a valid signature', async () => { const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004'; - const ecSignature = await ecSignOrderHashAsync( - provider, - orderHash, - makerAddress, - SignerProviderType.EthSign, - ); + const ecSignature = await ecSignOrderHashAsync(provider, orderHash, makerAddress, SignerType.Default); const isValidSignature = await isValidSignatureAsync(provider, orderHash, ecSignature, makerAddress); expect(isValidSignature).to.be.true(); }); }); + describe('#convertECSignatureToSignatureHex', () => { + const ecSignature: ECSignature = { + v: 27, + r: '0xaca7da997ad177f040240cdccf6905b71ab16b74434388c3a72f34fd25d64393', + s: '0x46b2bac274ff29b48b3ea6e2d04c1336eaceafda3c53ab483fc3ff12fac3ebf2', + }; + it('should concatenate v,r,s and append the Trezor signature type', async () => { + const expectedSignatureWithSignatureType = + '0x1baca7da997ad177f040240cdccf6905b71ab16b74434388c3a72f34fd25d6439346b2bac274ff29b48b3ea6e2d04c1336eaceafda3c53ab483fc3ff12fac3ebf208'; + const signatureWithSignatureType = convertECSignatureToSignatureHex(ecSignature, SignerType.Trezor); + expect(signatureWithSignatureType).to.equal(expectedSignatureWithSignatureType); + }); + it('should concatenate v,r,s and append the EthSign signature type when SignerType is Default', async () => { + const expectedSignatureWithSignatureType = + '0x1baca7da997ad177f040240cdccf6905b71ab16b74434388c3a72f34fd25d6439346b2bac274ff29b48b3ea6e2d04c1336eaceafda3c53ab483fc3ff12fac3ebf203'; + const signatureWithSignatureType = convertECSignatureToSignatureHex(ecSignature, SignerType.Default); + expect(signatureWithSignatureType).to.equal(expectedSignatureWithSignatureType); + }); + it('should concatenate v,r,s and append the EthSign signature type when SignerType is Ledger', async () => { + const expectedSignatureWithSignatureType = + '0x1baca7da997ad177f040240cdccf6905b71ab16b74434388c3a72f34fd25d6439346b2bac274ff29b48b3ea6e2d04c1336eaceafda3c53ab483fc3ff12fac3ebf203'; + const signatureWithSignatureType = convertECSignatureToSignatureHex(ecSignature, SignerType.Ledger); + expect(signatureWithSignatureType).to.equal(expectedSignatureWithSignatureType); + }); + it('should concatenate v,r,s and append the EthSign signature type when SignerType is Metamask', async () => { + const expectedSignatureWithSignatureType = + '0x1baca7da997ad177f040240cdccf6905b71ab16b74434388c3a72f34fd25d6439346b2bac274ff29b48b3ea6e2d04c1336eaceafda3c53ab483fc3ff12fac3ebf203'; + const signatureWithSignatureType = convertECSignatureToSignatureHex(ecSignature, SignerType.Metamask); + expect(signatureWithSignatureType).to.equal(expectedSignatureWithSignatureType); + }); + it('should throw if the SignerType is invalid', async () => { + const expectedMessage = 'Unrecognized SignerType: INVALID_SIGNER'; + expect(() => convertECSignatureToSignatureHex(ecSignature, 'INVALID_SIGNER' as SignerType)).to.throw( + expectedMessage, + ); + }); + }); }); -- cgit