Skip to content

Commit

Permalink
feat(cactus-common): add Objects utility class to get owned and inher…
Browse files Browse the repository at this point in the history
…ited methods of class instance

Signed-off-by: Peter Somogyvari <peter.somogyvari@accenture.com>
  • Loading branch information
petermetz committed May 19, 2020
1 parent 195d759 commit 2299cff
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 0 deletions.
65 changes: 65 additions & 0 deletions packages/cactus-common/src/main/typescript/objects.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* Utility class responsible for common and tedious tasks involving Javascript objects (instances of classes).
*/
export class Objects {
/**
* Returns a list of methods for an instance, including the inherited ones.
* Example:
*
* ```javascript
* class Base {
* constructor() {
* }
* getX() {
* return 'x';
* }
* }
*
* class A extends Base {
* getA() {
* return 'a';
* }
* }
*
* const a = new A();
* const methodNames = Objects.getAllMethodNames(a);
* console.log(methodNames);
* // [ 'getA', 'getX' ]
* ```
*
* @param anObject
*/
public static getAllMethodNames(anObject: any): string[] {
let properties: string[] = [];
do {
const symbols = Object.getOwnPropertySymbols(anObject);
const symbolPropertyNames = symbols.map((aSymbol) => aSymbol.toString());

const propertyNamesCurrent = Object.getOwnPropertyNames(anObject)
.concat(symbolPropertyNames)
.sort()
.filter((propertyName: string, index: number, arr) => {
return (
typeof anObject[propertyName] === "function" &&
propertyName !== "constructor" &&
(index === 0 || propertyName !== arr[index - 1]) &&
properties.indexOf(propertyName) === -1
);
});

properties = properties.concat(propertyNamesCurrent);
anObject = Object.getPrototypeOf(anObject);
} while (anObject && Object.getPrototypeOf(anObject));
return properties;
}

public static getAllFieldNames(anObject: any): string[] {
const allFieldNames = [];
for (const propertyKey in anObject) {
if (anObject.hasOwnProperty(propertyKey)) {
allFieldNames.push(propertyKey);
}
}
return allFieldNames;
}
}
1 change: 1 addition & 0 deletions packages/cactus-common/src/main/typescript/public-api.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { LoggerProvider } from "./logging/logger-provider";
export { Logger, ILoggerOptions } from "./logging/logger";
export { LogLevelDesc } from "loglevel";
export { Objects } from "./objects";
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// tslint:disable: max-classes-per-file
// tslint:disable-next-line: no-var-requires
const tap = require("tap");
import { Objects } from "../../../../main/typescript/public-api";

class Base {
private readonly y: string;

constructor() {
this.y = "y";
}

getX() {
return "x";
}
}

class A extends Base {
private readonly b: string;

constructor() {
super();
this.b = "b";
}

getA() {
return "a";
}
}

tap.test("handles inheritance correctly", (assert: any) => {
const a = new A();
const methodNames = Objects.getAllMethodNames(a);
assert.ok(Array.isArray(methodNames), "expect an arran of strings returned");
assert.ok(
methodNames.length === 2,
"expect two items in said array of strings"
);
assert.ok(
methodNames.includes("getX"),
'expect "getX" in said array of strings'
);
assert.ok(
methodNames.includes("getA"),
'expect "getA" in said array of strings'
);
assert.end();
});

0 comments on commit 2299cff

Please sign in to comment.