diff --git a/README.md b/README.md index ceac578..e5397e9 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ _Powers http://jsonplaceholder.typicode.com_ ```javascript // db.json -{ +{ "posts": [ { "id": 1, "body": "foo" } ] @@ -33,13 +33,11 @@ $ curl -i http://localhost:3000/posts/1 ```javascript var server = require('json-server'); -server.low.db = { +server({ posts: [ { id: 1, body: 'foo' } ] -} - -server.listen(3000); +}).listen(3000); ``` You can find a running demo here: http://jsonplaceholder.typicode.com. @@ -62,20 +60,18 @@ $ npm install -g json-server ## CLI usage ```bash +json-server - Usage: json-server [options] +Examples: + json-server db.json + json-server file.js + json-server http://example.com/db.json - Options: - --version output version - --port set port - - Exemples: - - json-server db.json - json-server seed.js - json-server http://example.com/db.json - +Options: + --help, -h Show help + --version, -v Show version number + --port, -p Set port [default: 3000] ``` #### Input @@ -97,10 +93,10 @@ Here's 2 examples showing how to format JSON or JS seed file: } ``` -* __seed.js__ +* __file.js__ ```javascript -exports.run = function() { +module.exports = function() { var data = {}; data.posts = []; @@ -111,7 +107,7 @@ exports.run = function() { } ``` -JSON Server expects JS files to export a ```run``` method that returns an object. +JSON Server expects JS files to export a function that returns an object. Seed files are useful if you need to programmaticaly create a lot of data. @@ -159,4 +155,4 @@ Returns default index file or content of ./public/index.html (useful if you need ## Links * [Fast prototyping using Restangular and Json-server](http://bahmutov.calepin.co/fast-prototyping-using-restangular-and-json-server.html) -* [Grunt plugin](https://github.com/tfiwm/grunt-json-server) +* [grunt plugin](https://github.com/tfiwm/grunt-json-server) \ No newline at end of file diff --git a/bin/index.js b/bin/index.js index 9ae5ab7..004f4f7 100755 --- a/bin/index.js +++ b/bin/index.js @@ -1,20 +1,74 @@ #!/usr/bin/env node -var minimist = require('minimist') var updateNotifier = require('update-notifier') -var cli = require('../src/cli') +var _db = require('underscore-db') +var yargs = require('yargs') +var chalk = require('chalk') +var got = require('got') +var pkg = require('../package.json') +var server = require('../src') -var notifier = updateNotifier({packagePath: '../package'}) -if (notifier.update) notifier.notify() +updateNotifier({packageName: pkg.name, packageVersion: pkg.version}).notify() -var argv = minimist(process.argv.slice(2), { - boolean: ["silent"], - alias: { - 'p': 'port', - 's': 'silent' - }, - default: { - silent: false +var argv = yargs + .usage('$0 ') + .help('help').alias('help', 'h') + .version(pkg.version, 'version').alias('version', 'v') + .options({ + port: { + alias: 'p', + description: 'Set port', + default: 3000 } -}) + }) + .example('$0 db.json', '') + .example('$0 file.js', '') + .example('$0 http://example.com/db.json', '') + .require(1, 'Missing argument') + .argv -cli.run(argv) +function start(object, filename) { + for (var prop in object) { + console.log('http://localhost:' + port + '/' + chalk.green(prop)) + } + + console.log( + '\nEnter ' + chalk.green('`s`') + ' at any time to create a snapshot of the db\n' + ) + + process.stdin.resume() + process.stdin.setEncoding('utf8') + process.stdin.on('data', function (chunk) { + if (chunk.trim().toLowerCase() === 's') { + var file = 'db-' + Date.now() + '.json' + _db.save(object, filename) + console.log('\nSaved snapshot to ' + chalk.green(file) + '\n') + } + }) + + server(object, filename).listen(port) +} + +var source = argv._[0] +var port = process.env.PORT || argv.port + +console.log(chalk.green('\n{^ ^} Yo!\n')) +console.log('Loading database from ' + source + '\n') + +if (/\.json$/.test(source)) { + var filename = process.cwd() + '/' + source + var object = require(filename) + start(object, filename) +} + +if (/\.js$/.test(source)) { + var object = require(process.cwd() + '/' + source)() + start(object) +} + +if (/^http/.test(source)) { + got(source, function(err, data) { + if (err) throw err + var object = JSON.parse(data) + start(object) + }) +} \ No newline at end of file diff --git a/package.json b/package.json index c686c40..38f3656 100644 --- a/package.json +++ b/package.json @@ -12,17 +12,18 @@ "chalk": "^0.4.0", "cors": "^2.3.0", "errorhandler": "^1.2.0", - "express": "^4.9.0", - "lowdb": "^0.3.0", + "express": "^4.9.5", + "got": "^1.2.2", + "lowdb": "^0.4.2", "method-override": "^2.1.2", - "minimist": "0.0.8", "morgan": "^1.3.1", "serve-static": "^1.6.1", - "superagent": "~0.15.7", - "underscore": "~1.5.2", + "superagent": "^0.15.7", + "underscore": "^1.5.2", + "underscore-db": "^0.8.0", "underscore.inflections": "~0.2.1", - "update-notifier": "^0.1.8", - "yargs": "^1.2.1" + "update-notifier": "^0.2.2", + "yargs": "^1.3.1" }, "devDependencies": { "supertest": "~0.8.1", diff --git a/public/index.html b/public/index.html index 025f97f..f258dde 100644 --- a/public/index.html +++ b/public/index.html @@ -52,7 +52,7 @@

Issues

-

Please go +

Please go here.

diff --git a/src/cli.js b/src/cli.js deleted file mode 100644 index 4869115..0000000 --- a/src/cli.js +++ /dev/null @@ -1,90 +0,0 @@ -var fs = require('fs') -var chalk = require('chalk') -var minimist = require('minimist') -var request = require('superagent') -var low = require('lowdb') -var server = require('./server') - -// Output version -function version() { - var pkg = require('../package.json') - console.log(pkg.version) -} - -// Output help.txt with some colors -function help() { - var txt = fs.readFileSync(__dirname + '/help.txt').toString() - txt = txt.replace(/json-server/g, chalk.green('json-server')) - console.log(txt) -} - -// Start server -function start(port, silent) { - for (var prop in low.db) { - console.log('http://localhost:' + port + '/' + chalk.green(prop)) - } - - if(!silent) { - console.log( - '\nEnter ' + chalk.green('`s`') + ' at any time to create a snapshot of the db\n' - ) - process.stdin.resume() - process.stdin.setEncoding('utf8') - process.stdin.on('data', function (chunk) { - if (chunk.trim().toLowerCase() === 's') { - var file = 'db-' + Date.now() + '.json' - low.save(file) - console.log('\nSaved snapshot to ' + chalk.green(file) + '\n') - } - }) - } - - server.listen(port) -} - -// Load source -function load(source, port, silent) { - console.log(chalk.green('\n{^ ^} Heya!\n')) - - console.log('Loading database from ' + source + '\n') - - if (/\.json$/.test(source)) { - var path = process.cwd() + '/' + source - low.path = path - low.db = require(path); - start(port, silent) - } - - if (/\.js$/.test(source)) { - var path = process.cwd() + '/' + source - low.db = require(path).run(); - start(port, silent) - } - - if (/^http/.test(source)) { - request - .get(source) - .end(function(err, res) { - if (err) { - console.error(err) - } else { - low.db = JSON.parse(res.text) - start(port, silent) - } - }) - } -} - -// Uses minimist parsed argv -function run(argv) { - var source = argv._[0] - var port = argv.port || 3000 - var silent = argv.silent - - if (argv.version) return version() - if (source) return load(source, port, silent) - - help() -} - -module.exports.run = run diff --git a/src/create-routes.js b/src/create-routes.js new file mode 100644 index 0000000..82b0f40 --- /dev/null +++ b/src/create-routes.js @@ -0,0 +1,169 @@ +var _ = require('underscore') +var low = require('lowdb') +var _db = require('underscore-db') +var _inflections = require('underscore.inflections') +var utils = require('./utils') + +low.mixin(_db) +low.mixin(_inflections) + +module.exports = function(object, filename) { + if (filename) { + var db = low(filename) + } else { + var db = low() + _.extend(db.object, object) + } + + return { + // GET /db + showDatabase: function(req, res, next) { + res.jsonp(db.object) + }, + + // GET /:resource + // GET /:resource?q= + // GET /:resource?attr=&attr= + // GET /:parent/:parentId/:resource?attr=&attr= + // GET /*?*&_end= + // GET /*?*&_start=&_end= + list: function(req, res, next) { + // Filters list + var filters = {} + + // Result array + var array + + // Remove _start and _end from req.query to avoid filtering using those + // parameters + var _start = req.query._start + var _end = req.query._end + var _sort = req.query._sort + var _sortDir = req.query._sortDir + + delete req.query._start + delete req.query._end + delete req.query._sort + delete req.query._sortDir + + if (req.query.q) { + + // Full-text search + var q = req.query.q.toLowerCase() + + array = db(req.params.resource).where(function(obj) { + for (var key in obj) { + var value = obj[key] + if (_.isString(value) && value.toLowerCase().indexOf(q) !== -1) { + return true + } + } + }).value() + + } else { + + // Add :parentId filter in case URL is like /:parent/:parentId/:resource + if (req.params.parent) { + filters[req.params.parent.slice(0, - 1) + 'Id'] = +req.params.parentId + } + + // Add query parameters filters + // Convert query parameters to their native counterparts + for (var key in req.query) { + if (key !== 'callback') { + filters[key] = utils.toNative(req.query[key]) + } + } + + // Filter + if (_(filters).isEmpty()) { + array = db(req.params.resource).value() + } else { + array = db(req.params.resource).where(filters).value() + } + } + + if(_sort) { + _sortDir = _sortDir || 'ASC' + + array = _.sortBy(array, function(element) { + return element[_sort]; + }) + + if (_sortDir === 'DESC') { + array.reverse(); + } + } + + // Slice result + if (_end) { + res.setHeader('X-Total-Count', array.length) + res.setHeader('Access-Control-Expose-Headers', 'X-Total-Count') + + _start = _start || 0 + + array = array.slice(_start, _end) + } + + res.jsonp(array) + }, + + // GET /:resource/:id + show: function(req, res, next) { + var resource = db(req.params.resource) + .get(+req.params.id) + .value() + + if (resource) { + res.jsonp(resource) + } else { + res.status(404).jsonp({}) + } + }, + + // POST /:resource + create: function(req, res, next) { + for (var key in req.body) { + req.body[key] = utils.toNative(req.body[key]) + } + + var resource = db(req.params.resource) + .insert(req.body) + .value() + + res.jsonp(resource) + }, + + // PUT /:resource/:id + // PATCH /:resource/:id + update: function(req, res, next) { + for (var key in req.body) { + req.body[key] = utils.toNative(req.body[key]) + } + + var resource = db(req.params.resource) + .update(+req.params.id, req.body) + .value() + + if (resource) { + res.jsonp(resource) + } else { + res.status(404).jsonp({}) + } + }, + + // DELETE /:resource/:id + destroy: function(req, res, next) { + db(req.params.resource).remove(+req.params.id) + + // Remove dependents documents + var removable = utils.getRemovable(db.object) + + _(removable).each(function(item) { + db(item.name).remove(item.id) + }) + + res.status(204).end() + } + } +} diff --git a/src/help.txt b/src/help.txt deleted file mode 100644 index 06fb12b..0000000 --- a/src/help.txt +++ /dev/null @@ -1,14 +0,0 @@ - - Usage: json-server [options] - - Options: - - --version output version - --port set port - - Exemples: - - json-server db.json - json-server seed.js - json-server http://example.com/db.json - \ No newline at end of file diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..5980b0c --- /dev/null +++ b/src/index.js @@ -0,0 +1,69 @@ +var fs = require('fs') +var path = require('path') + +// LowDB +var low = require('lowdb') +var _db = require('underscore-db') +var _inflections = require('underscore.inflections') + +low.mixin('_db') +low.mixin('_inflections') + +// Express +var http = require('http') +var express = require('express') +var logger = require('morgan') +var cors = require('cors') +var methodOverride = require('method-override') +var bodyParser = require('body-parser') +var serveStatic = require('serve-static') +var errorhandler = require('errorhandler') + +// json-server +var utils = require('./utils') +var createRoutes = require('./create-routes') + +low.mixin({ createId: utils.createId }) + +module.exports = function(object, filename) { + var server = express() + var routes = createRoutes(object, filename) + + // Don't use logger if json-server is mounted + if (!module.parent) { + server.use(logger('dev')) + } + + server.use(bodyParser.json()) + server.use(bodyParser.urlencoded({ extended: false })) + server.use(methodOverride()) + + if (fs.existsSync(process.cwd() + '/public')) { + server.use(serveStatic(process.cwd() + '/public')); + } else { + server.use(serveStatic(path.join(__dirname, './public'))); + } + + server.use(cors({ origin: true, credentials: true })) + + server.get('/db', routes.showDatabase) + + server.route('/:resource') + .get(routes.list) + .post(routes.create) + + server.route('/:resource/:id') + .get(routes.show) + .put(routes.update) + .patch(routes.update) + .delete(routes.destroy) + + server.get('/:parent/:parentId/:resource', routes.list) + + if (process.env.NODE_ENV === 'development') { + // only use in development + server.use(errorhandler()) + } + + return server +} \ No newline at end of file diff --git a/src/routes.js b/src/routes.js deleted file mode 100644 index 7c3941b..0000000 --- a/src/routes.js +++ /dev/null @@ -1,158 +0,0 @@ -var _ = require('underscore') -var low = require('lowdb') -var utils = require('./utils') - -var routes = {} - -// GET /db -routes.db = function(req, res, next) { - res.jsonp(low.db) -} - -// GET /:resource -// GET /:resource?q= -// GET /:resource?attr=&attr= -// GET /:parent/:parentId/:resource?attr=&attr= -// GET /*?*&_end= -// GET /*?*&_start=&_end= -routes.list = function(req, res, next) { - - // Filters list - var filters = {} - - // Result array - var array - - // Remove _start and _end from req.query to avoid filtering using those - // parameters - var _start = req.query._start - var _end = req.query._end - var _sort = req.query._sort - var _sortDir = req.query._sortDir - - delete req.query._start - delete req.query._end - delete req.query._sort - delete req.query._sortDir - - if (req.query.q) { - - // Full-text search - var q = req.query.q.toLowerCase() - - array = low(req.params.resource).where(function(obj) { - for (var key in obj) { - var value = obj[key] - if (_.isString(value) && value.toLowerCase().indexOf(q) !== -1) { - return true - } - } - }).value() - - } else { - - // Add :parentId filter in case URL is like /:parent/:parentId/:resource - if (req.params.parent) { - filters[req.params.parent.slice(0, - 1) + 'Id'] = +req.params.parentId - } - - // Add query parameters filters - // Convert query parameters to their native counterparts - for (var key in req.query) { - if (key !== 'callback') { - filters[key] = utils.toNative(req.query[key]) - } - } - - // Filter - if (_(filters).isEmpty()) { - array = low(req.params.resource).value() - } else { - array = low(req.params.resource).where(filters).value() - } - } - - if(_sort) { - _sortDir = _sortDir || 'ASC' - - array = _.sortBy(array, function(element) { - return element[_sort]; - }) - - if (_sortDir === 'DESC') { - array.reverse(); - } - } - - // Slice result - if (_end) { - res.setHeader('X-Total-Count', array.length) - res.setHeader('Access-Control-Expose-Headers', 'X-Total-Count') - - _start = _start || 0 - - array = array.slice(_start, _end) - } - - res.jsonp(array) -} - -// GET /:resource/:id -routes.show = function(req, res, next) { - var resource = low(req.params.resource) - .get(+req.params.id) - .value() - - if (resource) { - res.jsonp(resource) - } else { - res.status(404).jsonp({}) - } -} - -// POST /:resource -routes.create = function(req, res, next) { - for (var key in req.body) { - req.body[key] = utils.toNative(req.body[key]) - } - - var resource = low(req.params.resource) - .insert(req.body) - .value() - - res.jsonp(resource) -} - -// PUT /:resource/:id -// PATCH /:resource/:id -routes.update = function(req, res, next) { - for (var key in req.body) { - req.body[key] = utils.toNative(req.body[key]) - } - - var resource = low(req.params.resource) - .update(+req.params.id, req.body) - .value() - - if (resource) { - res.jsonp(resource) - } else { - res.status(404).jsonp({}) - } -} - -// DELETE /:resource/:id -routes.destroy = function(req, res, next) { - low(req.params.resource).remove(+req.params.id) - - // Remove dependents documents - var removable = utils.getRemovable(low.db) - - _(removable).each(function(item) { - low(item[0]).remove(item[1]); - }) - - res.status(204).end() -} - -module.exports = routes diff --git a/src/server.js b/src/server.js deleted file mode 100644 index c3fbdfb..0000000 --- a/src/server.js +++ /dev/null @@ -1,60 +0,0 @@ -var fs = require('fs') -var path = require('path') -var http = require('http') -var express = require('express') -var logger = require('morgan') -var cors = require('cors') -var methodOverride = require('method-override') -var bodyParser = require('body-parser') -var serveStatic = require('serve-static') -var errorhandler = require('errorhandler') -var low = require('lowdb') - -var utils = require('./utils') -var routes = require('./routes') - -low._.createId = utils.createId - -var server = express() - -server.set('port', process.env.PORT || 3000) - -// Don't use logger if json-server is mounted -if (!module.parent) { - server.use(logger('dev')) -} - -server.use(bodyParser.json()) -server.use(bodyParser.urlencoded({ extended: false })) -server.use(methodOverride()) - -if (fs.existsSync(process.cwd() + '/public')) { - server.use(serveStatic(process.cwd() + '/public')); -} else { - server.use(serveStatic(path.join(__dirname, './public'))); -} - -server.use(cors({ origin: true, credentials: true })) - -server.get('/db', routes.db) - -server.route('/:resource') - .get(routes.list) - .post(routes.create) - -server.route('/:resource/:id') - .get(routes.show) - .put(routes.update) - .patch(routes.update) - .delete(routes.destroy) - -server.get('/:parent/:parentId/:resource', routes.list) - -if (process.env.NODE_ENV === 'development') { - // only use in development - server.use(errorhandler()) -} - -server.low = low - -module.exports = server \ No newline at end of file diff --git a/src/utils.js b/src/utils.js index 0c2124a..00177fd 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,7 +1,6 @@ -var low = require('lowdb') var _ = require('underscore') -_.mixin(require('underscore.inflections')) - +var _inflections = require('underscore.inflections') +_.mixin(_inflections) // Turns string to native. // Example: @@ -42,7 +41,7 @@ function getRemovable(db) { var refName = _.pluralize(key.slice(0, - 2)) var ref = _.findWhere(db[refName], {id: value}) if (_.isUndefined(ref)) { - removable.push([collName, doc.id]) + removable.push({ name: collName, id: doc.id }) } } }) diff --git a/test/server.js b/test/index.js similarity index 86% rename from test/server.js rename to test/index.js index 8bcd946..a993a89 100644 --- a/test/server.js +++ b/test/index.js @@ -1,31 +1,35 @@ var request = require('supertest') var assert = require('assert') -var low = require('lowdb') -var server = require('../src/server') +var jsonServer = require('../src/') describe('Server', function() { - beforeEach(function() { - low.db = {} + var server + var db - low.db.posts = [ + beforeEach(function() { + db = {} + + db.posts = [ {id: 1, body: 'foo'}, {id: 2, body: 'bar'} ] - low.db.tags = [ + db.tags = [ {id: 1, body: 'Technology'}, {id: 2, body: 'Photography'}, {id: 3, body: 'photo'} ] - low.db.comments = [ + db.comments = [ {id: 1, published: true, postId: 1}, {id: 2, published: false, postId: 1}, {id: 3, published: false, postId: 2}, {id: 4, published: false, postId: 2}, {id: 5, published: false, postId: 2}, ] + + server = jsonServer(db) }) describe('GET /db', function() { @@ -33,7 +37,7 @@ describe('Server', function() { request(server) .get('/db') .expect('Content-Type', /json/) - .expect(low.db) + .expect(db) .expect(200, done) }) }) @@ -46,7 +50,7 @@ describe('Server', function() { .expect('Content-Type', /json/) .expect('Access-Control-Allow-Credentials', 'true') .expect('Access-Control-Allow-Origin', 'http://example.com') - .expect(low.db.posts) + .expect(db.posts) .expect(200, done) }) }) @@ -56,7 +60,7 @@ describe('Server', function() { request(server) .get('/comments?postId=1&published=true') .expect('Content-Type', /json/) - .expect([low.db.comments[0]]) + .expect([db.comments[0]]) .expect(200, done) }) }) @@ -66,7 +70,7 @@ describe('Server', function() { request(server) .get('/tags?q=pho') .expect('Content-Type', /json/) - .expect([low.db.tags[1], low.db.tags[2]]) + .expect([db.tags[1], db.tags[2]]) .expect(200, done) }) @@ -84,9 +88,9 @@ describe('Server', function() { request(server) .get('/comments?_end=2') .expect('Content-Type', /json/) - .expect('x-total-count', low.db.comments.length.toString()) + .expect('x-total-count', db.comments.length.toString()) .expect('Access-Control-Expose-Headers', 'X-Total-Count') - .expect(low.db.comments.slice(0, 2)) + .expect(db.comments.slice(0, 2)) .expect(200, done) }) }) @@ -96,7 +100,7 @@ describe('Server', function() { request(server) .get('/tags?_sort=body') .expect('Content-Type', /json/) - .expect([low.db.tags[1], low.db.tags[0], low.db.tags[2]]) + .expect([db.tags[1], db.tags[0], db.tags[2]]) .expect(200, done) }) @@ -104,7 +108,7 @@ describe('Server', function() { request(server) .get('/tags?_sort=body&_sortDir=DESC') .expect('Content-Type', /json/) - .expect([low.db.tags[2], low.db.tags[0], low.db.tags[1]]) + .expect([db.tags[2], db.tags[0], db.tags[1]]) .expect(200, done) }) @@ -112,7 +116,7 @@ describe('Server', function() { request(server) .get('/posts?_sort=id&_sortDir=DESC') .expect('Content-Type', /json/) - .expect(low.db.posts.reverse()) + .expect(db.posts.reverse()) .expect(200, done) }) }) @@ -122,9 +126,9 @@ describe('Server', function() { request(server) .get('/comments?_start=1&_end=2') .expect('Content-Type', /json/) - .expect('x-total-count', low.db.comments.length.toString()) + .expect('x-total-count', db.comments.length.toString()) .expect('Access-Control-Expose-Headers', 'X-Total-Count') - .expect(low.db.comments.slice(1, 2)) + .expect(db.comments.slice(1, 2)) .expect(200, done) }) }) @@ -135,8 +139,8 @@ describe('Server', function() { .get('/posts/1/comments') .expect('Content-Type', /json/) .expect([ - low.db.comments[0], - low.db.comments[1] + db.comments[0], + db.comments[1] ]) .expect(200, done) }) @@ -147,7 +151,7 @@ describe('Server', function() { request(server) .get('/posts/1') .expect('Content-Type', /json/) - .expect(low.db.posts[0]) + .expect(db.posts[0]) .expect(200, done) }) @@ -171,7 +175,7 @@ describe('Server', function() { .expect(200) .end(function(err, res){ if (err) return done(err) - assert.equal(low.db.posts.length, 3) + assert.equal(db.posts.length, 3) done() }) }) @@ -188,7 +192,7 @@ describe('Server', function() { .end(function(err, res){ if (err) return done(err) // assert it was created in database too - assert.deepEqual(low.db.posts[0], {id: 1, body: 'bar', booleanValue: true, integerValue: 1}) + assert.deepEqual(db.posts[0], {id: 1, body: 'bar', booleanValue: true, integerValue: 1}) done() }) }) @@ -214,7 +218,7 @@ describe('Server', function() { .end(function(err, res){ if (err) return done(err) // assert it was created in database too - assert.deepEqual(low.db.posts[0], {id: 1, body: 'bar'}) + assert.deepEqual(db.posts[0], {id: 1, body: 'bar'}) done() }) }) @@ -236,8 +240,8 @@ describe('Server', function() { .expect(204) .end(function(err, res){ if (err) return done(err) - assert.equal(low.db.posts.length, 1) - assert.equal(low.db.comments.length, 3) + assert.equal(db.posts.length, 1) + assert.equal(db.comments.length, 3) done() }) }) diff --git a/test/utils.js b/test/utils.js index 32b71f5..5753c16 100644 --- a/test/utils.js +++ b/test/utils.js @@ -2,11 +2,11 @@ var assert = require('assert') var utils = require('../src/utils') describe('utils', function() { - + describe('getRemovable', function() { it('should return removable documents', function() { - + var db = { posts: [ {id: 1, comment: 1} @@ -20,8 +20,8 @@ describe('utils', function() { } var expected = [ - ['comments', 2], - ['comments', 3] + { name: 'comments', id: 2 }, + { name: 'comments', id: 3 } ] assert.deepEqual(expected, utils.getRemovable(db)) @@ -39,7 +39,7 @@ describe('utils', function() { assert.strictEqual(utils.toNative('string'), 'string') assert.strictEqual(utils.toNative(1), 1) assert.strictEqual(utils.toNative(true), true) - + }) })