UNPKG

execution-engine

Version:

A TypeScript library for tracing and visualizing code execution workflows.

123 lines (122 loc) 6.1 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; Object.defineProperty(exports, "__esModule", { value: true }); const cache_decorator_1 = require("./cache.decorator"); describe('cache decorator', () => { it('should cache async function results and prevent redundant calls', async () => { let memoizationCheckCount = 0; let memoizedCalls = 0; let totalFunctionCalls = 0; let bypassCache = false; class DataService { async fetchData(id) { totalFunctionCalls++; return new Promise((resolve) => setTimeout(() => resolve(`Data for ID: ${id}`), 100)); } async fetchDataWithByPassedCacheFunction(id) { totalFunctionCalls++; return new Promise((resolve) => setTimeout(() => resolve(`Data for ID: ${id}`), 100)); } async throwData(name) { totalFunctionCalls++; throw new Error(`hello ${name} but I throw!`); } } __decorate([ (0, cache_decorator_1.cache)({ ttl: 3000, onCacheEvent: (cacheContext) => { memoizationCheckCount++; if (cacheContext.isCached && !cacheContext.isBypassed) { memoizedCalls++; } } }) ], DataService.prototype, "fetchData", null); __decorate([ (0, cache_decorator_1.cache)({ ttl: 3000, bypass: () => bypassCache, onCacheEvent: (cacheContext) => { memoizationCheckCount++; if (cacheContext.isCached && !cacheContext.isBypassed) { memoizedCalls++; } } }) ], DataService.prototype, "fetchDataWithByPassedCacheFunction", null); __decorate([ (0, cache_decorator_1.cache)({ ttl: 3000, onCacheEvent: (cacheContext) => { memoizationCheckCount++; if (cacheContext.isCached) { memoizedCalls++; } } }) ], DataService.prototype, "throwData", null); const service = new DataService(); memoizationCheckCount = 0; memoizedCalls = 0; totalFunctionCalls = 0; const result1 = await service.fetchData(1); expect(result1).toBe('Data for ID: 1'); expect(memoizedCalls).toBe(0); expect(totalFunctionCalls).toBe(1); expect(memoizationCheckCount).toBe(1); // Called once const result2 = await service.fetchData(1); expect(result2).toBe('Data for ID: 1'); expect(memoizedCalls).toBe(1); // Now it should be memoized expect(totalFunctionCalls).toBe(1); // No new calls expect(memoizationCheckCount).toBe(2); // Checked twice const result3 = await service.fetchData(2); expect(result3).toBe('Data for ID: 2'); expect(memoizedCalls).toBe(1); // No extra memoized calls yet expect(totalFunctionCalls).toBe(2); // New call for different ID expect(memoizationCheckCount).toBe(3); // Three checks (1st, 2nd for ID 1, and 3rd for ID 2) const result4 = await service.fetchData(2); expect(result4).toBe('Data for ID: 2'); expect(memoizedCalls).toBe(2); // ID 2 result is now memoized expect(totalFunctionCalls).toBe(2); // No extra new calls expect(memoizationCheckCount).toBe(4); // 4 checks in total // test NO cache for a Bypassed cache function memoizationCheckCount = 0; memoizedCalls = 0; totalFunctionCalls = 0; const result21 = await service.fetchDataWithByPassedCacheFunction(2); expect(result21).toBe('Data for ID: 2'); expect(memoizedCalls).toBe(0); // ID 2 result is now memoized expect(totalFunctionCalls).toBe(1); // extra new call expect(memoizationCheckCount).toBe(1); // 5 checks in total bypassCache = false; const result22 = await service.fetchDataWithByPassedCacheFunction(2); expect(result22).toBe('Data for ID: 2'); expect(memoizedCalls).toBe(1); // ID 2 result is now memoized expect(totalFunctionCalls).toBe(1); // NO extra new call expect(memoizationCheckCount).toBe(2); // 2 checks in total bypassCache = true; const result23 = await service.fetchDataWithByPassedCacheFunction(2); expect(result23).toBe('Data for ID: 2'); expect(memoizedCalls).toBe(1); // ID 2 result is NOT RETRIEVED FROM CACHE AS THEY ARE BYPASSED expect(totalFunctionCalls).toBe(2); // extra new call as bypassCache = true expect(memoizationCheckCount).toBe(3); // 5 checks in total // test NO cache for a throwing async method memoizationCheckCount = 0; memoizedCalls = 0; totalFunctionCalls = 0; await Promise.all([ expect(service.throwData('akram')).rejects.toThrow('hello akram but I throw!'), expect(service.throwData('akram')).rejects.toThrow('hello akram but I throw!'), expect(service.throwData('akram')).rejects.toThrow('hello akram but I throw!') ]); expect(memoizationCheckCount).toEqual(totalFunctionCalls + memoizedCalls); expect(memoizedCalls).toEqual(0); // No cache expect(totalFunctionCalls).toBe(3); // we call everytime we get a throw }); });