From 571e4942cd6a76313af47e19e91b1d15ede66350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franc=CC=A7ois=20Hodierne?= Date: Wed, 27 Mar 2019 09:47:22 +0100 Subject: [PATCH] prettier --- .prettierrc | 3 + .travis.yml | 8 +- README.md | 26 ++-- index.d.ts | 14 +- index.js | 114 +++++++++----- package.json | 20 ++- test/test.js | 424 +++++++++++++++++++++++++++++---------------------- 7 files changed, 357 insertions(+), 252 deletions(-) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..544138b --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "singleQuote": true +} diff --git a/.travis.yml b/.travis.yml index f2b2cf6..fc14e2e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: - - "9.0" - - "8.0" - - "7.0" - - "6.0" + - '9.0' + - '8.0' + - '7.0' + - '6.0' diff --git a/README.md b/README.md index 36cbd18..fc045cc 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,12 @@ -Historical tables for Sequelize -=============================== +# Historical tables for Sequelize Warning: this is a fork of [sequelize-temporal](https://github.com/bonaval/sequelize-temporal) that adds support for Sequelize 5. [![Build Status](https://travis-ci.org/opencollective/sequelize-historical.svg?branch=master)](https://travis-ci.org/opencollective/sequelize-historical) [![Dependency Status](https://david-dm.org/opencollective/sequelize-historical.svg)](https://david-dm.org/opencollective/sequelize-historical) [![NPM version](https://img.shields.io/npm/v/sequelize-historical.svg)](https://www.npmjs.com/package/sequelize-historical) [![Greenkeeper badge](https://badges.greenkeeper.io/opencollective/sequelize-historical.svg)](https://greenkeeper.io/) +## What is it? -What is it? ------------ - -Historical tables maintain __historical versions__ of data. Modifying operations (UPDATE, DELETE) on these tables don't cause permanent changes to entries, but create new versions of them. Hence this might be used to: +Historical tables maintain **historical versions** of data. Modifying operations (UPDATE, DELETE) on these tables don't cause permanent changes to entries, but create new versions of them. Hence this might be used to: - log changes (security/auditing) - undo functionalities @@ -22,15 +19,13 @@ The normal singular/plural naming scheme in Sequelize is used: - model name: `modelName + History` - table name: `modelName + Histories` -Installation ------------- +## Installation ``` npm install sequelize-historical ``` -How to use ----------- +## How to use ### 1) Import `sequelize-historical` @@ -48,7 +43,7 @@ var sequelize = new Sequelize('', '', '', { }); ``` -### 2) Add the *historical* feature to your models +### 2) Add the _historical_ feature to your models ``` var User = Historical(sequelize.define('User'), sequelize); @@ -62,8 +57,7 @@ var User = sequelize.define('User', {.types.}, {.options.}); // Sequelize Docu Historical(User, sequelize); ``` -Options -------- +## Options The default syntax for `Historical` is: @@ -84,8 +78,7 @@ whereas the options are listed here (with default value). full: false ``` -Details --------- +## Details @See: https://wiki.postgresql.org/wiki/SQL2011Temporal @@ -101,8 +94,7 @@ Triggers for storing old versions of rows to history table are inspired by refer If you only use Postgres, you might want to have a look at the [Temporal Table](https://github.com/arkhipov/temporal_tables) extension. -License -------- +## License The MIT License (MIT) diff --git a/index.d.ts b/index.d.ts index fc74696..cfd61c9 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,10 +1,10 @@ -declare module 'sequelize-temporal' { - interface Options { - blocking?:boolean, - full?:boolean - } +declare module 'sequelize-temporal' { + interface Options { + blocking?: boolean; + full?: boolean; + } - function output(define:T, sequelize:any, options?:Options): T + function output(define: T, sequelize: any, options?: Options): T; - export = output; + export = output; } diff --git a/index.js b/index.js index 2f7714b..7e5236d 100644 --- a/index.js +++ b/index.js @@ -7,13 +7,13 @@ var temporalDefaultOptions = { full: false }; -var excludeAttributes = function(obj, attrsToExclude){ +var excludeAttributes = function(obj, attrsToExclude) { // fancy way to exclude attributes - return _.omit(obj, _.partial(_.rearg(_.contains,0,2,1), attrsToExclude)); -} + return _.omit(obj, _.partial(_.rearg(_.contains, 0, 2, 1), attrsToExclude)); +}; -var Temporal = function(model, sequelize, temporalOptions){ - temporalOptions = _.extend({},temporalDefaultOptions, temporalOptions); +var Temporal = function(model, sequelize, temporalOptions) { + temporalOptions = _.extend({}, temporalDefaultOptions, temporalOptions); var Sequelize = sequelize.Sequelize; @@ -23,8 +23,8 @@ var Temporal = function(model, sequelize, temporalOptions){ var historyOwnAttrs = { hid: { - type: Sequelize.BIGINT, - primaryKey: true, + type: Sequelize.BIGINT, + primaryKey: true, autoIncrement: true, unique: true }, @@ -35,55 +35,89 @@ var Temporal = function(model, sequelize, temporalOptions){ } }; - var excludedAttributes = ["Model","unique","primaryKey","autoIncrement", "set", "get", "_modelAttribute"]; - var historyAttributes = _(model.rawAttributes).mapValues(function(v){ - v = excludeAttributes(v, excludedAttributes); - // remove the "NOW" defaultValue for the default timestamps - // we want to save them, but just a copy from our master record - if(v.fieldName == "createdAt" || v.fieldName == "updatedAt"){ - v.type = Sequelize.DATE; - } - return v; - }).assign(historyOwnAttrs).value(); + var excludedAttributes = [ + 'Model', + 'unique', + 'primaryKey', + 'autoIncrement', + 'set', + 'get', + '_modelAttribute' + ]; + var historyAttributes = _(model.rawAttributes) + .mapValues(function(v) { + v = excludeAttributes(v, excludedAttributes); + // remove the "NOW" defaultValue for the default timestamps + // we want to save them, but just a copy from our master record + if (v.fieldName == 'createdAt' || v.fieldName == 'updatedAt') { + v.type = Sequelize.DATE; + } + return v; + }) + .assign(historyOwnAttrs) + .value(); // If the order matters, use this: //historyAttributes = _.assign({}, historyOwnAttrs, historyAttributes); var historyOwnOptions = { timestamps: false }; - var excludedNames = ["name", "tableName", "sequelize", "uniqueKeys", "hasPrimaryKey", "hooks", "scopes", "instanceMethods", "defaultScope"]; + var excludedNames = [ + 'name', + 'tableName', + 'sequelize', + 'uniqueKeys', + 'hasPrimaryKey', + 'hooks', + 'scopes', + 'instanceMethods', + 'defaultScope' + ]; var modelOptions = excludeAttributes(model.options, excludedNames); var historyOptions = _.assign({}, modelOptions, historyOwnOptions); - + // We want to delete indexes that have unique constraint var indexes = historyOptions.indexes; - if(Array.isArray(indexes)){ - historyOptions.indexes = indexes.filter(function(index){return !index.unique && index.type != 'UNIQUE';}); + if (Array.isArray(indexes)) { + historyOptions.indexes = indexes.filter(function(index) { + return !index.unique && index.type != 'UNIQUE'; + }); } - var modelHistory = sequelize.define(historyName, historyAttributes, historyOptions); + var modelHistory = sequelize.define( + historyName, + historyAttributes, + historyOptions + ); // we already get the updatedAt timestamp from our models - var insertHook = function(obj, options){ - var dataValues = (!temporalOptions.full && obj._previousDataValues) || obj.dataValues; - var historyRecord = modelHistory.create(dataValues, {transaction: options.transaction}); - if(temporalOptions.blocking){ + var insertHook = function(obj, options) { + var dataValues = + (!temporalOptions.full && obj._previousDataValues) || obj.dataValues; + var historyRecord = modelHistory.create(dataValues, { + transaction: options.transaction + }); + if (temporalOptions.blocking) { return historyRecord; } - } - var insertBulkHook = function(options){ - if(!options.individualHooks){ - var queryAll = model.findAll({where: options.where, transaction: options.transaction}).then(function(hits){ - if(hits){ - hits = _.pluck(hits, 'dataValues'); - return modelHistory.bulkCreate(hits, {transaction: options.transaction}); - } - }); - if(temporalOptions.blocking){ + }; + var insertBulkHook = function(options) { + if (!options.individualHooks) { + var queryAll = model + .findAll({ where: options.where, transaction: options.transaction }) + .then(function(hits) { + if (hits) { + hits = _.pluck(hits, 'dataValues'); + return modelHistory.bulkCreate(hits, { + transaction: options.transaction + }); + } + }); + if (temporalOptions.blocking) { return queryAll; } } - } + }; // use `after` to be nonBlocking // all hooks just create a copy @@ -100,8 +134,10 @@ var Temporal = function(model, sequelize, temporalOptions){ model.addHook('beforeBulkUpdate', insertBulkHook); model.addHook('beforeBulkDestroy', insertBulkHook); - var readOnlyHook = function(){ - throw new Error("This is a read-only history database. You aren't allowed to modify it."); + var readOnlyHook = function() { + throw new Error( + "This is a read-only history database. You aren't allowed to modify it." + ); }; modelHistory.addHook('beforeUpdate', readOnlyHook); diff --git a/package.json b/package.json index d370b51..b4a0c1e 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,11 @@ "test": "test" }, "scripts": { - "test": "mocha" + "test": "mocha", + "pretest": "npm run prettier:check", + "prettier": "prettier \"**/*.@(js|json|md|yml|ts)\"", + "prettier:write": "npm run prettier -- --write", + "prettier:check": "npm run prettier -- --list-different" }, "repository": { "type": "git", @@ -34,8 +38,22 @@ "devDependencies": { "chai": "^4.2.0", "chai-as-promised": "^7.1.1", + "husky": "^1.3.1", + "lint-staged": "^8.1.5", "mocha": "^6.0.2", + "prettier": "^1.16.4", "sequelize": "^5.2.1", "sqlite3": "^4.0.6" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "*.{js,json,md,yml,ts}": [ + "prettier --write", + "git add" + ] } } diff --git a/test/test.js b/test/test.js index 0a7bc5c..2dddc8a 100644 --- a/test/test.js +++ b/test/test.js @@ -1,23 +1,26 @@ var Temporal = require('../'); var Sequelize = require('sequelize'); -var chai = require("chai"); -var chaiAsPromised = require("chai-as-promised"); +var chai = require('chai'); +var chaiAsPromised = require('chai-as-promised'); chai.use(chaiAsPromised); var assert = chai.assert; var eventually = assert.eventually; -describe('Read-only API', function(){ +describe('Read-only API', function() { var sequelize, User, UserHistory; - function freshDB(){ + function freshDB() { // overwrites the old SQLite DB sequelize = new Sequelize('', '', '', { dialect: 'sqlite', storage: __dirname + '/.test.sqlite' }); - User = Temporal(sequelize.define('User', { - name: Sequelize.TEXT - }), sequelize); + User = Temporal( + sequelize.define('User', { + name: Sequelize.TEXT + }), + sequelize + ); UserHistory = sequelize.models.UserHistory; return sequelize.sync({ force: true }); } @@ -27,229 +30,275 @@ describe('Read-only API', function(){ dialect: 'sqlite', storage: __dirname + '/.test.sqlite' }); - User = Temporal(sequelize.define('User', { - name: Sequelize.TEXT - }, { paranoid: true }), sequelize, { full: true }); + User = Temporal( + sequelize.define( + 'User', + { + name: Sequelize.TEXT + }, + { paranoid: true } + ), + sequelize, + { full: true } + ); UserHistory = sequelize.models.UserHistory; return sequelize.sync({ force: true }); } - function assertCount(modelHistory, n, opts){ + function assertCount(modelHistory, n, opts) { // wrapped, chainable promise - return function(obj){ - return modelHistory.count(opts).then(function(count){ - assert.equal(n, count, "history entries") + return function(obj) { + return modelHistory.count(opts).then(function(count) { + assert.equal(n, count, 'history entries'); return obj; }); - } + }; } - describe('hooks', function(){ + describe('hooks', function() { beforeEach(freshDB); - it('onCreate: should not store the new version in history db' , function(){ + it('onCreate: should not store the new version in history db', function() { return User.create({ name: 'test' }).then(assertCount(UserHistory, 0)); }); - it('onUpdate/onDestroy: should save to the historyDB' , function(){ + it('onUpdate/onDestroy: should save to the historyDB', function() { return User.create() - .then(assertCount(UserHistory,0)) - .then(function(user){ - user.name = "foo"; - return user.save(); - }).then(assertCount(UserHistory,1)) - .then(function(user){ - return user.destroy(); - }).then(assertCount(UserHistory,2)) + .then(assertCount(UserHistory, 0)) + .then(function(user) { + user.name = 'foo'; + return user.save(); + }) + .then(assertCount(UserHistory, 1)) + .then(function(user) { + return user.destroy(); + }) + .then(assertCount(UserHistory, 2)); }); - it('onUpdate: should store the previous version to the historyDB' , function(){ - return User.create({name: "foo"}) - .then(assertCount(UserHistory,0)) - .then(function(user){ - user.name = "bar"; - return user.save(); - }).then(assertCount(UserHistory,1)) - .then(function(){ - return UserHistory.findAll(); - }).then(function(users){ - assert.equal(users.length,1, "only one entry in DB"); - assert.equal(users[0].name, "foo", "previous entry saved"); - }).then(function(user){ - return User.findOne(); - }).then(function(user){ - return user.destroy(); - }).then(assertCount(UserHistory,2)) + it('onUpdate: should store the previous version to the historyDB', function() { + return User.create({ name: 'foo' }) + .then(assertCount(UserHistory, 0)) + .then(function(user) { + user.name = 'bar'; + return user.save(); + }) + .then(assertCount(UserHistory, 1)) + .then(function() { + return UserHistory.findAll(); + }) + .then(function(users) { + assert.equal(users.length, 1, 'only one entry in DB'); + assert.equal(users[0].name, 'foo', 'previous entry saved'); + }) + .then(function(user) { + return User.findOne(); + }) + .then(function(user) { + return user.destroy(); + }) + .then(assertCount(UserHistory, 2)); }); - it('onDelete: should store the previous version to the historyDB' , function(){ - return User.create({name: "foo"}) - .then(assertCount(UserHistory,0)) - .then(function(user){ - return user.destroy(); - }).then(assertCount(UserHistory,1)) - .then(function(){ - return UserHistory.findAll(); - }).then(function(users){ - assert.equal(users.length,1, "only one entry in DB"); - assert.equal(users[0].name, "foo", "previous entry saved"); - }); + it('onDelete: should store the previous version to the historyDB', function() { + return User.create({ name: 'foo' }) + .then(assertCount(UserHistory, 0)) + .then(function(user) { + return user.destroy(); + }) + .then(assertCount(UserHistory, 1)) + .then(function() { + return UserHistory.findAll(); + }) + .then(function(users) { + assert.equal(users.length, 1, 'only one entry in DB'); + assert.equal(users[0].name, 'foo', 'previous entry saved'); + }); }); }); - describe('transactions', function(){ + describe('transactions', function() { beforeEach(freshDB); - it('revert on failed transactions' , function(){ - return sequelize.transaction().then(function(t){ - var opts = {transaction: t}; - return User.create(opts) - .then(assertCount(UserHistory,0, opts)) - .then(function(user){ - user.name = "foo"; - return user.save(opts); - }).then(assertCount(UserHistory,1, opts)) - .then(function(){ - t.rollback(); - }); - }).then(assertCount(UserHistory,0)); + it('revert on failed transactions', function() { + return sequelize + .transaction() + .then(function(t) { + var opts = { transaction: t }; + return User.create(opts) + .then(assertCount(UserHistory, 0, opts)) + .then(function(user) { + user.name = 'foo'; + return user.save(opts); + }) + .then(assertCount(UserHistory, 1, opts)) + .then(function() { + t.rollback(); + }); + }) + .then(assertCount(UserHistory, 0)); }); }); - describe('bulk update', function(){ + describe('bulk update', function() { beforeEach(freshDB); - it('should archive every entry' , function(){ - return User.bulkCreate([ - {name: "foo1"}, - {name: "foo2"}, - ]).then(assertCount(UserHistory,0)) - .then(function(){ - return User.update({ name: 'updated-foo' }, {where: {}}); - }).then(assertCount(UserHistory,2)) + it('should archive every entry', function() { + return User.bulkCreate([{ name: 'foo1' }, { name: 'foo2' }]) + .then(assertCount(UserHistory, 0)) + .then(function() { + return User.update({ name: 'updated-foo' }, { where: {} }); + }) + .then(assertCount(UserHistory, 2)); }); - it('should revert under transactions' , function(){ - return sequelize.transaction().then(function(t){ - var opts = {transaction: t}; - return User.bulkCreate([ - {name: "foo1"}, - {name: "foo2"}, - ], opts).then(assertCount(UserHistory,0,opts)) - .then(function(){ - return User.update({ name: 'updated-foo' }, {where: {}, transaction: t}); - }).then(assertCount(UserHistory,2, opts)) - .then(function(){ - t.rollback(); - }); - }).then(assertCount(UserHistory,0)); + it('should revert under transactions', function() { + return sequelize + .transaction() + .then(function(t) { + var opts = { transaction: t }; + return User.bulkCreate([{ name: 'foo1' }, { name: 'foo2' }], opts) + .then(assertCount(UserHistory, 0, opts)) + .then(function() { + return User.update( + { name: 'updated-foo' }, + { where: {}, transaction: t } + ); + }) + .then(assertCount(UserHistory, 2, opts)) + .then(function() { + t.rollback(); + }); + }) + .then(assertCount(UserHistory, 0)); }); - }); - describe('bulk destroy/truncate', function(){ + describe('bulk destroy/truncate', function() { beforeEach(freshDB); - it('should archive every entry' , function(){ - return User.bulkCreate([ - {name: "foo1"}, - {name: "foo2"}, - ]).then(assertCount(UserHistory,0)) - .then(function(){ - return User.destroy({ - where: {}, - truncate: true // truncate the entire table - }); - }).then(assertCount(UserHistory,2)) - }); - it('should revert under transactions' , function(){ - return sequelize.transaction().then(function(t){ - var opts = {transaction: t}; - return User.bulkCreate([ - {name: "foo1"}, - {name: "foo2"}, - ], opts).then(assertCount(UserHistory,0,opts)) - .then(function(){ + it('should archive every entry', function() { + return User.bulkCreate([{ name: 'foo1' }, { name: 'foo2' }]) + .then(assertCount(UserHistory, 0)) + .then(function() { return User.destroy({ where: {}, - truncate: true, // truncate the entire table - transaction: t + truncate: true // truncate the entire table }); - }).then(assertCount(UserHistory,2, opts)) - .then(function(){ - t.rollback(); - }); - }).then(assertCount(UserHistory,0)); + }) + .then(assertCount(UserHistory, 2)); + }); + it('should revert under transactions', function() { + return sequelize + .transaction() + .then(function(t) { + var opts = { transaction: t }; + return User.bulkCreate([{ name: 'foo1' }, { name: 'foo2' }], opts) + .then(assertCount(UserHistory, 0, opts)) + .then(function() { + return User.destroy({ + where: {}, + truncate: true, // truncate the entire table + transaction: t + }); + }) + .then(assertCount(UserHistory, 2, opts)) + .then(function() { + t.rollback(); + }); + }) + .then(assertCount(UserHistory, 0)); }); - - }); - describe('read-only ', function(){ - it('should forbid updates' , function(){ - var userUpdate = UserHistory.create().then(function(uh){ - uh.update({name: 'bla'}); + describe('read-only ', function() { + it('should forbid updates', function() { + var userUpdate = UserHistory.create().then(function(uh) { + uh.update({ name: 'bla' }); }); - return assert.isRejected(userUpdate, Error, "Validation error"); + return assert.isRejected(userUpdate, Error, 'Validation error'); }); - it('should forbid deletes' , function(){ - var userUpdate = UserHistory.create().then(function(uh){ + it('should forbid deletes', function() { + var userUpdate = UserHistory.create().then(function(uh) { uh.destroy(); }); - return assert.isRejected(userUpdate, Error, "Validation error"); + return assert.isRejected(userUpdate, Error, 'Validation error'); }); }); - describe('interference with the original model', function(){ - + describe('interference with the original model', function() { beforeEach(freshDB); - it('shouldn\'t delete instance methods' , function(){ - Fruit = Temporal(sequelize.define('Fruit', { - name: Sequelize.TEXT - }), sequelize); - Fruit.prototype.sayHi = function(){ return 2;} - return sequelize.sync().then(function(){ - return Fruit.create(); - }).then(function(f){ - assert.isFunction(f.sayHi); - assert.equal(f.sayHi(), 2); - }); + it("shouldn't delete instance methods", function() { + Fruit = Temporal( + sequelize.define('Fruit', { + name: Sequelize.TEXT + }), + sequelize + ); + Fruit.prototype.sayHi = function() { + return 2; + }; + return sequelize + .sync() + .then(function() { + return Fruit.create(); + }) + .then(function(f) { + assert.isFunction(f.sayHi); + assert.equal(f.sayHi(), 2); + }); }); - it('shouldn\'t interfere with hooks of the model' , function(){ + it("shouldn't interfere with hooks of the model", function() { var triggered = 0; - Fruit = Temporal(sequelize.define('Fruit', { - name: Sequelize.TEXT - }, { - hooks:{ - beforeCreate: function(){ triggered++;} - } - }), sequelize); - return sequelize.sync().then(function(){ - return Fruit.create(); - }).then(function(f){ - assert.equal(triggered, 1,"hook trigger count"); - }); + Fruit = Temporal( + sequelize.define( + 'Fruit', + { + name: Sequelize.TEXT + }, + { + hooks: { + beforeCreate: function() { + triggered++; + } + } + } + ), + sequelize + ); + return sequelize + .sync() + .then(function() { + return Fruit.create(); + }) + .then(function(f) { + assert.equal(triggered, 1, 'hook trigger count'); + }); }); - it('shouldn\'t interfere with setters' , function(){ + it("shouldn't interfere with setters", function() { var triggered = 0; - Fruit = Temporal(sequelize.define('Fruit', { - name: { - type: Sequelize.TEXT, - set: function(){ - triggered++; + Fruit = Temporal( + sequelize.define('Fruit', { + name: { + type: Sequelize.TEXT, + set: function() { + triggered++; + } } - } - }), sequelize); - return sequelize.sync().then(function(){ - return Fruit.create({name: "apple"}); - }).then(function(f){ - assert.equal(triggered, 1,"hook trigger count"); - }); + }), + sequelize + ); + return sequelize + .sync() + .then(function() { + return Fruit.create({ name: 'apple' }); + }) + .then(function(f) { + assert.equal(triggered, 1, 'hook trigger count'); + }); }); - }); describe('full mode', function() { - beforeEach(freshDBWithFullModeAndParanoid); - it('onCreate: should store the new version in history db' , function(){ + it('onCreate: should store the new version in history db', function() { return User.create({ name: 'test' }) .then(function() { return UserHistory.findAll(); @@ -260,7 +309,7 @@ describe('Read-only API', function(){ }); }); - it('onUpdate: should store the new version to the historyDB' , function(){ + it('onUpdate: should store the new version to the historyDB', function() { return User.create({ name: 'test' }) .then(function(user) { return user.update({ name: 'renamed' }); @@ -275,7 +324,7 @@ describe('Read-only API', function(){ }); }); - it('onDelete: should store the previous version to the historyDB' , function(){ + it('onDelete: should store the previous version to the historyDB', function() { return User.create({ name: 'test' }) .then(function(user) { return user.update({ name: 'renamed' }); @@ -290,11 +339,15 @@ describe('Read-only API', function(){ assert.equal(histories.length, 3, 'three entries in DB'); assert.equal(histories[0].name, 'test', 'first version saved'); assert.equal(histories[1].name, 'renamed', 'second version saved'); - assert.notEqual(histories[2].deletedAt, null, 'deleted version saved'); + assert.notEqual( + histories[2].deletedAt, + null, + 'deleted version saved' + ); }); }); - it('onRestore: should store the new version to the historyDB' , function(){ + it('onRestore: should store the new version to the historyDB', function() { return User.create({ name: 'test' }) .then(function(user) { return user.destroy(); @@ -308,13 +361,18 @@ describe('Read-only API', function(){ .then(function(histories) { assert.equal(histories.length, 3, 'three entries in DB'); assert.equal(histories[0].name, 'test', 'first version saved'); - assert.notEqual(histories[1].deletedAt, null, 'deleted version saved'); + assert.notEqual( + histories[1].deletedAt, + null, + 'deleted version saved' + ); assert.equal(histories[2].deletedAt, null, 'restored version saved'); }); }); - it('should revert on failed transactions, even when using after hooks' , function(){ - return sequelize.transaction() + it('should revert on failed transactions, even when using after hooks', function() { + return sequelize + .transaction() .then(function(transaction) { var options = { transaction: transaction }; @@ -324,12 +382,10 @@ describe('Read-only API', function(){ }) .then(assertCount(UserHistory, 2, options)) .then(function() { - return transaction.rollback() + return transaction.rollback(); }); }) - .then(assertCount(UserHistory,0)); + .then(assertCount(UserHistory, 0)); }); - }); - });