import type { CacheOptions } from '../cache' ; import { Cache } from '../cache' ; jest . mock ( '../cache' ) ; describe ( '#Cache' , ( ) => { const setup = ( options = { } ) => { const cache = new Cache ( ) ; cache . initialize ( options ) ; return cache ; } ; it ( 'should cache the values with default "cache" option as true' , ( ) => { const cache = setup ( ) ; const lazyValue = jest . fn ( ) . mockReturnValue ( 10 ) ; const data = { namespace : 'namespace' , cacheKey : 'cacheKey' , value : lazyValue } ; const value = cache . load ( data ) ; expect ( cache . getSize ( ) ) . toBe ( 1 ) ; expect ( lazyValue ) . toHaveBeenCalledTimes ( 1 ) ; expect ( value ) . toBe ( 10 ) ; } ) ; it ( 'should cache the values when "cache" option is true' , ( ) => { const cache = setup ( { cache : true } ) ; const lazyValue = jest . fn ( ) . mockReturnValue ( 10 ) ; const data = { namespace : 'namespace' , cacheKey : 'cacheKey' , value : lazyValue } ; const value = cache . load ( data ) ; expect ( cache . getSize ( ) ) . toBe ( 1 ) ; expect ( lazyValue ) . toHaveBeenCalledTimes ( 1 ) ; expect ( value ) . toBe ( 10 ) ; } ) ; it ( 'should not cache the values when "cache" option is false' , ( ) => { const cache = setup ( { cache : false } ) ; const lazyValue = jest . fn ( ) . mockReturnValue ( 10 ) ; const data = { namespace : 'namespace' , cacheKey : 'cacheKey' , value : lazyValue } ; const value = cache . load ( data ) ; expect ( cache . getSize ( ) ) . toBe ( 0 ) ; expect ( lazyValue ) . toHaveBeenCalledTimes ( 1 ) ; expect ( value ) . toBe ( 10 ) ; } ) ; it ( 'should return original cached value when accessed with original key' , ( ) => { const cache = setup ( ) ; const lazyValue = jest . fn ( ) . mockReturnValue ( 10 ) ; const data = { namespace : 'namespace' , cacheKey : 'cacheKey' , value : lazyValue } ; cache . load ( data ) ; cache . load ( data ) ; const value = cache . load ( data ) ; expect ( lazyValue ) . toHaveBeenCalledTimes ( 1 ) ; expect ( value ) . toBe ( 10 ) ; } ) ; it ( 'should move frequently used keys in last position of queue' , ( ) => { const cache = setup ( ) ; const data1 = { namespace : 'namespace1' , cacheKey : 'cacheKey1' , value : ( ) => 10 } ; const data2 = { cacheKey : 'cacheKey2' , value : ( ) => 20 } ; const data3 = { namespace : 'namespace3' , cacheKey : 'cacheKey3' , value : ( ) => 30 } ; cache . load ( data1 ) ; cache . load ( data2 ) ; cache . load ( data3 ) ; expect ( Array . from ( cache . getKeys ( ) ) ) . toEqual ( [ 'namespace1----cacheKey1' , 'cacheKey2' , 'namespace3----cacheKey3' , ] ) ; cache . load ( data2 ) ; cache . load ( data1 ) ; expect ( Array . from ( cache . getKeys ( ) ) ) . toEqual ( [ 'namespace3----cacheKey3' , 'cacheKey2' , 'namespace1----cacheKey1' , ] ) ; } ) ; it ( 'should should delete first key value pair from queue when exceeds max size' , ( ) => { const cache = setup ( { maxSize : 3 } ) ; const data1 = { namespace : 'namespace1' , cacheKey : 'cacheKey1' , value : ( ) => 10 } ; const data2 = { namespace : 'namespace2' , cacheKey : 'cacheKey2' , value : ( ) => 20 } ; const data3 = { cacheKey : 'cacheKey3' , value : ( ) => 30 } ; cache . load ( data1 ) ; cache . load ( data2 ) ; cache . load ( data3 ) ; cache . load ( data2 ) ; expect ( Array . from ( cache . getKeys ( ) ) ) . toEqual ( [ 'namespace1----cacheKey1' , 'cacheKey3' , 'namespace2----cacheKey2' , ] ) ; const data4 = { namespace : 'namespace4' , cacheKey : 'cacheKey4' , value : ( ) => 40 } ; const value = cache . load ( data4 ) ; expect ( Array . from ( cache . getKeys ( ) ) ) . toEqual ( [ 'cacheKey3' , 'namespace2----cacheKey2' , 'namespace4----cacheKey4' , ] ) ; expect ( value ) . toBe ( 40 ) ; } ) ; } ) ;