diff --git a/README.md b/README.md index 84e0f2e..f0dfb72 100644 --- a/README.md +++ b/README.md @@ -81,14 +81,27 @@ 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)); +const { fs, path } = require('filer'); + +fs.mkdir('/docs', (err) => { + if (err) { + return console.error('Unable to create /docs dir', err); + } + + const filename = path.join('/docs', 'first.txt'); + const data = 'Hello World!\n'; + + fs.writeFile(filename, data, (err) => { + if (err) { + return console.error('Unable to write /docs/first.txt', err); + } + + 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); }); }); }); @@ -125,9 +138,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: @@ -228,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' @@ -324,7 +342,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 dc54a5e..c89fdf9 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,24 @@ -module.exports = { +let fs = null; +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') }; + +// 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/index.js b/tests/index.js index 2402fd3..db38549 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 2fec5ab..18cb8d8 100644 --- a/tests/spec/filer.spec.js +++ b/tests/spec/filer.spec.js @@ -10,6 +10,37 @@ 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 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() { + 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 +55,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; } diff --git a/tests/spec/readme.example.spec.js b/tests/spec/readme.example.spec.js new file mode 100644 index 0000000..7605b9a --- /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); + }); + }); +});