From df5b2236d1c049966e04f5fcba2d3a1575d31d79 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Wed, 17 Apr 2024 10:47:19 +0200 Subject: [PATCH 1/5] fix(jmespath): preserve inheritance when introspecting methods --- packages/jmespath/src/Functions.ts | 9 ++++++-- packages/jmespath/tests/unit/index.test.ts | 27 +++++++++++++++++++--- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/packages/jmespath/src/Functions.ts b/packages/jmespath/src/Functions.ts index e16e0a4e8f..a96aa68676 100644 --- a/packages/jmespath/src/Functions.ts +++ b/packages/jmespath/src/Functions.ts @@ -48,7 +48,11 @@ import { arityCheck, typeCheck } from './utils.js'; * ``` */ class Functions { + /** + * A set of all the custom functions available in this and all child classes. + */ public methods: Set = new Set(); + /** * Get the absolute value of the provided number. * @@ -530,12 +534,13 @@ class Functions { public introspectMethods(scope?: Functions): Set { const prototype = Object.getPrototypeOf(this); - const ownName = prototype.constructor.name; const methods = new Set(); - if (ownName !== 'Functions') { + if (this instanceof Functions) { for (const method of prototype.introspectMethods(scope)) { methods.add(method); } + } else { + return methods; } // This block is executed for every class in the inheritance chain diff --git a/packages/jmespath/tests/unit/index.test.ts b/packages/jmespath/tests/unit/index.test.ts index a06f3328d2..5b9930e0e4 100644 --- a/packages/jmespath/tests/unit/index.test.ts +++ b/packages/jmespath/tests/unit/index.test.ts @@ -351,9 +351,6 @@ describe('Coverage tests', () => { it('uses the custom function extending the powertools custom functions', () => { // Prepare class CustomFunctions extends PowertoolsFunctions { - public constructor() { - super(); - } @PowertoolsFunctions.signature({ argumentsSpecs: [['string']], }) @@ -384,5 +381,29 @@ describe('Coverage tests', () => { // Assess expect(messages).toStrictEqual(['hello world']); }); + + it('correctly registers all the custom functions', () => { + // Prepare + class CustomFunctions extends PowertoolsFunctions { + @PowertoolsFunctions.signature({ + argumentsSpecs: [['string']], + }) + public funcDecodeBrotliCompression(value: string): string { + const encoded = fromBase64(value, 'base64'); + const uncompressed = brotliDecompressSync(encoded); + + return uncompressed.toString(); + } + } + + // Act + const customFunctions = new CustomFunctions(); + search('foo', {}, { customFunctions }); + + // Assess + expect(customFunctions.methods.size).toBeGreaterThan( + new PowertoolsFunctions().methods.size + ); + }); }); }); From 8b59813d26e4e0edda91bd1b465c4e69c4f44c4f Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Wed, 17 Apr 2024 11:03:02 +0200 Subject: [PATCH 2/5] docs: document method --- packages/jmespath/src/Functions.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/jmespath/src/Functions.ts b/packages/jmespath/src/Functions.ts index a96aa68676..972c649849 100644 --- a/packages/jmespath/src/Functions.ts +++ b/packages/jmespath/src/Functions.ts @@ -532,6 +532,23 @@ class Functions { return Object.values(arg); } + /** + * Lazily introspects the methods of the class instance and all child classes + * to get the names of the methods that correspond to JMESPath functions. + * + * This method is used to get the names of the custom functions that are available + * in the class instance and all child classes. The names of the functions are used + * to create the custom function map that is passed to the JMESPath search function. + * + * The method traverses the inheritance chain going from the leaf class to the root class + * and stops when it reaches the `Functions` class, which is the root class. + * + * In doing so, it collects the names of the methods that start with `func` and adds them + * to the `methods` set. Finally, when the recursion collects back to the current instance, + * it adds the collected methods to the `this.methods` set so that they can be accessed later. + * + * @param scope The scope of the class instance to introspect + */ public introspectMethods(scope?: Functions): Set { const prototype = Object.getPrototypeOf(this); const methods = new Set(); From 628441e2baec03c06964fe115d049973e7592a17 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Wed, 17 Apr 2024 11:40:29 +0200 Subject: [PATCH 3/5] chore: update test case --- packages/jmespath/tests/unit/index.test.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/jmespath/tests/unit/index.test.ts b/packages/jmespath/tests/unit/index.test.ts index 5b9930e0e4..6c61728c70 100644 --- a/packages/jmespath/tests/unit/index.test.ts +++ b/packages/jmespath/tests/unit/index.test.ts @@ -388,17 +388,14 @@ describe('Coverage tests', () => { @PowertoolsFunctions.signature({ argumentsSpecs: [['string']], }) - public funcDecodeBrotliCompression(value: string): string { - const encoded = fromBase64(value, 'base64'); - const uncompressed = brotliDecompressSync(encoded); - - return uncompressed.toString(); + public funcPassThrough(value: string): string { + return value } } // Act const customFunctions = new CustomFunctions(); - search('foo', {}, { customFunctions }); + search('pass_through(foo)', { foo: 1 }, { customFunctions }); // Assess expect(customFunctions.methods.size).toBeGreaterThan( From 2d3b01d9c1144bceb348b6f0c48ff45827782af5 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Wed, 17 Apr 2024 11:46:03 +0200 Subject: [PATCH 4/5] chore: formatting --- packages/jmespath/tests/unit/index.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jmespath/tests/unit/index.test.ts b/packages/jmespath/tests/unit/index.test.ts index 6c61728c70..5c77234df4 100644 --- a/packages/jmespath/tests/unit/index.test.ts +++ b/packages/jmespath/tests/unit/index.test.ts @@ -389,7 +389,7 @@ describe('Coverage tests', () => { argumentsSpecs: [['string']], }) public funcPassThrough(value: string): string { - return value + return value; } } From 70f2ee757914b3746a119ad9cb4ce8952ef254d2 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Wed, 17 Apr 2024 11:50:11 +0200 Subject: [PATCH 5/5] chore: fix test --- packages/jmespath/tests/unit/index.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jmespath/tests/unit/index.test.ts b/packages/jmespath/tests/unit/index.test.ts index 5c77234df4..a8cb33201c 100644 --- a/packages/jmespath/tests/unit/index.test.ts +++ b/packages/jmespath/tests/unit/index.test.ts @@ -395,7 +395,7 @@ describe('Coverage tests', () => { // Act const customFunctions = new CustomFunctions(); - search('pass_through(foo)', { foo: 1 }, { customFunctions }); + search('pass_through(foo)', { foo: 'bar' }, { customFunctions }); // Assess expect(customFunctions.methods.size).toBeGreaterThan(