11// SPDX-License-Identifier: Apache-2.0
2- // import {
3- // JSONSchemaObject,
4- // MethodObject,
5- // MethodOrReference,
6- // OpenrpcDocument,
7- // } from '@open-rpc/meta-schema';
8- // import { parseOpenRPCDocument } from '@open-rpc/schema-utils-js';
9- // import { expect } from 'chai';
2+ import { JSONSchemaObject , MethodObject , MethodOrReference , OpenrpcDocument } from '@open-rpc/meta-schema' ;
3+ import { parseOpenRPCDocument } from '@open-rpc/schema-utils-js' ;
4+ import { expect } from 'chai' ;
105import fs from 'fs' ;
116import path from 'path' ;
7+ import WebSocket from 'ws' ;
128
13- // import WebSocket from 'ws';
149import openRpcData from '../../../../docs/openrpc.json' ;
15- // import CallerContract from '../contracts/Caller.json';
16- // import LogsContract from '../contracts/Logs.json';
10+ import CallerContract from '../contracts/Caller.json' ;
11+ import LogsContract from '../contracts/Logs.json' ;
1712import {
1813 chainId ,
1914 gasLimit ,
@@ -26,9 +21,9 @@ import {
2621 setTransaction1559_2930AndBlockHash ,
2722 setTransaction1559AndBlockHash ,
2823 setTransaction2930AndBlockHash ,
29- // WS_RELAY_URL,
24+ WS_RELAY_URL ,
3025} from './data/conformity/utils/constants' ;
31- // import { TestCases, UpdateParamFunction } from './data/conformity/utils/interfaces';
26+ import { TestCase , TestCases , UpdateParamFunction } from './data/conformity/utils/interfaces' ;
3227import { processFileContent , splitReqAndRes } from './data/conformity/utils/processors' ;
3328import {
3429 createContractLegacyTransaction ,
@@ -37,53 +32,74 @@ import {
3732 transaction1559_2930 ,
3833 transaction2930 ,
3934} from './data/conformity/utils/transactions' ;
40- import {
41- getLatestBlockHash ,
42- // sendRequestToRelay,
43- signAndSendRawTransaction ,
44- } from './data/conformity/utils/utils' ;
45- // import { hasResponseFormatIssues, isResponseValid } from './data/conformity/utils/validations';
35+ import { getLatestBlockHash , sendRequestToRelay , signAndSendRawTransaction } from './data/conformity/utils/utils' ;
36+ import { getMissingKeys , isResponseValid } from './data/conformity/utils/validations' ;
4637
4738const directoryPath = path . resolve ( __dirname , '../../../../node_modules/execution-apis/tests' ) ;
4839const overwritesDirectoryPath = path . resolve ( __dirname , 'data/conformity/overwrites' ) ;
4940
50- // let relayOpenRpcData: OpenrpcDocument;
51- // (async () => {
52- // relayOpenRpcData = await parseOpenRPCDocument(JSON.stringify(openRpcData));
53- // })().catch((error) => console.error('Error parsing OpenRPC document:', error));
54-
55- // const synthesizeTestCases = function (testCases: TestCases, updateParamIfNeeded: UpdateParamFunction) {
56- // for (const testName in testCases) {
57- // it(`${testName}`, async function () {
58- // const isErrorStatusExpected: boolean =
59- // (testCases[testName]?.status && testCases[testName].status != 200) ||
60- // !!JSON.parse(testCases[testName].response).error;
61- // const method = relayOpenRpcData.methods.find(
62- // (m: MethodOrReference): m is MethodObject => 'name' in m && m.name === testName.split(' ')[0],
63- // );
64- // const schema: JSONSchemaObject | undefined =
65- // method?.result && 'schema' in method.result && typeof method.result.schema === 'object'
66- // ? method.result.schema
67- // : undefined;
68- // try {
69- // const req = updateParamIfNeeded(testName, JSON.parse(testCases[testName].request));
70- // const res = await sendRequestToRelay(RELAY_URL, req, false);
71- // const isResFormatInvalid: boolean = hasResponseFormatIssues(res, JSON.parse(testCases[testName].response));
72- //
73- // if (schema && schema.pattern) {
74- // const check = isResponseValid(schema, res);
75- // expect(check).to.be.true;
76- // }
77- //
78- // expect(isResFormatInvalid).to.be.false;
79- // expect(isErrorStatusExpected).to.be.false;
80- // } catch (e: any) {
81- // expect(isErrorStatusExpected).to.be.true;
82- // expect(e?.response?.status).to.equal(testCases[testName].status);
83- // }
84- // });
85- // }
86- // };
41+ let relayOpenRpcData : OpenrpcDocument ;
42+ ( async ( ) => {
43+ relayOpenRpcData = await parseOpenRPCDocument ( JSON . stringify ( openRpcData ) ) ;
44+ } ) ( ) . catch ( ( error ) => console . error ( 'Error parsing OpenRPC document:' , error ) ) ;
45+
46+ /**
47+ * Determines whether a given test case is expected to return an error response.
48+ *
49+ * @param testCase - The test case to evaluate.
50+ * @returns {boolean } `true` if an error response is expected, otherwise `false`.
51+ *
52+ * @example
53+ * ```typescript
54+ * const tc = { status: 404, response: '{"error": "Not found"}' };
55+ * console.log(isErrorResponseExpected(tc)); // true
56+ * ```
57+ */
58+ const isErrorResponseExpected = function ( testCase : TestCase ) : boolean {
59+ return ( testCase ?. status && testCase . status != 200 ) || ! ! JSON . parse ( testCase . response ) . error ;
60+ } ;
61+
62+ /**
63+ * Retrieves the JSON schema object for the result of a given method name from the OpenRPC data.
64+ *
65+ * @param name - The name of the method to look up.
66+ * @returns {JSONSchemaObject | undefined } The method's result schema, or `undefined` if not found or invalid.
67+ *
68+ * @example
69+ * ```typescript
70+ * const schema = getMethodSchema("eth_getBalance");
71+ * console.log(schema); // JSON schema object or undefined
72+ * ```
73+ */
74+ const getMethodSchema = function ( name : string ) : JSONSchemaObject | undefined {
75+ const method = relayOpenRpcData . methods . find (
76+ ( m : MethodOrReference ) : m is MethodObject => 'name' in m && m . name === name ,
77+ ) ;
78+ return method ?. result && 'schema' in method . result && typeof method . result . schema === 'object'
79+ ? method . result . schema
80+ : undefined ;
81+ } ;
82+
83+ const synthesizeTestCases = function ( testCases : TestCases , updateParamIfNeeded : UpdateParamFunction ) {
84+ for ( const testName in testCases ) {
85+ it ( `${ testName } ` , async function ( ) {
86+ const isErrorStatusExpected = isErrorResponseExpected ( testCases [ testName ] ) ;
87+ const schema = getMethodSchema ( testName . split ( ' ' ) [ 0 ] ) ;
88+ try {
89+ const req = updateParamIfNeeded ( testName , JSON . parse ( testCases [ testName ] . request ) ) ;
90+ const res = await sendRequestToRelay ( RELAY_URL , req , false ) ;
91+ if ( schema && schema . pattern ) {
92+ const check = isResponseValid ( schema , res ) ;
93+ expect ( check ) . to . be . true ;
94+ }
95+ expect ( isErrorStatusExpected ) . to . be . false ;
96+ } catch ( e : any ) {
97+ expect ( isErrorStatusExpected ) . to . be . true ;
98+ expect ( e ?. response ?. status ) . to . equal ( testCases [ testName ] . status ) ;
99+ }
100+ } ) ;
101+ }
102+ } ;
87103
88104/**
89105 * To run the Ethereum Execution API tests as defined in the repository ethereum/execution-apis, it’s necessary
@@ -152,7 +168,7 @@ describe('@api-conformity', async function () {
152168 //
153169 // These test suites must be un-skipped. The code requires refactoring to resolve the
154170 // static analysis issues before they can be re-enabled.
155- /* describe.skip ('@conformity-batch-2 Ethereum execution apis tests', async function () {
171+ describe ( '@conformity-batch-2 Ethereum execution apis tests' , async function ( ) {
156172 this . timeout ( 240 * 1000 ) ;
157173
158174 let existingBlockFilter : string ;
@@ -222,7 +238,7 @@ describe('@api-conformity', async function () {
222238 synthesizeTestCases ( TEST_CASES_BATCH_2 , updateParamIfNeeded ) ;
223239 } ) ;
224240
225- describe.skip ('@conformity-batch-3 Ethereum execution apis tests', async function () {
241+ describe ( '@conformity-batch-3 Ethereum execution apis tests' , async function ( ) {
226242 this . timeout ( 240 * 1000 ) ;
227243
228244 let txHash : any ;
@@ -333,7 +349,12 @@ describe('@api-conformity', async function () {
333349 } ) ;
334350 await new Promise ( ( r ) => setTimeout ( r , 500 ) ) ;
335351
336- const hasMissingKeys: boolean = hasResponseFormatIssues(response, JSON.parse(testCases[testName].response));
352+ const hasMissingKeys =
353+ getMissingKeys ( {
354+ actual : response ,
355+ expected : JSON . parse ( testCases [ testName ] . response ) ,
356+ wildcards : [ ] ,
357+ } ) . length > 0 ;
337358 expect ( hasMissingKeys ) . to . be . false ;
338359 } ) ;
339360 }
@@ -343,7 +364,7 @@ describe('@api-conformity', async function () {
343364 } ) ;
344365 } ) ;
345366
346- describe.skip ('@conformity-batch-4 Ethereum execution apis tests', async function () {
367+ describe ( '@conformity-batch-4 Ethereum execution apis tests' , async function ( ) {
347368 this . timeout ( 240 * 1000 ) ;
348369
349370 let existingCallerContractAddress : string | null ;
@@ -543,12 +564,12 @@ describe('@api-conformity', async function () {
543564 synthesizeTestCases ( TEST_CASES_BATCH_4 , updateParamIfNeeded ) ;
544565 } ) ;
545566
546- describe.skip ('@conformity-batch-5 Ethereum execution apis tests', async function () {
567+ describe ( '@conformity-batch-5 Ethereum execution apis tests' , async function ( ) {
547568 this . timeout ( 240 * 1000 ) ;
548569 // eslint-disable-next-line @typescript-eslint/no-var-requires
549570 const TEST_CASES_BATCH_5 = require ( './data/conformity-tests-batch-5.json' ) ;
550571
551572 const updateParamIfNeeded = ( _testName : any , request : any ) => request ;
552573 synthesizeTestCases ( TEST_CASES_BATCH_5 , updateParamIfNeeded ) ;
553- });*/
574+ } ) ;
554575} ) ;
0 commit comments