Skip to content

Commit

Permalink
fix(reflect): Fix unable to reflect function property inside object
Browse files Browse the repository at this point in the history
  • Loading branch information
ktutnik committed Jan 12, 2023
1 parent c9bc774 commit 95324dc
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 8 deletions.
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -32,7 +32,7 @@
"@types/fs-extra": "^9.0.13",
"@types/jest": "^27.5.2",
"@types/hapi__joi": "^17.1.8",
"@types/jsonwebtoken": "^8.5.9",
"@types/jsonwebtoken": "^9.0.0",
"@types/koa-router": "^7.4.4",
"@types/rimraf": "^3.0.2",
"@types/supertest": "^2.0.12",
Expand All @@ -52,7 +52,7 @@
"fs-extra": "^10.1.0",
"get-port": "5.1.1",
"jest": "^27.5.1",
"jsonwebtoken": "^8.5.1",
"jsonwebtoken": "^9.0.0",
"koa-better-body": "^3.3.9",
"koa-router": "^10.1.1",
"lerna": "4.0.0",
Expand Down
17 changes: 13 additions & 4 deletions packages/reflect/src/parser.ts
Expand Up @@ -59,6 +59,7 @@ function getNamesFromAst(nodes: any[]) {
}

function refineCode(fn: Class | Function, functionOnly = false) {

// some code may detected as invalid code, so its need to be fixed before parsed by acorn
const code = fn.toString()

Expand All @@ -70,13 +71,21 @@ function refineCode(fn: Class | Function, functionOnly = false) {
if (code.search(/^class(\s*){\s*}/gm) > -1)
return "class DynamicClass {}"

// in case function inside object, it will cause error
// in case function property used in an object
// example
// const obj = { fn(par1) {} }
// const obj = { fn: function(par1) {} }
// reflect(obj.fn)
if (functionOnly && code.search(/^([A-z0-9]+)\s*\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)/gm) > -1)
return `function ${code}`;
// regex search for
if (functionOnly && code.search(/^(async\b\s*)?function\s*\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)\s*{/gm) > -1)
return code.replace("function", "function _")

// in case inline function
// const obj = { fn(par1) {} }
if (functionOnly && code.search(/^([A-z0-9]+)\s*\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)\s*(?!=>){/gm) > -1)
return `function ${code}`;

// in case inline async function
// const obj = { async fn(par1) {} }
if (functionOnly && code.search(/^async\s*([A-z0-9]+)\s*\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)/gm) > -1)
return code.replace("async", "async function")

Expand Down
76 changes: 76 additions & 0 deletions tests/behavior/reflect/__snapshots__/function.spec.ts.snap
Expand Up @@ -19,6 +19,25 @@ Object {
}
`;

exports[`Reflect function Should able to reflect async function property inside object 1`] = `
Object {
"kind": "Function",
"name": "fn",
"parameters": Array [
Object {
"decorators": Array [],
"fields": "par1",
"index": 0,
"kind": "Parameter",
"name": "par1",
"type": undefined,
"typeClassification": undefined,
},
],
"returnType": undefined,
}
`;

exports[`Reflect function Should able to reflect destructured parameter 1`] = `
Object {
"kind": "Function",
Expand Down Expand Up @@ -88,6 +107,63 @@ Object {
}
`;

exports[`Reflect function Should able to reflect function property inside object 1`] = `
Object {
"kind": "Function",
"name": "fn",
"parameters": Array [
Object {
"decorators": Array [],
"fields": "par1",
"index": 0,
"kind": "Parameter",
"name": "par1",
"type": undefined,
"typeClassification": undefined,
},
],
"returnType": undefined,
}
`;

exports[`Reflect function Should able to reflect lambda function inside object 1`] = `
Object {
"kind": "Function",
"name": "fn",
"parameters": Array [
Object {
"decorators": Array [],
"fields": "par1",
"index": 0,
"kind": "Parameter",
"name": "par1",
"type": undefined,
"typeClassification": undefined,
},
],
"returnType": undefined,
}
`;

exports[`Reflect function Should able to reflect lambda function inside object 2`] = `
Object {
"kind": "Function",
"name": "fn",
"parameters": Array [
Object {
"decorators": Array [],
"fields": "par1",
"index": 0,
"kind": "Parameter",
"name": "par1",
"type": undefined,
"typeClassification": undefined,
},
],
"returnType": undefined,
}
`;

exports[`Reflect function Should able to reflect rest parameter 1`] = `
Object {
"kind": "Function",
Expand Down
41 changes: 39 additions & 2 deletions tests/behavior/reflect/function.spec.ts
Expand Up @@ -29,19 +29,56 @@ describe("Reflect function", () => {

it("Should able to reflect function inside object", () => {
const obj = {
fn(par1:string) {}
fn(par1: string) { }
}
const meta = reflect(obj.fn)
expect(meta).toMatchSnapshot()
})

it("Should able to reflect async function inside object", () => {
const obj = {
async fn(par1:string) {}
async fn(par1: string) { }
}
const meta = reflect(obj.fn)
expect(meta).toMatchSnapshot()
})


it("Should able to reflect function property inside object", () => {
const obj = {
fn: function (par1: string) { }
}
const meta = reflect(obj.fn)
expect(meta).toMatchSnapshot()
})

it("Should able to reflect async function property inside object", () => {
const obj = {
fn: async function (par1: string) { }
}
const meta = reflect(obj.fn)
expect(meta).toMatchSnapshot()
})

it("Should able to reflect lambda function inside object", () => {
const obj = {
fn: (par1: number) => {
return par1
},
};
const metadata = reflect(obj.fn);
expect(metadata).toMatchSnapshot()
})

it("Should able to reflect lambda function inside object", () => {
const obj = {
fn: async (par1: number) => {
return par1
},
};
const metadata = reflect(obj.fn);
expect(metadata).toMatchSnapshot()
})
})

describe("Reflect lambda function", () => {
Expand Down

0 comments on commit 95324dc

Please sign in to comment.