import { getCached } from '../cached';

describe('getCached', () => {
    const arrRef = [];
    const cached = getCached('test', 'foo', 42, arrRef);
    cached.setValue('the result of an expensive function call');

    it('returns the value if the arguments are the same', () => {
        const testCached = getCached('test', 'foo', 42, arrRef);
        expect(testCached.validate()).toBe(true);
        expect(testCached.getValue()).toBe('the result of an expensive function call');
    });

    it('returns undefined if any of the arguments are different', () => {
        const testCached = getCached('test', 'foo', 42, []);
        expect(testCached.validate()).toBe(false);
        expect(testCached.getValue()).toBe(undefined);
    });

    it('replaces the previous value', () => {
        const testCachedFirstCall = getCached('test', 'foo', 42, arrRef);
        expect(testCachedFirstCall.getValue()).toBe('the result of an expensive function call');
        testCachedFirstCall.setValue('new result');
        const testCachedSecondCall = getCached('test', 'foo', 42, arrRef);
        expect(testCachedSecondCall.getValue()).toBe('new result');
    });

    it('calls the provided function only if the args changed', () => {
        const testFn = jest.fn(() => {
            return {};
        });
        const ref1 = getCached('test', 'foo', 42, arrRef).use(testFn);
        const ref2 = getCached('test', 'foo', 42, arrRef).use(testFn);
        expect(ref2).toBe(ref1);
        const ref3 = getCached('test', 'foo', 43, arrRef).use(testFn);
        expect(ref3).not.toBe(ref1);
    });
});
