diff options
author | Leonid <logvinov.leon@gmail.com> | 2017-06-10 18:23:34 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-10 18:23:34 +0800 |
commit | b739ae24944876c28a2ff474993e72a7178b3d1b (patch) | |
tree | 5e176f2208a97471d83ad0e1ffbc9980e25cdd24 | |
parent | 1460966d8f03e5ec0012b21d4c4614c4c3ec44bc (diff) | |
parent | 823134b3bf24c93bd470a1de65bd39adaf554f73 (diff) | |
download | dexon-sol-tools-b739ae24944876c28a2ff474993e72a7178b3d1b.tar.gz dexon-sol-tools-b739ae24944876c28a2ff474993e72a7178b3d1b.tar.zst dexon-sol-tools-b739ae24944876c28a2ff474993e72a7178b3d1b.zip |
Merge pull request #52 from 0xProject/json-schema
Convert to JSON schema compatible object by default
-rw-r--r-- | src/0x.js.ts | 3 | ||||
-rw-r--r-- | src/contract_wrappers/exchange_wrapper.ts | 47 | ||||
-rw-r--r-- | src/utils/schema_validator.ts | 16 | ||||
-rw-r--r-- | test/schema_test.ts | 3 |
4 files changed, 24 insertions, 45 deletions
diff --git a/src/0x.js.ts b/src/0x.js.ts index 01820d075..143ad8e1f 100644 --- a/src/0x.js.ts +++ b/src/0x.js.ts @@ -128,8 +128,7 @@ export class ZeroEx { * Computes the orderHash for a given order and returns it as a hex encoded string. */ public async getOrderHashHexAsync(order: Order|SignedOrder): Promise<string> { - assert.doesConformToSchema('order', SchemaValidator.convertToJSONSchemaCompatibleObject(order as object), - orderSchema); + assert.doesConformToSchema('order', order, orderSchema); const exchangeContractAddr = await this.getExchangeAddressAsync(); const orderHashHex = utils.getOrderHashHex(order, exchangeContractAddr); diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index 214a19df9..65a873a9f 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -33,7 +33,6 @@ import {orderFillRequestsSchema} from '../schemas/order_fill_requests_schema'; import {orderCancellationRequestsSchema} from '../schemas/order_cancel_schema'; import {orderFillOrKillRequestsSchema} from '../schemas/order_fill_or_kill_requests_schema'; import {signedOrderSchema, orderSchema} from '../schemas/order_schemas'; -import {SchemaValidator} from '../utils/schema_validator'; import {constants} from '../utils/constants'; import {TokenWrapper} from './token_wrapper'; @@ -124,9 +123,7 @@ export class ExchangeWrapper extends ContractWrapper { */ public async fillOrderAsync(signedOrder: SignedOrder, takerTokenFillAmount: BigNumber.BigNumber, shouldCheckTransfer: boolean, takerAddress: string): Promise<void> { - assert.doesConformToSchema('signedOrder', - SchemaValidator.convertToJSONSchemaCompatibleObject(signedOrder as object), - signedOrderSchema); + assert.doesConformToSchema('signedOrder', signedOrder, signedOrderSchema); assert.isBigNumber('takerTokenFillAmount', takerTokenFillAmount); assert.isBoolean('shouldCheckTransfer', shouldCheckTransfer); await assert.isSenderAddressAsync('takerAddress', takerAddress, this.web3Wrapper); @@ -175,15 +172,12 @@ export class ExchangeWrapper extends ContractWrapper { ExchangeContractErrs.MULTIPLE_TAKER_TOKENS_IN_FILL_UP_TO_DISALLOWED); assert.isBigNumber('takerTokenFillAmount', takerTokenFillAmount); assert.isBoolean('shouldCheckTransfer', shouldCheckTransfer); - assert.doesConformToSchema( - 'signedOrders', SchemaValidator.convertToJSONSchemaCompatibleObject(signedOrders), signedOrdersSchema - ); + assert.doesConformToSchema('signedOrders', signedOrders, signedOrdersSchema); await assert.isSenderAddressAsync('takerAddress', takerAddress, this.web3Wrapper); - _.forEach(signedOrders, - async (signedOrder: SignedOrder, i: number) => { - await this.validateFillOrderAndThrowIfInvalidAsync( - signedOrder, takerTokenFillAmount, takerAddress); - }); + for (const signedOrder of signedOrders) { + await this.validateFillOrderAndThrowIfInvalidAsync( + signedOrder, takerTokenFillAmount, takerAddress); + } if (_.isEmpty(signedOrders)) { return; // no-op } @@ -239,13 +233,11 @@ export class ExchangeWrapper extends ContractWrapper { shouldCheckTransfer: boolean, takerAddress: string): Promise<void> { assert.isBoolean('shouldCheckTransfer', shouldCheckTransfer); await assert.isSenderAddressAsync('takerAddress', takerAddress, this.web3Wrapper); - assert.doesConformToSchema('orderFillRequests', - SchemaValidator.convertToJSONSchemaCompatibleObject(orderFillRequests as object), - orderFillRequestsSchema); - _.forEach(orderFillRequests, async (orderFillRequest: OrderFillRequest) => { + assert.doesConformToSchema('orderFillRequests', orderFillRequests, orderFillRequestsSchema); + for (const orderFillRequest of orderFillRequests) { await this.validateFillOrderAndThrowIfInvalidAsync( orderFillRequest.signedOrder, orderFillRequest.takerTokenFillAmount, takerAddress); - }); + } if (_.isEmpty(orderFillRequests)) { return; // no-op } @@ -298,9 +290,7 @@ export class ExchangeWrapper extends ContractWrapper { */ public async fillOrKillOrderAsync(signedOrder: SignedOrder, fillTakerAmount: BigNumber.BigNumber, takerAddress: string) { - assert.doesConformToSchema('signedOrder', - SchemaValidator.convertToJSONSchemaCompatibleObject(signedOrder as object), - signedOrderSchema); + assert.doesConformToSchema('signedOrder', signedOrder, signedOrderSchema); assert.isBigNumber('fillTakerAmount', fillTakerAmount); await assert.isSenderAddressAsync('takerAddress', takerAddress, this.web3Wrapper); @@ -344,10 +334,7 @@ export class ExchangeWrapper extends ContractWrapper { public async batchFillOrKillAsync(orderFillOrKillRequests: OrderFillOrKillRequest[], takerAddress: string) { await assert.isSenderAddressAsync('takerAddress', takerAddress, this.web3Wrapper); - assert.doesConformToSchema('orderFillOrKillRequests', - SchemaValidator.convertToJSONSchemaCompatibleObject(orderFillOrKillRequests), - orderFillOrKillRequestsSchema, - ); + assert.doesConformToSchema('orderFillOrKillRequests', orderFillOrKillRequests, orderFillOrKillRequestsSchema); const exchangeInstance = await this.getExchangeContractAsync(); for (const request of orderFillOrKillRequests) { await this.validateFillOrKillOrderAndThrowIfInvalidAsync(request.signedOrder, exchangeInstance.address, @@ -398,9 +385,7 @@ export class ExchangeWrapper extends ContractWrapper { */ public async cancelOrderAsync( order: Order|SignedOrder, takerTokenCancelAmount: BigNumber.BigNumber): Promise<void> { - assert.doesConformToSchema('order', - SchemaValidator.convertToJSONSchemaCompatibleObject(order), - orderSchema); + assert.doesConformToSchema('order', order, orderSchema); assert.isBigNumber('takerTokenCancelAmount', takerTokenCancelAmount); await assert.isSenderAddressAsync('order.maker', order.maker, this.web3Wrapper); @@ -436,14 +421,12 @@ export class ExchangeWrapper extends ContractWrapper { assert.hasAtMostOneUniqueValue(makers, ExchangeContractErrs.MULTIPLE_MAKERS_IN_SINGLE_CANCEL_BATCH_DISALLOWED); const maker = makers[0]; await assert.isSenderAddressAsync('maker', maker, this.web3Wrapper); - assert.doesConformToSchema('orderCancellationRequests', - SchemaValidator.convertToJSONSchemaCompatibleObject(orderCancellationRequests), - orderCancellationRequestsSchema); - _.forEach(orderCancellationRequests, async (cancellationRequest: OrderCancellationRequest) => { + assert.doesConformToSchema('orderCancellationRequests', orderCancellationRequests, orderCancellationRequestsSchema); + for (const cancellationRequest of orderCancellationRequests) { await this.validateCancelOrderAndThrowIfInvalidAsync( cancellationRequest.order, cancellationRequest.takerTokenCancelAmount, ); - }); + } if (_.isEmpty(orderCancellationRequests)) { return; // no-op } diff --git a/src/utils/schema_validator.ts b/src/utils/schema_validator.ts index 755f6e715..9097dce88 100644 --- a/src/utils/schema_validator.ts +++ b/src/utils/schema_validator.ts @@ -7,13 +7,6 @@ import {orderFillOrKillRequestsSchema} from '../schemas/order_fill_or_kill_reque export class SchemaValidator { private validator: Validator; - // In order to validate a complex JS object using jsonschema, we must replace any complex - // sub-types (e.g BigNumber) with a simpler string representation. Since BigNumber and other - // complex types implement the `toString` method, we can stringify the object and - // then parse it. The resultant object can then be checked using jsonschema. - public static convertToJSONSchemaCompatibleObject(obj: any): any { - return JSON.parse(JSON.stringify(obj)); - } constructor() { this.validator = new Validator(); this.validator.addSchema(tokenSchema, tokenSchema.id); @@ -25,7 +18,12 @@ export class SchemaValidator { this.validator.addSchema(ecSignatureParameterSchema, ecSignatureParameterSchema.id); this.validator.addSchema(orderFillOrKillRequestsSchema, orderFillOrKillRequestsSchema.id); } - public validate(instance: object, schema: Schema): ValidatorResult { - return this.validator.validate(instance, schema); + // In order to validate a complex JS object using jsonschema, we must replace any complex + // sub-types (e.g BigNumber) with a simpler string representation. Since BigNumber and other + // complex types implement the `toString` method, we can stringify the object and + // then parse it. The resultant object can then be checked using jsonschema. + public validate(instance: any, schema: Schema): ValidatorResult { + const jsonSchemaCompatibleObject = JSON.parse(JSON.stringify(instance)); + return this.validator.validate(jsonSchemaCompatibleObject, schema); } } diff --git a/test/schema_test.ts b/test/schema_test.ts index 376ac5d6f..b251a68f9 100644 --- a/test/schema_test.ts +++ b/test/schema_test.ts @@ -286,8 +286,7 @@ describe('Schema', () => { '.3': '0.3', }; _.forEach(testCases, (serialized: string, input: string) => { - expect(SchemaValidator.convertToJSONSchemaCompatibleObject(new BigNumber(input))) - .to.be.equal(serialized); + expect(JSON.parse(JSON.stringify(new BigNumber(input)))).to.be.equal(serialized); }); }); }); |