als-store
Version:
Library for streamlined file management and advanced data caching, featuring intelligent file searching, dynamic cache control, and flexible file operations
224 lines (191 loc) • 7.65 kB
JavaScript
const assert = require('node:assert')
const { describe, it, beforeEach, afterEach,after } = require('node:test')
const File = require('../lib/file')
const { existsSync, outputFileSync, unlinkSync, remove, removeSync } = require('fs-extra')
const { join } = require('path')
const Schema = require('als-schema')
describe('create save and remove', () => {
it('constructor should set correct path and name', () => {
const file = new File(__dirname, 'test.txt')
assert(file.path === __dirname)
assert(file.name === 'test.txt')
assert(file.size > 0)
})
it('save and remove', async () => {
const name = 'test.txt'
const file = new File(__dirname, name)
assert(!existsSync(file.fullPath))
await file.save()
assert(existsSync(file.fullPath))
await file.remove()
assert(!existsSync(file.fullPath))
})
})
describe('stats and value/buffer/json tests', () => {
const name = 'test.json'
const testFilePath = join(__dirname, name)
const testContent = '{"hello": "world"}'
beforeEach(async () => {
outputFileSync(testFilePath, testContent)
})
afterEach(async () => {
unlinkSync(testFilePath)
File.clearCache()
})
it('should retrieve stats for a file', async () => {
const file = new File(__dirname, name)
await file.getStats()
assert(file.stats.size > 0)
assert(typeof file.stats.atimeMs === 'number')
assert(typeof file.stats.mtimeMs === 'number')
assert(typeof file.stats.birthtimeMs === 'number')
})
it('should return empty object if stats are not set', () => {
const file = new File(__dirname, name)
const stats = file.stats
assert.deepStrictEqual(stats, {})
})
it('async getValue() - should correctly read file content', async () => {
const file = new File(__dirname, name)
assert(file.value === null)
await file.getValue()
assert(file.value === testContent)
})
it('should set the new file content', () => {
const file = new File(__dirname, name)
const newValue = 'New content'
file.value = newValue
assert(file.value === newValue)
})
it('get buffer() - should return the file content as a buffer', async () => {
const file = new File(__dirname, name)
await file.getValue()
assert(file.buffer instanceof Buffer)
assert(file.buffer.toString() === testContent)
})
it('get json() - should return the file content as JSON', async () => {
const file = new File(__dirname, name)
await file.getValue()
assert.deepStrictEqual(file.json, JSON.parse(testContent))
})
it('set json(newValue) - should set the file content as JSON string', () => {
const file = new File(__dirname, name)
const newJsonValue = { hello: "new world" }
file.json = newJsonValue
assert.strictEqual(file.value, JSON.stringify(newJsonValue))
})
})
describe('name and schema tests', () => {
const { string, number, optional } = Schema
const userSchema = new Schema({ name: string(3, 25), age: [optional, number(0, 120)], active: false })
it('first test', () => {
const file = new File(__dirname, 'test', userSchema)
const { name, params, fullPath, $fullPath, $name } = file
assert(name === 'test')
assert.deepStrictEqual(params, { name: 'test', age: undefined, active: false })
assert(fullPath, join(__dirname, 'test'))
assert($name === 'test..false')
assert($fullPath === join(__dirname, 'test..false'))
})
it('change params', async () => {
const file = new File(__dirname, 'test', userSchema)
file.params.age = 50
const { name, params, fullPath, $fullPath, $name } = file
assert(name !== $name)
assert($name === 'test.50.false')
assert.throws(() => file.params.age = '50')
assert($fullPath === join(__dirname, 'test.50.false'))
await file.save()
assert(file.name === file.$name)
await file.remove()
})
})
describe('Cache tests', () => {
const testDir = join(__dirname, 'test_files')
const fileName = 'test.txt'
const newFileName = 'new_test.txt'
const testFilePath = join(testDir, fileName)
const newTestFilePath = join(testDir, newFileName)
const testContent = 'Test content'
beforeEach(async () => {
File.clearCache()
outputFileSync(testFilePath, testContent)
})
afterEach(async () => {
if (existsSync(testFilePath)) unlinkSync(testFilePath)
if (existsSync(newTestFilePath)) unlinkSync(newTestFilePath)
File.clearCache()
})
after(() => removeSync(testDir))
it('should add file to cache on save and retrieve from cache', async () => {
const file = new File(testDir, fileName)
await file.save()
const startTime = performance.now()
await file.getValue()
const timeWithoutCache = performance.now() - startTime
const newFile = new File(testDir, fileName)
const startTimeNoCache = performance.now()
await newFile.getValue()
const timeWithCache = performance.now() - startTimeNoCache
assert(timeWithCache < timeWithoutCache) // Reading from cache should be faster
assert(file.value === testContent)
assert(file === newFile)
})
it('should remove file from cache', async () => {
const file = new File(testDir, fileName)
await file.save()
assert(file.cacheDir[file.name] !== undefined)
file.removeFromCache()
assert(file.cacheDir[file.name] === undefined)
})
it('should rename file in cache', async () => {
const file = new File(testDir, fileName)
await file.save()
assert(file.cacheDir[fileName] !== undefined)
const sizeBefore = file.size
file.value = 'New content'
file.name = newFileName
await file.save()
assert(file.cacheDir[newFileName] !== undefined)
assert(file.cacheDir[fileName] === undefined)
assert(file.name === newFileName)
assert(file.size !== sizeBefore) // size should change
})
it.todo('LRU',() => {
// TODO LRU
const getIndex = (i=0) => {
for(let $file of File.map) {
i++;
if($file === file) return i;
}
}
})
it('clearCache() should clear the cache', async () => {
const file = new File(testDir, fileName)
await file.save()
assert(file.cacheDir[fileName] !== undefined)
assert(File.map.has(file))
File.clearCache()
assert.deepStrictEqual(File.cache, {})
assert(!File.map.has(file))
})
it('removeDirFromCache(dirPath)',() => {
const file = new File(testDir, fileName)
const {parent,dirName} = File.getDir(testDir)
assert(parent[dirName] !== undefined)
assert(parent[dirName][fileName] !== undefined)
File.removeDirFromCache(testDir)
assert(parent[dirName] === undefined)
})
it('renameDirInCache(baseDir,dirName,newDirname)',() => {
const newDirname = 'newdir'
const file = new File(testDir, fileName)
const {parent,dirName} = File.getDir(testDir)
assert(parent[dirName] !== undefined)
assert(parent[dirName][fileName] !== undefined)
File.renameDirInCache(__dirname,dirName,newDirname)
assert(parent[dirName] === undefined)
assert(parent[newDirname] !== undefined)
assert(parent[newDirname][fileName] !== undefined)
})
})