Home Reference Source Test Repository

buildDocs/memoize.spec.js

import * as tslib_1 from "tslib";
import { expect } from 'chai';
import { spy } from 'sinon';
import { Memoize } from './memoize';
describe('memoize', () => {
    it('should memoize the function', () => {
        const _spy = spy();
        class MyClass {
            fn(n) {
                _spy(n);
                expect(this, 'context').to.equal(myClass);
                return n;
            }
        }
        tslib_1.__decorate([
            Memoize()
        ], MyClass.prototype, "fn", null);
        const myClass = new MyClass();
        myClass.fn(1);
        myClass.fn(1);
        myClass.fn(1);
        myClass.fn(1);
        myClass.fn(1);
        expect(myClass.fn(1)).to.equal(1);
        expect(_spy.callCount).to.equal(1);
        myClass.fn(2);
        myClass.fn(2);
        expect(myClass.fn(2)).to.equal(2);
        expect(_spy.callCount).to.equal(2);
    });
    describe('with function resolver', () => {
        it('should resolve the key', () => {
            const _spy = spy();
            class MyClass {
                fn(item) {
                    _spy();
                    expect(this, 'context').to.equal(myClass);
                    return item.value;
                }
            }
            tslib_1.__decorate([
                Memoize((item) => item.key)
            ], MyClass.prototype, "fn", null);
            const myClass = new MyClass();
            myClass.fn({ key: 'test', value: 10 });
            myClass.fn({ key: 'test', value: 20 });
            myClass.fn({ key: 'test', value: 30 });
            expect(myClass.fn({ key: 'test', value: 50 })).to.equal(10);
            expect(_spy.callCount).to.equal(1);
            myClass.fn({ key: 'test2', value: 30 });
            expect(myClass.fn({ key: 'test2', value: 50 })).to.equal(30);
            expect(_spy.callCount).to.equal(2);
        });
    });
    describe('with string resolver', () => {
        it('should resolve the key', () => {
            const _spy = spy();
            class MyClass {
                fn(item) {
                    _spy();
                    expect(this, 'context').to.equal(myClass);
                    return item.value;
                }
                resolve(item) {
                    expect(this, 'resolver context').to.equal(myClass);
                    return item.key;
                }
            }
            tslib_1.__decorate([
                Memoize('resolve')
            ], MyClass.prototype, "fn", null);
            const myClass = new MyClass();
            myClass.fn({ key: 'test', value: 10 });
            myClass.fn({ key: 'test', value: 20 });
            myClass.fn({ key: 'test', value: 30 });
            expect(myClass.fn({ key: 'test', value: 50 })).to.equal(10);
            expect(_spy.callCount).to.equal(1);
            myClass.fn({ key: 'test2', value: 30 });
            expect(myClass.fn({ key: 'test2', value: 50 })).to.equal(30);
            expect(_spy.callCount).to.equal(2);
        });
    });
    describe('with custom map type', () => {
        it('should create the map of type', () => {
            class MyClass {
                fn(item) {
                    return item.value;
                }
            }
            tslib_1.__decorate([
                Memoize({ type: WeakMap })
            ], MyClass.prototype, "fn", null);
            const myClass = new MyClass();
            expect(myClass.fn.cache).to.be.an.instanceOf(WeakMap);
        });
    });
    describe('with custom cache', () => {
        it('should use the provided map', () => {
            const cache = new Map();
            class MyClass {
                fn(item) {
                    return item.value;
                }
            }
            tslib_1.__decorate([
                Memoize({ cache })
            ], MyClass.prototype, "fn", null);
            const myClass = new MyClass();
            const myClass2 = new MyClass();
            expect(myClass.fn.cache).to.equal(cache);
            expect(myClass2.fn.cache).to.equal(cache);
        });
    });
});