typemoq
Version:
A simple mocking library for TypeScript
89 lines (66 loc) • 3.12 kB
text/typescript
import * as _ from "lodash";
import { PropDescriptor } from "./PropDescriptor";
export class PropertyRetriever {
static getOwnEnumerables(obj: any) {
return this._getPropertyNames(obj, true, false, this._enumerable);
// Or could use for..in filtered with hasOwnProperty or just this: return Object.keys(obj);
}
static getOwnNonenumerables(obj: any) {
return this._getPropertyNames(obj, true, false, this._notEnumerable);
}
static getOwnEnumerablesAndNonenumerables(obj: any) {
return this._getPropertyNames(obj, true, false, this._enumerableAndNotEnumerable);
// Or just use: return Object.getOwnPropertyNames(obj);
}
static getPrototypeEnumerables(obj: any) {
return this._getPropertyNames(obj, false, true, this._enumerable);
}
static getPrototypeNonenumerables(obj: any) {
return this._getPropertyNames(obj, false, true, this._notEnumerable);
}
static getPrototypeEnumerablesAndNonenumerables(obj: any) {
return this._getPropertyNames(obj, false, true, this._enumerableAndNotEnumerable);
}
static getOwnAndPrototypeEnumerables(obj: any) {
return this._getPropertyNames(obj, true, true, this._enumerable);
// Or could use unfiltered for..in
}
static getOwnAndPrototypeNonenumerables(obj: any) {
return this._getPropertyNames(obj, true, true, this._notEnumerable);
}
static getOwnAndPrototypeEnumerablesAndNonenumerables(obj: any) {
return this._getPropertyNames(obj, true, true, this._enumerableAndNotEnumerable);
}
// Private static property checker callbacks
private static _enumerable(obj: any, prop: any): boolean {
return obj.propertyIsEnumerable(prop);
}
private static _notEnumerable(obj: any, prop: any): boolean {
return !obj.propertyIsEnumerable(prop);
}
private static _enumerableAndNotEnumerable(obj: any, prop: any): boolean {
return true;
}
private static _getPropertyNames(
obj: any, iterateSelfBool: boolean, iteratePrototypeBool: boolean, includePropCb: (obj: any, prop: any) => boolean):
Array<{ name: string; desc: PropDescriptor }> {
let result: Array<{ name: string; desc: PropDescriptor }> = [];
do {
if (iterateSelfBool) {
let props = Object.getOwnPropertyNames(obj);
for (let prop of props) {
let duplicate = _.find(result, (p: { name: string; desc: PropDescriptor }) => p.name === prop);
if (!duplicate && includePropCb(obj, prop)) {
let propDesc = Object.getOwnPropertyDescriptor(obj, prop);
result.push({ name: prop, desc: propDesc });
}
};
}
if (!iteratePrototypeBool) {
break;
}
iterateSelfBool = true;
} while (obj = Object.getPrototypeOf(obj));
return result;
}
}