Created
July 31, 2019 21:50
-
-
Save max-lt/f4d4b30442c79d7d42a6241964da899c to your computer and use it in GitHub Desktop.
Cache decorator typescript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Cache } from './cache.decorator'; | |
class Test { | |
seed; | |
constructor(seed?) { | |
this.seed = seed || Math.random(); | |
} | |
@Cache() | |
getValue(): number { | |
return this.seed; | |
} | |
@Cache() | |
getRandomValue(): number { | |
return Math.random(); | |
} | |
@Cache() | |
mulRandomValue(mult = 3): number { | |
return mult * Math.random(); | |
} | |
@Cache() | |
getNewInstance(): Test { | |
return new Test(Math.random()); | |
} | |
} | |
describe('Cache decorator', () => { | |
const a = new Test(345); | |
const b = new Test(); | |
it('Should correctly bind class reference (this)', () => { | |
expect(a.getValue()).toBeDefined(); | |
expect(a.getValue()).toBe(345); | |
}); | |
it('Should return the same vale twice if method called with no parameter', () => { | |
expect(a.getRandomValue()).toBe(a.getRandomValue()); | |
expect(b.getRandomValue()).toBe(b.getRandomValue()); | |
}); | |
it('Should return different values if methods are not from the same instance', () => { | |
expect(a.getRandomValue()).not.toBe(b.getRandomValue()); | |
}); | |
it('Should cache a method called with no argument', () => { | |
expect(a.mulRandomValue()).toBe(a.mulRandomValue()); | |
}); | |
it('Should not cache a method called with argument', () => { | |
expect(a.mulRandomValue()).not.toBe(a.mulRandomValue(3)); | |
expect(b.mulRandomValue(3)).not.toBe(b.mulRandomValue(3)); | |
}); | |
it('Should work with instances', () => { | |
expect(a.getNewInstance().seed).toBe(a.getNewInstance().seed); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export function Cache() { | |
return (target: any, name: string, desc: PropertyDescriptor) => { | |
// Keeping original method. | |
const fn = desc.value; | |
// Create a symbol for the targetted method. | |
const cache = Symbol(name + ' cache symbol'); | |
// tslint:disable-next-line: only-arrow-functions | |
desc.value = function () { | |
if (!this[cache]) { | |
// Define this[cache]: this is our cache object. | |
Object.defineProperty(this, cache, { writable: true }); | |
} | |
// We bypass cache if argument(s) provided. | |
if (arguments.length) { | |
return fn.apply(this, arguments); | |
} | |
// Set cache value if not defined | |
if (this[cache] === undefined) { | |
this[cache] = fn.apply(this); | |
} | |
return this[cache]; | |
}; | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment