UNPKG

workshopper-adventure-storage

Version:

Storage system for workshopper-adventure to store the preferences.

178 lines (153 loc) 5.3 kB
var storage = require('..') var fs = require('fs') var expect = require('chai').expect var rimraf = require('rimraf') var path = require('path') describe('Storage', function () { var userDir = path.join(__dirname, '..', '.tmp') var route = [userDir, 'foo', 'bar'] var storageDir = path.join.apply(path, route) var fileNameA = path.join(storageDir, 'a.json') var fileNameB = path.join(storageDir, 'b.json') function assertStorageNonExistence () { try { if (fs.accessSync) { fs.accessSync(storageDir) } else { fs.statSync(storageDir) } } catch (e) { expect(e.code).to.be.equals('ENOENT') return } throw new Error('storage folder seems to exist?!') } function create () { return storage.apply(null, route) } before(function () { // For the test to run in an restricted environment that // also doesn't interfere we run in a clear, separate user // directory rimraf.sync(userDir) storage.userDir = userDir }) describe('in clean state', function () { beforeEach(function () { rimraf.sync(userDir) }) it('should not automatically create a folder', function () { // If the storage creates a folder automatically we might // theoretically end up with a lot of empty foldes, it // is better that the storages are only created once they // exist create() assertStorageNonExistence() }) it('should not create a folder when getting data', function () { // It might be tempting to make a system to create a file // if a property is missing. This would be unwanted behavior // (for the same reason as one above) create().get('a') assertStorageNonExistence() }) it('should allow to get data', function () { // By allowing this we can simply assume & test for null expect(create().get('a')).to.be.equals(null) }) it('should store files at a predicatable locations', function () { // In order to be update compatible the path should be // in this and future versions of the storage api var storage = create() storage.save('a', 1) storage.save('b', 2) expect(JSON.parse(fs.readFileSync(fileNameA))).to.be.equals(1) expect(JSON.parse(fs.readFileSync(fileNameB))).to.be.equals(2) }) it('should store readable files', function () { // For debugging we want the files to be stored // in a fashion that is readable to humans create().save('a', { x: 1 }) expect(fs.readFileSync(fileNameA, 'utf8')).to.be.equals('{\n "x": 1\n}') }) it('should allow to store data', function () { var storage = create() storage.save('a', 1) expect(storage.get('a')).to.be.equals(1) }) it('should allow to reset the store', function () { // Reset as operation could happen at any given // time, this can break if reset assumes that // the folder exists var storage = create() storage.reset() expect(storage.get('a')).to.be.equals(null) }) }) describe('with stored data', function () { var storage = create() beforeEach(function () { rimraf.sync(userDir) storage.save('a', 1) }) it('should return the stored data', function () { expect(storage.get('a')).to.be.equals(1) }) it('should allow to overwrite the data', function () { storage.save('a', 2) expect(storage.get('a')).to.be.equals(2) }) it('should allow to reset the data', function () { storage.reset() expect(storage.get('a')).to.be.equals(null) }) }) describe('with corrupt storage', function () { var storage = create() beforeEach(function () { rimraf.sync(userDir) fs.mkdirSync(storageDir, { recursive: true }) fs.writeFileSync(fileNameA, '{') }) it('should still not break get', function () { // By breaking the API with a broken file we gain no // value for the user of workshoppers. A broken file // should not inflict pain on the user of // workshopper-adventure // // TODO: Debugging broken files could be improved by storing the broken // file in a backup location expect(storage.get('a')).to.be.equal(null) }) it('should allow to overwrite the broken data', function () { storage.save('a', 1) expect(storage.get('a')).to.be.equal(1) }) it('should allow to reset the state', function () { storage.reset() expect(storage.get('a')).to.be.equal(null) }) }) describe('inaccessible storage', function () { var storage = create() before(function () { rimraf.sync(userDir) fs.mkdirSync(storageDir, { recursive: true }) fs.writeFileSync(fileNameA, '{"x": 1}') fs.chmodSync(fileNameA, 0) fs.chmodSync(storageDir, 0) }) it('should still not break get', function () { expect(storage.get('a')).to.be.equal(null) }) it('should just not store if a file isn\'t writable', function () { storage.save('a', 1) expect(storage.get('a')).to.be.equal(null) }) after(function () { fs.chmodSync(storageDir, 448) fs.chmodSync(fileNameA, 448) rimraf.sync(userDir) }) }) })