From 6c7c938fc685f4299b66779ef170e5af7c70f7b1 Mon Sep 17 00:00:00 2001 From: David Humphrey Date: Wed, 2 Jan 2019 20:46:12 -0500 Subject: [PATCH 1/2] Add Filer.fs to support --- README.md | 39 ++++++++++++++++++++++++++------------- src/index.js | 17 ++++++++++++++++- tests/spec/filer.spec.js | 31 +++++++++++++++++++++++++++++-- 3 files changed, 71 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 84e0f2e9..a4e0820e 100644 --- a/README.md +++ b/README.md @@ -81,15 +81,20 @@ backend storage providers, for example `Memory`. See the section on [Storage Pro ```js -var fs = new Filer.FileSystem(); -fs.open('/myfile', 'w+', function(err, fd) { - if (err) throw err; - fs.close(fd, function(err) { - if (err) throw err; - fs.stat('/myfile', function(err, stats) { - if (err) throw err; - console.log('stats: ' + JSON.stringify(stats)); - }); +// You can easily use Filer.fs in place of node's `fs` +const { fs } = require('filer'); + +fs.writeFile('/myfile', 'Hello World!', (err) => { + if (err) { + return console.error('Unable to write /myfile', err); + } + + fs.stat('/myfile', (err, stats) => { + if (err) { + return console.error('Unable to stat /myfile', err); + } + + console.log('Wrote /myfile, stats are:', stats); }); }); ``` @@ -125,9 +130,13 @@ fs.writeFile('/myfile', 'some data') #### Filer.FileSystem(options, callback) constructor -File system constructor, invoked to open an existing file system or create a new one. -Accepts two arguments: an `options` object, and an optional `callback`. The `options` -object can specify a number of optional arguments, including: +In most cases, using `Filer.fs` will be sufficient, and provide a working filesystem. +However, if you need more control over the filesystem, you can also use the `FileSystem` +constructor, invoked to open an existing file system or create a new one. + +`Filer.FileSystem()` It accepts two arguments: an `options` object, and an optional +`callback` function. The `options` object can specify a number of optional arguments, +including: * `name`: the name of the file system, defaults to `'"local'` * `flags`: an Array of one or more flags to use when creating/opening the file system: @@ -324,7 +333,11 @@ Once a `FileSystem` is created, it has the following methods. NOTE: code example a `FileSystem` instance named `fs` has been created like so: ```javascript -var fs = new Filer.FileSystem(); +// 1. Using Filer.fs for a default filesystem +const { fs } = require('filer'); + +// 2. Or via the FileSystem constructor with specified options +const fs = new Filer.FileSystem(options, callback); ``` * [fs.rename(oldPath, newPath, callback)](#rename) diff --git a/src/index.js b/src/index.js index dc54a5ea..b9433f4d 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,22 @@ -module.exports = { +let fs = null; +let Filer = null; + +module.exports = Filer = { FileSystem: require('./filesystem/interface.js'), Buffer: Buffer, Path: require('./path.js'), Errors: require('./errors.js'), Shell: require('./shell/shell.js') }; + +// Add a getter for the `fs` instance, which returns +// a Filer FileSystem instance, using the default provider/flags. +Object.defineProperty(Filer, 'fs', { + enumerable: true, + get() { + if(!fs) { + fs = new Filer.FileSystem(); + } + return fs; + } +}); diff --git a/tests/spec/filer.spec.js b/tests/spec/filer.spec.js index 2fec5abc..3c699548 100644 --- a/tests/spec/filer.spec.js +++ b/tests/spec/filer.spec.js @@ -10,6 +10,35 @@ describe('Filer', function() { expect(typeof Filer.FileSystem).to.equal('function'); }); + it('has Buffer constructor', function() { + expect(typeof Filer.Buffer).to.equal('function'); + }); + + it('has Path object', function() { + expect(typeof Filer.Path).to.equal('object'); + }); + + it('has Errors object', function() { + expect(typeof Filer.Errors).to.equal('object'); + }); + + it('has an fs object that returns a Filer.FileSystem', function() { + // Depends on IndexedDB being available, since we can't + // configure our own test provider. + if(!Filer.FileSystem.providers.IndexedDB.isSupported()) { + this.skip(); + } + + expect(typeof Filer.fs).to.equal('object'); + + const fs1 = Filer.fs; + const fs2 = Filer.fs; + + expect(fs1).to.be.an.instanceof(Filer.FileSystem); + expect(fs2).to.be.an.instanceof(Filer.FileSystem); + expect(fs1).to.equal(fs2); + }); + it('has Shell constructor', function() { expect(typeof Filer.Shell).to.equal('function'); }); @@ -24,8 +53,6 @@ describe('Filer', function() { var Provider; if(providers.IndexedDB.isSupported()) { Provider = providers.IndexedDB; - } else if(providers.WebSQL.isSupported()) { - Provider = providers.WebSQL; } else { Provider = providers.Memory; } From 7ada0d61004f96292ccf2650a590d0e8726657fe Mon Sep 17 00:00:00 2001 From: David Humphrey Date: Wed, 2 Jan 2019 21:11:50 -0500 Subject: [PATCH 2/2] Update README code examples, add tests, also expose Path as path --- README.md | 29 ++++++++++++++------- src/index.js | 2 ++ tests/index.js | 3 +++ tests/spec/filer.spec.js | 4 ++- tests/spec/readme.example.spec.js | 43 +++++++++++++++++++++++++++++++ 5 files changed, 70 insertions(+), 11 deletions(-) create mode 100644 tests/spec/readme.example.spec.js diff --git a/README.md b/README.md index a4e0820e..f0dfb727 100644 --- a/README.md +++ b/README.md @@ -81,20 +81,28 @@ backend storage providers, for example `Memory`. See the section on [Storage Pro ```js -// You can easily use Filer.fs in place of node's `fs` -const { fs } = require('filer'); +const { fs, path } = require('filer'); -fs.writeFile('/myfile', 'Hello World!', (err) => { +fs.mkdir('/docs', (err) => { if (err) { - return console.error('Unable to write /myfile', err); + return console.error('Unable to create /docs dir', err); } + + const filename = path.join('/docs', 'first.txt'); + const data = 'Hello World!\n'; - fs.stat('/myfile', (err, stats) => { + fs.writeFile(filename, data, (err) => { if (err) { - return console.error('Unable to stat /myfile', err); + return console.error('Unable to write /docs/first.txt', err); } - console.log('Wrote /myfile, stats are:', stats); + fs.stat(filename, (err, stats) => { + if (err) { + return console.error('Unable to stat /docs/first.txt', err); + } + + console.log('Stats for /docs/first.txt:', stats); + }); }); }); ``` @@ -237,15 +245,16 @@ Buffer.allocUnsafe(size) #### Filer.Path -The node.js [path module](http://nodejs.org/api/path.html) is available via the `Filer.Path` object. It is -identical to the node.js (see [https://github.com/browserify/path-browserify](https://github.com/browserify/path-browserify)) version with the following differences: +The node.js [path module](http://nodejs.org/api/path.html) is available via `Filer.path` or +`Filer.Path` (both are supported for historical reasons, and to match node). The Filer `path` +module is identical to the node.js version (see [https://github.com/browserify/path-browserify](https://github.com/browserify/path-browserify)), with the following differences: * The CWD always defaults to `/` * No support for Windows style paths (assume you are on a POSIX system) * Additional utility methods (see below) ```javascript -var path = Filer.Path; +var path = Filer.path; var dir = path.dirname('/foo/bar/baz/asdf/quux'); // dir is now '/foo/bar/baz/asdf' diff --git a/src/index.js b/src/index.js index b9433f4d..c89fdf99 100644 --- a/src/index.js +++ b/src/index.js @@ -4,7 +4,9 @@ let Filer = null; module.exports = Filer = { FileSystem: require('./filesystem/interface.js'), Buffer: Buffer, + // We previously called this Path, but node calls it path. Do both Path: require('./path.js'), + path: require('./path.js'), Errors: require('./errors.js'), Shell: require('./shell/shell.js') }; diff --git a/tests/index.js b/tests/index.js index 2402fd30..db385494 100644 --- a/tests/index.js +++ b/tests/index.js @@ -85,3 +85,6 @@ require('./bugs/issue267.js'); require('./bugs/issue270.js'); require('./bugs/rename-dir-trailing-slash.js'); require('./bugs/issue357.js'); + +// Sample code from README +require('./spec/readme.example.spec'); diff --git a/tests/spec/filer.spec.js b/tests/spec/filer.spec.js index 3c699548..18cb8d8a 100644 --- a/tests/spec/filer.spec.js +++ b/tests/spec/filer.spec.js @@ -14,8 +14,10 @@ describe('Filer', function() { expect(typeof Filer.Buffer).to.equal('function'); }); - it('has Path object', function() { + it('has Path and path objects', function() { expect(typeof Filer.Path).to.equal('object'); + expect(typeof Filer.path).to.equal('object'); + expect(Filer.Path).to.equal(Filer.path); }); it('has Errors object', function() { diff --git a/tests/spec/readme.example.spec.js b/tests/spec/readme.example.spec.js new file mode 100644 index 00000000..7605b9a1 --- /dev/null +++ b/tests/spec/readme.example.spec.js @@ -0,0 +1,43 @@ +const { path } = require('../../src'); +var util = require('../lib/test-utils.js'); +var expect = require('chai').expect; + +describe('README example code', function() { + beforeEach(util.setup); + afterEach(util.cleanup); + + it('should run the code in the README overview example', function(done) { + // Slightly modified version of the first example code in the README + // See + const fs = util.fs(); + + fs.mkdir('/docs', (err) => { + if (err) throw err; + + const filename = path.join('/docs', 'first.txt'); + const data = 'Hello World!\n'; + + fs.writeFile(filename, data, (err) => { + if (err) throw err; + + fs.stat(filename, (err, stats) => { + if (err) throw err; + expect(stats.size).to.equal(data.length); + done(); + }); + }); + }); + }); + + it('should run the fsPromises example code', function() { + const fs = util.fs().promises; + const filename = '/myfile'; + const data = 'some data'; + + return fs.writeFile(filename, data) + .then(() => fs.stat(filename)) + .then(stats => { + expect(stats.size).to.equal(data.length); + }); + }); +});