!C99Shell v. 2.5 [PHP 8 Update] [24.05.2025]!

Software: Apache/2.4.41 (Ubuntu). PHP/8.0.30 

uname -a: Linux apirnd 5.4.0-204-generic #224-Ubuntu SMP Thu Dec 5 13:38:28 UTC 2024 x86_64 

uid=33(www-data) gid=33(www-data) groups=33(www-data) 

Safe-mode: OFF (not secure)

/var/www/html/wincloud_gateway/node_modules/redis-lru/test/   drwxr-xr-x
Free 13.33 GB of 57.97 GB (22.99%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Self remove    Logout    


Viewing file:     index.js (16.37 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
'use strict';

const assert = require('assert');

// const redis = require('redis').createClient(6379, 'redis-host');
// const Redis = require('ioredis'); const redis = new Redis(6379, 'redis-host');
const redis = require('./redisMock');

const LRU = require('../index');

beforeEach((done) => redis.flushdb(() => done()));

const dbsize = () => new Promise((resolve, reject) =>
  redis.dbsize((err, result) => {
    if (err) return reject(err);
    resolve(result);
  }));

// const printrange = (ns) => new Promise((resolve) =>
//   redis.zrange(`${ns || 'LRU-CACHE!'}-i`, 0, -1, (err, res) => { console.log(res); resolve(); }));

// sometimes need to force a ms change so multiple lru.get have different timestamp scores
const tick = (time) => new Promise((resolve) => setTimeout(resolve, time || 2));

describe('build cache', () => {
  it('should fail if no client given', () =>
    assert.throws(() => LRU(), /redis client is required\./));

  it('should fail if no max arg given', () => {
    assert.throws(() => LRU(redis), /max number of items in cache must be specified\./);
    assert.throws(() => LRU(redis, {}), /max number of items in cache must be specified\./);
  });
});

describe('set and get methods', () => {
  it('should save an item in the cache and allow to get it back', () => {
    const lru = LRU(redis, 3);

    return lru.set('key', 'hello')
      .then((result) => assert.equal(result, 'hello'))
      .then(() => lru.set('key2', {message: 'goodbye'}))
      .then(() => Promise.all([lru.get('key'), lru.get('key2')]))
      .then((results) => {
        assert.equal(results[0], 'hello');
        assert.deepEqual(results[1], {message: 'goodbye'});
      });
  });

  it('should return null if a key is not found in the cache', () => {
    const lru = LRU(redis, 3);

    return lru.get('key1')
      .then((result) => assert.equal(result, null));
  });

  it('should save up to opts.max items in the cache', () => {
    const lru = LRU(redis, 3);

    return Promise.all([
      lru.set('k1', 'v1'), lru.set('k2', 'v2'), lru.set('k3', 'v3')
    ])
    .then(() => lru.get('k1'))
    .then((r) => assert.equal(r, 'v1'))
    .then(tick)
    .then(() => lru.get('k2'))
    .then((r) => assert.equal(r, 'v2'))
    .then(tick)
    .then(() => lru.get('k3'))
    .then((r) => assert.equal(r, 'v3'))
    .then(dbsize)
    .then((r) => assert.equal(r, 4)) // DB size is #items + 1 for the index
    .then(() => lru.set('k4', 'v4'))
    .then(() => lru.get('k1'))
    .then((r) => assert.equal(r, null, 'k1 should have been evicted from the cache'))
    .then(() => lru.get('k2'))
    .then((r) => assert.equal(r, 'v2'))
    .then(() => lru.get('k3')) // set k4, get k1, k2 => k3 out of the cache
    .then((r) => assert.equal(r, 'v3'))
    .then(() => lru.get('k4'))
    .then((r) => assert.equal(r, 'v4'))
    .then(dbsize)
    .then((r) => assert.equal(r, 4, 'db size should not have grown'));
  });

  it('should keep different items in different namespaces', () => {
    const lru1 = LRU(redis, {max: 3, namespace: 'first'});
    const lru2 = LRU(redis, {max: 3, namespace: 'second'});

    return lru1.set('k1', 'first cache')
      .then(() => lru2.set('k1', 'second cache'))
      .then(() => Promise.all([lru1.get('k1'), lru2.get('k1')]))
      .then((results) => {
        assert.equal(results[0], 'first cache');
        assert.equal(results[1], 'second cache');
      });
  });

  it('should keep the last accessed items first', () => {
    const lru = LRU(redis, 3);

    return lru.set('k1', 'v1')
    .then(() => lru.set('k2', 'v2'))
    .then(() => lru.set('k3', 'v3'))
    .then(() => lru.get('k2')) // k2 last
    .then(tick)
    .then(() => lru.get('k3')) // k3 second
    .then(tick)
    .then(() => lru.get('k1')) // k1 first
    .then(tick)
    .then(() => lru.set('k4', 'v4')) // should evict oldest => k2 out
    .then(() => lru.get('k2'))
    .then((result) => {
      assert.equal(result, null);
    });
  });

  it('should update value and last accessed score when setting a key again', () => {
    const lru = LRU(redis, 3);

    return lru.set('k1', 'v1')
    .then(() => lru.set('k2', 'v2'))
    .then(() => lru.set('k3', 'v3'))
    .then(() => lru.get('k2'))
    .then(tick)
    .then(() => lru.get('k3'))
    .then(tick)
    .then(() => lru.get('k1'))
    .then(tick)
    .then(() => lru.set('k2', 'v2')) // k2 back to front, k3 is oldest
    .then(tick)
    .then(() => lru.set('k4', 'v4')) // k3 out
    .then(() => lru.get('k3'))
    .then((result) => {
      assert.equal(result, null);
    });
  });

  it('should not update last accessed score on a different namespace', () => {
    const lru1 = LRU(redis, {max: 2, namespace: 'c1'});
    const lru2 = LRU(redis, {max: 2, namespace: 'c2'});

    return lru1.set('k1', 'v1')
    .then(() => lru1.set('k2', 'v2'))
    .then(() => lru2.set('k1', 'v1'))
    .then(tick)
    .then(() => lru2.set('k2', 'v2'))
    .then(tick)
    .then(() => lru1.get('k1')) // bumps k1 in first cache
    .then(tick)
    .then(() => lru2.set('k3', 'v3')) // should evict k1 in second cache
    .then(() => lru2.get('k1'))
    .then((result) => {
      assert.equal(result, null);
    });
  });
});

describe('getOrSet method', () => {
  it('should get the value from cache and NOT call the function', () => {
    const lru = LRU(redis, 3);

    function fn () {
      throw Error('should not call');
    }

    return lru.set('key', 'hello')
      .then(() => lru.getOrSet('key', fn))
      .then((result) => assert.equal(result, 'hello'));
  });

  it('should set key to the return value of the function', () => {
    const lru = LRU(redis, 3);

    function fn () {
      return 5;
    }

    return lru.getOrSet('key', fn)
      .then((result) => assert.equal(result, 5))
      .then(() => lru.get('key'))
      .then((result) => assert.equal(result, 5));
  });

  it('should set key to the resolved value of the promise returned by the function', () => {
    const lru = LRU(redis, 3);

    function fn () {
      return Promise.resolve(5);
    }

    return lru.getOrSet('key', fn)
      .then((result) => assert.equal(result, 5))
      .then(() => lru.get('key'))
      .then((result) => assert.equal(result, 5));
  });

  it('should reject if function rejects', () => {
    const lru = LRU(redis, 3);

    function fn () {
      return Promise.reject(Error('something went wrong'));
    }

    return lru.getOrSet('key', fn)
      .then(() => { throw Error('should not resolve'); })
      .catch((err) => assert.equal(err.message, 'something went wrong'));
  });

  it('should reject if function throws', () => {
    const lru = LRU(redis, 3);

    function fn () {
      throw Error('something went wrong');
    }

    return lru.getOrSet('key', fn)
      .then(() => { throw Error('should not resolve'); })
      .catch((err) => assert.equal(err.message, 'something went wrong'));
  });

  it('should update recent-ness when getOrSet a saved value', () => {
    const lru = LRU(redis, 3);

    return lru.set('k1', 'v1')
    .then(() => lru.set('k2', 'v2'))
    .then(() => lru.set('k3', 'v3'))
    .then(() => lru.getOrSet('k2')) // k2 last
    .then(tick)
    .then(() => lru.getOrSet('k3')) // k3 second
    .then(tick)
    .then(() => lru.getOrSet('k1')) // k1 first
    .then(tick)
    .then(() => lru.set('k4', 'v4')) // should evict oldest => k2 out
    .then(() => lru.get('k2'))
    .then((result) => {
      assert.equal(result, null);
    });
  });

  it('should update recent-ness when getOrSet a missing value', () => {
    const lru = LRU(redis, 3);

    return lru.getOrSet('k2', () => 2) // k2 last
    .then(tick)
    .then(() => lru.getOrSet('k3', () => 3)) // k3 second
    .then(tick)
    .then(() => lru.getOrSet('k1', () => 1)) // k1 first
    .then(tick)
    .then(() => lru.set('k4', 'v4')) // should evict oldest => k2 out
    .then(() => lru.get('k2'))
    .then((result) => {
      assert.equal(result, null);
    });
  });
});

describe('peek method', () => {
  it('should return the value without changing the recent-ness score', () => {
    const lru = LRU(redis, 2);

    return lru.set('k1', 'v1')
      .then(tick)
      .then(() => lru.set('k2', 'v2'))
      .then(() => lru.peek('k1'))
      .then((r) => {
        assert.equal(r, 'v1');
        return lru.set('k3', 'v3'); // should evict k1 since last peek doesnt update recentness
      })
      .then(() => lru.get('k1'))
      .then((r) => assert.equal(r, null));
  });
});

describe('del method', () => {
  it('should remove the key from the cache and preserve the rest', () => {
    const lru = LRU(redis, 2);

    return lru.set('k1', 'v1')
      .then(() => lru.set('k2', 'v2'))
      .then(() => lru.del('k1'))
      .then(() => lru.get('k1'))
      .then((r) => assert.equal(r, null))
      .then(() => lru.get('k2'))
      .then((r) => assert.equal(r, 'v2'));
  });

  it('should not remove from other namespaces', () => {
    const lru = LRU(redis, 2);
    const lru2 = LRU(redis, {max: 2, namespace: 'c2'});

    return lru.set('k1', 'v1')
      .then(() => lru2.set('k1', 'v1'))
      .then(() => lru.del('k1'))
      .then(() => lru.get('k1'))
      .then((r) => assert.equal(r, null))
      .then(() => lru2.get('k1'))
      .then((r) => assert.equal(r, 'v1'));
  });
});

describe('reset method', () => {
  it('should remove all keys from the cache', () => {
    const lru = LRU(redis, 2);

    return lru.set('k1', 'v1')
      .then(() => lru.set('k2', 'v2'))
      .then(() => lru.reset())
      .then(() => lru.get('k1'))
      .then((r) => assert.equal(r, null))
      .then(() => lru.get('k2'))
      .then((r) => assert.equal(r, null));
  });

  it('should not empty other namespaces', () => {
    const lru = LRU(redis, 2);
    const lru2 = LRU(redis, {max: 2, namespace: 'c2'});

    return lru.set('k1', 'v1')
      .then(() => lru2.set('k1', 'v1'))
      .then(() => lru.reset())
      .then(() => lru.get('k1'))
      .then((r) => assert.equal(r, null))
      .then(() => lru2.get('k1'))
      .then((r) => assert.equal(r, 'v1'));
  });
});

describe('has method', () => {
  it('should return true if the item is in the cache without affecting the recent-ness', () => {
    const lru = LRU(redis, 2);

    return lru.set('k1', 'v1')
      .then(tick)
      .then(() => lru.set('k2', 'v2'))
      .then(() => lru.has('k1'))
      .then((r) => {
        assert.equal(r, true);
        return lru.set('k3', 'v3'); // should evict k1 since last peek doesnt update recentness
      })
      .then(() => lru.get('k1'))
      .then((r) => assert.equal(r, null));
  });

  it('should return false if the item is not in the cache', () => {
    const lru = LRU(redis, 2);

    return lru.set('k1', 'v1')
      .then(() => lru.set('k2', 'v2'))
      .then(() => lru.has('k3'))
      .then((r) => assert.equal(r, false));
  });
});

describe('keys method', () => {
  it('should return all keys inside the cache', () => {
    const lru = LRU(redis, 2);

    return lru.set('k1', 'v1')
      .then(tick)
      .then(() => lru.set('k2', 'v2'))
      .then(() => lru.keys())
      .then((r) => assert.deepEqual(r, ['k2', 'k1']));
  });

  it('should not return more keys if size exceeded before', () => {
    const lru = LRU(redis, 2);

    return lru.set('k1', 'v1')
      .then(tick)
      .then(() => lru.set('k2', 'v2'))
      .then(tick)
      .then(() => lru.set('k3', 'v3'))
      .then(() => lru.keys())
      .then((r) => assert.deepEqual(r, ['k3', 'k2']));
  });
});

describe('values method', () => {
  it('should return all values inside the cache', () => {
    const lru = LRU(redis, 2);

    return lru.set('k1', 'v1')
      .then(tick)
      .then(() => lru.set('k2', 'v2'))
      .then(() => lru.values())
      .then((r) => assert.deepEqual(r, ['v2', 'v1']));
  });

  it('should not return more values if size exceeded before', () => {
    const lru = LRU(redis, 2);

    return lru.set('k1', 'v1')
      .then(tick)
      .then(() => lru.set('k2', 'v2'))
      .then(tick)
      .then(() => lru.set('k3', 'v3'))
      .then(() => lru.values())
      .then((r) => assert.deepEqual(r, ['v3', 'v2']));
  });
});

describe('count method', () => {
  it('should return zero if no items in the cache', () => {
    const lru = LRU(redis, 2);

    return lru.count()
      .then((r) => assert.equal(r, 0));
  });

  it('should return the amount of items in the cache', () => {
    const lru = LRU(redis, 2);

    return lru.set('k1', 'v1')
      .then(tick)
      .then(() => lru.set('k2', 'v2'))
      .then(() => lru.count())
      .then((r) => assert.equal(r, 2));
  });

  it('should return the max size if cache size exceeded before', () => {
    const lru = LRU(redis, 2);

    return lru.set('k1', 'v1')
      .then(tick)
      .then(() => lru.set('k2', 'v2'))
      .then(tick)
      .then(() => lru.set('k3', 'v3'))
      .then(() => lru.count())
      .then((r) => assert.equal(r, 2));
  });
});

describe('maxAge option', () => {
  it('should return null after global maxAge has passed', () => {
    const lru = LRU(redis, {max: 2, maxAge: 10});

    return lru.set('k1', 'v1')
      .then(() => lru.get('k1'))
      .then((result) => assert.equal(result, 'v1'))
      .then(() => tick(11))
      .then(() => lru.get('k1'))
      .then((result) => assert.equal(result, null));
  });

  it('should return null after key maxAge has passed', () => {
    const lru = LRU(redis, {max: 2});

    return lru.set('k1', 'v1', 10)
      .then(() => lru.get('k1'))
      .then((result) => assert.equal(result, 'v1'))
      .then(() => tick(11))
      .then(() => lru.get('k1'))
      .then((result) => assert.equal(result, null));
  });

  it('should reduce dbsize after key expiration', () => {
    const lru = LRU(redis, {max: 2, maxAge: 10});

    return lru.set('k1', 'v1')
      .then(dbsize)
      .then((size) => assert.equal(size, 2))
      .then(() => tick(11))
      .then(() => lru.get('k1'))
      .then((result) => assert.equal(result, null))
      .then(dbsize)
      .then((size) => assert.equal(size, 0)); // zset doesnt count if empty
  });

  it('should remove expired key from index next time is getted', () => {
    const lru = LRU(redis, {max: 2});

    return lru.set('k1', 'v1')
      .then(() => lru.set('k2', 'v2', 10))
      .then(() => tick(11))
      .then(() => lru.get('k2'))
      .then((result) => assert.equal(result, null))
      .then(() => lru.count())
      .then((count) => assert.equal(count, 1))
      .then(() => lru.keys())
      .then((keys) => assert.deepEqual(keys, ['k1']));
  });

  it('should remove expired key from index next time is peeked', () => {
    const lru = LRU(redis, {max: 2});

    return lru.set('k1', 'v1')
      .then(() => lru.set('k2', 'v2', 10))
      .then(() => tick(11))
      .then(() => lru.peek('k2'))
      .then((result) => assert.equal(result, null))
      .then(() => lru.count())
      .then((count) => assert.equal(count, 1))
      .then(() => lru.keys())
      .then((keys) => assert.deepEqual(keys, ['k1']));
  });

  it('should not let key maxAge affect other keys', () => {
    const lru = LRU(redis, {max: 2, maxAge: 30});

    return lru.set('k1', 'v1', 10)
      .then(() => lru.set('k2', 'v2'))
      .then(() => lru.get('k1'))
      .then((result) => assert.equal(result, 'v1'))
      .then(() => lru.get('k2'))
      .then((result) => assert.equal(result, 'v2'))
      .then(() => tick(11))
      .then(() => lru.get('k1'))
      .then((result) => assert.equal(result, null))
      .then(() => lru.get('k2'))
      .then((result) => assert.equal(result, 'v2'))
      .then(() => tick(20))
      .then(() => lru.get('k2'))
      .then((result) => assert.equal(result, null));
  });

  it('should return false when calling has on an expired item', () => {
    const lru = LRU(redis, {max: 2, maxAge: 10});

    return lru.set('k1', 'v1')
      .then(() => lru.has('k1'))
      .then((result) => assert.equal(result, true))
      .then(() => tick(11))
      .then(() => lru.has('k1'))
      .then((result) => assert.equal(result, false));
  });
});

describe('custom score/increment options', () => {
  it('should allow building a LFU cache with a custom score and increment', () => {
    const lfu = LRU(redis, {max: 3, score: () => 1, increment: true});

    return lfu.set('k1', 'v1')
      .then(() => lfu.get('k1'))
      .then(() => lfu.get('k1')) // k1 used three times
      .then(() => lfu.set('k2', 'v2'))
      .then(() => lfu.set('k2', 'v22')) // k2 used 2 times
      .then(() => lfu.set('k3', 'v3'))
      .then(() => lfu.set('k4', 'v4')) // k3 should be removed
      .then(() => lfu.get('k3'))
      .then((result) => assert.equal(result, null))
      .then(() => lfu.keys())
      .then((keys) => assert.deepEqual(keys, ['k1', 'k2', 'k4']));
  });
});

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.0641 ]--