diff --git a/.gitignore b/.gitignore index f46fffd..ae657d9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,4 @@ typings node_modules coverage doc -dist/*.js -dist/*.map -*.log \ No newline at end of file +*.log diff --git a/dist/js-data-adapter-tests.js b/dist/js-data-adapter-tests.js new file mode 100644 index 0000000..942d126 --- /dev/null +++ b/dist/js-data-adapter-tests.js @@ -0,0 +1,4810 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('chai'), require('sinon')) : + typeof define === 'function' && define.amd ? define('js-data-adapter-tests', ['chai', 'sinon'], factory) : + (global.JSDataAdapterTests = factory(global.chai,global.sinon)); +}(this, (function (chai,sinon$1) { 'use strict'; + +sinon$1 = sinon$1 && 'default' in sinon$1 ? sinon$1['default'] : sinon$1; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { + return typeof obj; +} : function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; +}; + + + + + + + + + +var asyncToGenerator = function (fn) { + return function () { + var gen = fn.apply(this, arguments); + return new Promise(function (resolve, reject) { + function step(key, arg) { + try { + var info = gen[key](arg); + var value = info.value; + } catch (error) { + reject(error); + return; + } + + if (info.done) { + resolve(value); + } else { + return Promise.resolve(value).then(function (value) { + step("next", value); + }, function (err) { + step("throw", err); + }); + } + } + + return step("next"); + }); + }; +}; + +var classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } +}; + +var createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; +}(); + + + + + +var defineProperty = function (obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; +}; + + + +var inherits = function (subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); + } + + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; +}; + + + + + + + + + + + +var possibleConstructorReturn = function (self, call) { + if (!self) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return call && (typeof call === "object" || typeof call === "function") ? call : self; +}; + +/* global assert:true */ +var afterCreateTest = function (options) { + describe('Adapter#afterCreate', function () { + it('should exist', function () { + assert.equal(_typeof(this.$$adapter.afterCreate), 'function', 'adapter should have a "afterCreate" method'); + }); + it('should call afterCreate', asyncToGenerator(regeneratorRuntime.mark(function _callee() { + var adapter, User, props, user, args; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + sinon.stub(adapter, 'afterCreate').callsFake(function (mapper, props, opts) { + assert.isDefined(opts, 'afterCreate should have received options'); + assert.equal(opts.op, 'afterCreate', 'opts.op'); + }); + + assert.debug('create', User.name, props); + _context.next = 7; + return adapter.create(User, props); + + case 7: + user = _context.sent; + + assert.debug('created', User.name, user); + + assert.equal(user.name, props.name, 'name of user should be "' + props.name + '"'); + assert.isDefined(user[User.idAttribute], 'new user should have an id'); + + assert.isTrue(adapter.afterCreate.calledOnce, 'afterCreate should have been called once'); + + args = adapter.afterCreate.firstCall.args; + + assert.equal(args.length, 4, 'afterCreate should have received 4 arguments'); + assert.isTrue(args[0] === User, 'afterCreate should have received User mapper'); + assert.objectsEqual(args[1], { name: 'John' }, 'afterCreate should have received create props'); + assert.isObject(args[2], 'afterCreate should have received options'); + assert.isObject(args[3], 'afterCreate should have received record'); + adapter.afterCreate.restore(); + + case 19: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + }))); + it('should allow re-assignment', asyncToGenerator(regeneratorRuntime.mark(function _callee2() { + var adapter, User, props, user, args; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + sinon.stub(adapter, 'afterCreate').callsFake(function (mapper, props, opts) { + assert.isDefined(opts, 'afterCreate should have received options'); + assert.equal(opts.op, 'afterCreate', 'opts.op'); + return 'foo'; + }); + + assert.debug('create', User.name, props); + _context2.next = 7; + return adapter.create(User, props); + + case 7: + user = _context2.sent; + + assert.debug('created', User.name, user); + + assert.equal(user, 'foo', 'result should be "foo"'); + + assert.isTrue(adapter.afterCreate.calledOnce, 'afterCreate should have been called once'); + + args = adapter.afterCreate.firstCall.args; + + assert.equal(args.length, 4, 'afterCreate should have received 4 arguments'); + assert.isTrue(args[0] === User, 'afterCreate should have received User mapper'); + assert.objectsEqual(args[1], { name: 'John' }, 'afterCreate should have received create props'); + assert.isObject(args[2], 'afterCreate should have received options'); + assert.isObject(args[3], 'afterCreate should have received record'); + adapter.afterCreate.restore(); + + case 18: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + }))); + it('should allow returning a promise', asyncToGenerator(regeneratorRuntime.mark(function _callee3() { + var adapter, User, props, user, args; + return regeneratorRuntime.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + sinon.stub(adapter, 'afterCreate').callsFake(function (mapper, props, opts, record) { + assert.isDefined(opts, 'afterCreate should have received options'); + assert.equal(opts.op, 'afterCreate', 'opts.op'); + return Promise.resolve(); + }); + + assert.debug('create', User.name, props); + _context3.next = 7; + return adapter.create(User, props); + + case 7: + user = _context3.sent; + + assert.debug('created', User.name, user); + + assert.equal(user.name, props.name, 'name of user should be "' + props.name + '"'); + assert.isDefined(user[User.idAttribute], 'new user should have an id'); + + assert.isTrue(adapter.afterCreate.calledOnce, 'afterCreate should have been called once'); + + args = adapter.afterCreate.firstCall.args; + + assert.equal(args.length, 4, 'afterCreate should have received 4 arguments'); + assert.isTrue(args[0] === User, 'afterCreate should have received User mapper'); + assert.objectsEqual(args[1], { name: 'John' }, 'afterCreate should have received create props'); + assert.isDefined(args[2], 'afterCreate should have received options'); + assert.isObject(args[3], 'afterCreate should have received record'); + adapter.afterCreate.restore(); + + case 19: + case 'end': + return _context3.stop(); + } + } + }, _callee3, this); + }))); + it('should allow returning a promise and re-assignment', asyncToGenerator(regeneratorRuntime.mark(function _callee4() { + var adapter, User, props, user, args; + return regeneratorRuntime.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + sinon.stub(adapter, 'afterCreate').callsFake(function (mapper, props, opts) { + assert.isDefined(opts, 'afterCreate should have received options'); + assert.equal(opts.op, 'afterCreate', 'opts.op'); + return 'foo'; + }); + + assert.debug('create', User.name, props); + _context4.next = 7; + return adapter.create(User, props); + + case 7: + user = _context4.sent; + + assert.debug('created', User.name, user); + + assert.equal(user, 'foo', 'result should be "foo"'); + + assert.isTrue(adapter.afterCreate.calledOnce, 'afterCreate should have been called once'); + + args = adapter.afterCreate.firstCall.args; + + assert.equal(args.length, 4, 'afterCreate should have received 4 arguments'); + assert.isTrue(args[0] === User, 'afterCreate should have received User mapper'); + assert.objectsEqual(args[1], { name: 'John' }, 'afterCreate should have received create props'); + assert.isObject(args[2], 'afterCreate should have received options'); + assert.isObject(args[3], 'afterCreate should have received record'); + adapter.afterCreate.restore(); + + case 18: + case 'end': + return _context4.stop(); + } + } + }, _callee4, this); + }))); + it('should receive raw', asyncToGenerator(regeneratorRuntime.mark(function _callee5() { + var adapter, User, props, result, args; + return regeneratorRuntime.wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + sinon.stub(adapter, 'afterCreate').callsFake(function (mapper, props, opts) { + assert.isDefined(opts, 'afterCreate should have received options'); + assert.equal(opts.op, 'afterCreate', 'opts.op'); + }); + + assert.debug('create', User.name, props); + _context5.next = 7; + return adapter.create(User, props, { raw: true }); + + case 7: + result = _context5.sent; + + assert.debug('created', User.name, result); + + assert.equal(result.created, 1, 'result.created'); + assert.equal(result.data.name, props.name, 'result.data.name'); + assert.isDefined(result.data[User.idAttribute], 'result.data[' + User.idAttribute + ']'); + + assert.isTrue(adapter.afterCreate.calledOnce, 'afterCreate should have been called once'); + + args = adapter.afterCreate.firstCall.args; + + assert.equal(args.length, 4, 'afterCreate should have received 4 arguments'); + assert.isTrue(args[0] === User, 'afterCreate should have received User mapper'); + assert.objectsEqual(args[1], { name: 'John' }, 'afterCreate should have received create props'); + assert.isObject(args[2], 'afterCreate should have received options'); + assert.isObject(args[3], 'afterCreate should have received result'); + assert.equal(args[3].created, 1, 'result.created'); + assert.isObject(args[3].data, 'result.data'); + adapter.afterCreate.restore(); + + case 22: + case 'end': + return _context5.stop(); + } + } + }, _callee5, this); + }))); + }); +}; + +/* global assert:true */ +var afterUpdateTest = function (options) { + describe('Adapter#afterUpdate', function () { + it('should exist', function () { + assert.equal(_typeof(this.$$adapter.afterUpdate), 'function', 'adapter should have a "afterUpdate" method'); + }); + it('should call afterUpdate', asyncToGenerator(regeneratorRuntime.mark(function _callee() { + var adapter, User, props, user, userId, updatedUser, args; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + sinon.stub(adapter, 'afterUpdate').callsFake(function (mapper, id, props, opts) { + assert.isDefined(opts, 'afterUpdate should have received options'); + assert.equal(opts.op, 'afterUpdate', 'opts.op'); + }); + + assert.debug('create', User.name, props); + _context.next = 7; + return adapter.create(User, props); + + case 7: + user = _context.sent; + userId = user[User.idAttribute]; + + assert.debug('created', User.name, user); + + assert.equal(user.name, props.name, 'name of user should be "' + props.name + '"'); + assert.isDefined(user[User.idAttribute], 'new user should have an id'); + + assert.debug('update', User.name, userId, { name: 'Johnny' }); + _context.next = 15; + return adapter.update(User, userId, { name: 'Johnny' }); + + case 15: + updatedUser = _context.sent; + + assert.debug('updated', User.name, updatedUser); + assert.equal(updatedUser.name, 'Johnny'); + assert.equal(updatedUser[User.idAttribute], userId); + + assert.isTrue(adapter.afterUpdate.calledOnce, 'afterUpdate should have been called once'); + + args = adapter.afterUpdate.firstCall.args; + + assert.equal(args.length, 5, 'beforeUpdate should have received 5 arguments'); + assert.isTrue(args[0] === User, 'afterUpdate should have received User mapper'); + assert.isTrue(args[1] === userId, 'afterUpdate should have received user id'); + assert.objectsEqual(args[2], { name: 'Johnny' }, 'afterUpdate should have received update props'); + assert.isDefined(args[3], 'afterUpdate should have received options'); + assert.equal(args[3].op, 'afterUpdate', 'args[3].op'); + assert.isDefined(args[4], 'afterUpdate should have received updated record'); + assert.equal(args[4][User.idAttribute], userId, 'args[4].' + User.idAttribute); + assert.equal(args[4].name, 'Johnny', 'args[4].name'); + adapter.afterUpdate.restore(); + + case 31: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + }))); + it('should receive raw', asyncToGenerator(regeneratorRuntime.mark(function _callee2() { + var adapter, User, props, user, userId, result, args; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + sinon.stub(adapter, 'afterUpdate').callsFake(function (mapper, id, props, opts) { + assert.isDefined(opts, 'afterUpdate should have received options'); + assert.equal(opts.op, 'afterUpdate', 'opts.op'); + }); + + assert.debug('create', User.name, props); + _context2.next = 7; + return adapter.create(User, props); + + case 7: + user = _context2.sent; + userId = user[User.idAttribute]; + + assert.debug('created', User.name, user); + + assert.equal(user.name, props.name, 'name of user should be "' + props.name + '"'); + assert.isDefined(user[User.idAttribute], 'new user should have an id'); + + assert.debug('update', User.name, userId, { name: 'Johnny' }); + _context2.next = 15; + return adapter.update(User, userId, { name: 'Johnny' }, { raw: true }); + + case 15: + result = _context2.sent; + + assert.debug('updated', User.name, result); + assert.isDefined(result.data, 'result.data'); + assert.equal(result.data.name, 'Johnny', result.data.name); + assert.equal(result.data[User.idAttribute], userId, 'result.data.' + User.idAttribute); + + assert.isTrue(adapter.afterUpdate.calledOnce, 'afterUpdate should have been called once'); + + args = adapter.afterUpdate.firstCall.args; + + assert.equal(args.length, 5, 'beforeUpdate should have received 5 arguments'); + assert.isTrue(args[0] === User, 'afterUpdate should have received User mapper'); + assert.isTrue(args[1] === userId, 'afterUpdate should have received user id'); + assert.objectsEqual(args[2], { name: 'Johnny' }, 'afterUpdate should have received update props'); + assert.isDefined(args[3], 'afterUpdate should have received options'); + assert.equal(args[3].op, 'afterUpdate', 'args[3].op'); + assert.isDefined(args[4], 'afterUpdate should have received update result'); + assert.equal(args[4].updated, 1, 'args[4].updated'); + assert.isDefined(args[4].data, 'args[4].data'); + assert.equal(args[4].data[User.idAttribute], userId, 'args[4].data.' + User.idAttribute); + assert.equal(args[4].data.name, 'Johnny', 'args[4].data.name'); + adapter.afterUpdate.restore(); + + case 34: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + }))); + it('should allow re-assignment', asyncToGenerator(regeneratorRuntime.mark(function _callee3() { + var adapter, User, props, user, userId, updatedUser, args; + return regeneratorRuntime.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + sinon.stub(adapter, 'afterUpdate').callsFake(function (mapper, id, props, opts) { + assert.isDefined(opts, 'afterUpdate should have received options'); + assert.equal(opts.op, 'afterUpdate', 'opts.op'); + return 'foo'; + }); + + assert.debug('create', User.name, props); + _context3.next = 7; + return adapter.create(User, props); + + case 7: + user = _context3.sent; + userId = user[User.idAttribute]; + + assert.debug('created', User.name, user); + + assert.equal(user.name, props.name, 'name of user should be "' + props.name + '"'); + assert.isDefined(user[User.idAttribute], 'new user should have an id'); + + assert.debug('update', User.name, userId, { name: 'Johnny' }); + _context3.next = 15; + return adapter.update(User, userId, { name: 'Johnny' }); + + case 15: + updatedUser = _context3.sent; + + assert.debug('updated', User.name, updatedUser); + assert.equal(updatedUser, 'foo', 'should have received re-assigned value'); + + assert.isTrue(adapter.afterUpdate.calledOnce, 'afterUpdate should have been called once'); + + args = adapter.afterUpdate.firstCall.args; + + assert.equal(args.length, 5, 'beforeUpdate should have received 5 arguments'); + assert.isTrue(args[0] === User, 'afterUpdate should have received User mapper'); + assert.isTrue(args[1] === userId, 'afterUpdate should have received user id'); + assert.objectsEqual(args[2], { name: 'Johnny' }, 'afterUpdate should have received update props'); + assert.isDefined(args[3], 'afterUpdate should have received options'); + assert.equal(args[3].op, 'afterUpdate', 'args[3].op'); + assert.isDefined(args[4], 'afterUpdate should have received updated record'); + assert.equal(args[4][User.idAttribute], userId, 'args[4].' + User.idAttribute); + assert.equal(args[4].name, 'Johnny', 'args[4].name'); + adapter.afterUpdate.restore(); + + case 30: + case 'end': + return _context3.stop(); + } + } + }, _callee3, this); + }))); + it('should allow returning a promise', asyncToGenerator(regeneratorRuntime.mark(function _callee4() { + var adapter, User, props, user, userId, updatedUser, args; + return regeneratorRuntime.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + sinon.stub(adapter, 'afterUpdate').callsFake(function (mapper, id, props, opts) { + assert.isDefined(opts, 'afterUpdate should have received options'); + assert.equal(opts.op, 'afterUpdate', 'opts.op'); + return Promise.resolve(); + }); + + assert.debug('create', User.name, props); + _context4.next = 7; + return adapter.create(User, props); + + case 7: + user = _context4.sent; + userId = user[User.idAttribute]; + + assert.debug('created', User.name, user); + + assert.equal(user.name, props.name, 'name of user should be "' + props.name + '"'); + assert.isDefined(user[User.idAttribute], 'new user should have an id'); + + assert.debug('update', User.name, userId, { name: 'Johnny' }); + _context4.next = 15; + return adapter.update(User, userId, { name: 'Johnny' }); + + case 15: + updatedUser = _context4.sent; + + assert.debug('updated', User.name, updatedUser); + assert.equal(updatedUser.name, 'Johnny'); + assert.equal(updatedUser[User.idAttribute], userId); + + assert.isTrue(adapter.afterUpdate.calledOnce, 'afterUpdate should have been called once'); + + args = adapter.afterUpdate.firstCall.args; + + assert.equal(args.length, 5, 'beforeUpdate should have received 5 arguments'); + assert.isTrue(args[0] === User, 'afterUpdate should have received User mapper'); + assert.isTrue(args[1] === userId, 'afterUpdate should have received user id'); + assert.objectsEqual(args[2], { name: 'Johnny' }, 'afterUpdate should have received update props'); + assert.isDefined(args[3], 'afterUpdate should have received options'); + assert.equal(args[3].op, 'afterUpdate', 'args[3].op'); + assert.isDefined(args[4], 'afterUpdate should have received updated record'); + assert.equal(args[4][User.idAttribute], userId, 'args[4].' + User.idAttribute); + assert.equal(args[4].name, 'Johnny', 'args[4].name'); + adapter.afterUpdate.restore(); + + case 31: + case 'end': + return _context4.stop(); + } + } + }, _callee4, this); + }))); + it('should allow returning a promise and re-assignment', asyncToGenerator(regeneratorRuntime.mark(function _callee5() { + var adapter, User, props, user, userId, updatedUser, args; + return regeneratorRuntime.wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + sinon.stub(adapter, 'afterUpdate').callsFake(function (mapper, id, props, opts) { + assert.isDefined(opts, 'afterUpdate should have received options'); + assert.equal(opts.op, 'afterUpdate', 'opts.op'); + return Promise.resolve('foo'); + }); + + assert.debug('create', User.name, props); + _context5.next = 7; + return adapter.create(User, props); + + case 7: + user = _context5.sent; + userId = user[User.idAttribute]; + + assert.debug('created', User.name, user); + + assert.equal(user.name, props.name, 'name of user should be "' + props.name + '"'); + assert.isDefined(user[User.idAttribute], 'new user should have an id'); + + assert.debug('update', User.name, userId, { name: 'Johnny' }); + _context5.next = 15; + return adapter.update(User, userId, { name: 'Johnny' }); + + case 15: + updatedUser = _context5.sent; + + assert.debug('updated', User.name, updatedUser); + assert.equal(updatedUser, 'foo', 'should have received re-assigned value'); + + assert.isTrue(adapter.afterUpdate.calledOnce, 'afterUpdate should have been called once'); + + args = adapter.afterUpdate.firstCall.args; + + assert.equal(args.length, 5, 'beforeUpdate should have received 5 arguments'); + assert.isTrue(args[0] === User, 'afterUpdate should have received User mapper'); + assert.isTrue(args[1] === userId, 'afterUpdate should have received user id'); + assert.objectsEqual(args[2], { name: 'Johnny' }, 'afterUpdate should have received update props'); + assert.isDefined(args[3], 'afterUpdate should have received options'); + assert.equal(args[3].op, 'afterUpdate', 'args[3].op'); + assert.isDefined(args[4], 'afterUpdate should have received updated record'); + assert.equal(args[4][User.idAttribute], userId, 'args[4].' + User.idAttribute); + assert.equal(args[4].name, 'Johnny', 'args[4].name'); + adapter.afterUpdate.restore(); + + case 30: + case 'end': + return _context5.stop(); + } + } + }, _callee5, this); + }))); + }); +}; + +/* global assert:true */ +var beforeCreateTest = function (options) { + describe('Adapter#beforeCreate', function () { + it('should exist', function () { + assert.equal(_typeof(this.$$adapter.beforeCreate), 'function', 'adapter should have a "beforeCreate" method'); + }); + it('should call beforeCreate', asyncToGenerator(regeneratorRuntime.mark(function _callee() { + var adapter, User, props, user, args; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + sinon.stub(adapter, 'beforeCreate').callsFake(function (mapper, props, opts) { + assert.isDefined(opts, 'beforeCreate should have received options'); + assert.equal(opts.op, 'beforeCreate', 'opts.op'); + }); + + assert.debug('create', User.name, props); + _context.next = 7; + return adapter.create(User, props); + + case 7: + user = _context.sent; + + assert.debug('created', User.name, user); + + assert.equal(user.name, props.name, 'name of user should be "' + props.name + '"'); + assert.isDefined(user[User.idAttribute], 'new user should have an id'); + + assert.isTrue(adapter.beforeCreate.calledOnce, 'beforeCreate should have been called once'); + + args = adapter.beforeCreate.firstCall.args; + + assert.equal(args.length, 3, 'beforeCreate should have received 3 arguments'); + assert.isTrue(args[0] === User, 'beforeCreate should have received User mapper'); + assert.objectsEqual(args[1], { name: 'John' }, 'beforeCreate should have received create props'); + assert.isObject(args[2], 'beforeCreate should have received options'); + adapter.beforeCreate.restore(); + + case 18: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + }))); + it('should allow re-assignment', asyncToGenerator(regeneratorRuntime.mark(function _callee2() { + var adapter, User, props, user, args; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + sinon.stub(adapter, 'beforeCreate').callsFake(function (mapper, props, opts) { + assert.isDefined(opts, 'beforeCreate should have received options'); + assert.equal(opts.op, 'beforeCreate', 'opts.op'); + return { name: 'Sally' }; + }); + + assert.debug('create', User.name, props); + _context2.next = 7; + return adapter.create(User, props); + + case 7: + user = _context2.sent; + + assert.debug('created', User.name, user); + + assert.equal(user.name, 'Sally', 'name of user should be "Sally"'); + assert.isDefined(user[User.idAttribute], 'new user should have an id'); + + assert.isTrue(adapter.beforeCreate.calledOnce, 'beforeCreate should have been called once'); + + args = adapter.beforeCreate.firstCall.args; + + assert.equal(args.length, 3, 'beforeCreate should have received 3 arguments'); + assert.isTrue(args[0] === User, 'beforeCreate should have received User mapper'); + assert.objectsEqual(args[1], { name: 'John' }, 'beforeCreate should have received create props'); + assert.isObject(args[2], 'beforeCreate should have received options'); + adapter.beforeCreate.restore(); + + case 18: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + }))); + it('should allow returning a promise', asyncToGenerator(regeneratorRuntime.mark(function _callee3() { + var adapter, User, props, user, args; + return regeneratorRuntime.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + sinon.stub(adapter, 'beforeCreate').callsFake(function (mapper, props, opts) { + assert.isDefined(opts, 'beforeCreate should have received options'); + assert.equal(opts.op, 'beforeCreate', 'opts.op'); + return Promise.resolve(); + }); + + assert.debug('create', User.name, props); + _context3.next = 7; + return adapter.create(User, props); + + case 7: + user = _context3.sent; + + assert.debug('created', User.name, user); + + assert.equal(user.name, props.name, 'name of user should be "' + props.name + '"'); + assert.isDefined(user[User.idAttribute], 'new user should have an id'); + + assert.isTrue(adapter.beforeCreate.calledOnce, 'beforeCreate should have been called once'); + + args = adapter.beforeCreate.firstCall.args; + + assert.equal(args.length, 3, 'beforeCreate should have received 3 arguments'); + assert.isTrue(args[0] === User, 'beforeCreate should have received User mapper'); + assert.objectsEqual(args[1], { name: 'John' }, 'beforeCreate should have received create props'); + assert.isDefined(args[2], 'beforeCreate should have received options'); + adapter.beforeCreate.restore(); + + case 18: + case 'end': + return _context3.stop(); + } + } + }, _callee3, this); + }))); + it('should allow returning a promise and re-assignment', asyncToGenerator(regeneratorRuntime.mark(function _callee4() { + var adapter, User, props, user, args; + return regeneratorRuntime.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + sinon.stub(adapter, 'beforeCreate').callsFake(function (mapper, props, opts) { + assert.isDefined(opts, 'beforeCreate should have received options'); + assert.equal(opts.op, 'beforeCreate', 'opts.op'); + return Promise.resolve({ name: 'Sally' }); + }); + + assert.debug('create', User.name, props); + _context4.next = 7; + return adapter.create(User, props); + + case 7: + user = _context4.sent; + + assert.debug('created', User.name, user); + + assert.equal(user.name, 'Sally', 'name of user should be "Sally"'); + assert.isDefined(user[User.idAttribute], 'new user should have an id'); + + assert.isTrue(adapter.beforeCreate.calledOnce, 'beforeCreate should have been called once'); + + args = adapter.beforeCreate.firstCall.args; + + assert.equal(args.length, 3, 'beforeCreate should have received 3 arguments'); + assert.isTrue(args[0] === User, 'beforeCreate should have received User mapper'); + assert.objectsEqual(args[1], { name: 'John' }, 'beforeCreate should have received create props'); + assert.isObject(args[2], 'beforeCreate should have received options'); + adapter.beforeCreate.restore(); + + case 18: + case 'end': + return _context4.stop(); + } + } + }, _callee4, this); + }))); + }); +}; + +/* global assert:true */ +var beforeUpdateTest = function (options) { + describe('Adapter#beforeUpdate', function () { + it('should exist', function () { + assert.equal(_typeof(this.$$adapter.beforeUpdate), 'function', 'adapter should have a "beforeUpdate" method'); + }); + it('should call beforeUpdate', asyncToGenerator(regeneratorRuntime.mark(function _callee() { + var adapter, User, props, user, userId, updatedUser, args; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + sinon.stub(adapter, 'beforeUpdate').callsFake(function (mapper, id, props, opts) { + assert.isDefined(opts, 'beforeUpdate should have received options'); + assert.equal(opts.op, 'beforeUpdate', 'opts.op'); + }); + + assert.debug('create', User.name, props); + _context.next = 7; + return adapter.create(User, props); + + case 7: + user = _context.sent; + userId = user[User.idAttribute]; + + assert.debug('created', User.name, user); + + assert.equal(user.name, props.name, 'name of user should be "' + props.name + '"'); + assert.isDefined(user[User.idAttribute], 'new user should have an id'); + + assert.debug('update', User.name, userId, { name: 'Johnny' }); + _context.next = 15; + return adapter.update(User, userId, { name: 'Johnny' }); + + case 15: + updatedUser = _context.sent; + + assert.debug('updated', User.name, updatedUser); + assert.equal(updatedUser.name, 'Johnny'); + assert.equal(updatedUser[User.idAttribute], userId); + + assert.isTrue(adapter.beforeUpdate.calledOnce, 'beforeUpdate should have been called once'); + + args = adapter.beforeUpdate.firstCall.args; + + assert.equal(args.length, 4, 'beforeUpdate should have received 4 arguments'); + assert.isTrue(args[0] === User, 'beforeUpdate should have received User mapper'); + assert.isTrue(args[1] === userId, 'beforeUpdate should have received user id'); + assert.objectsEqual(args[2], { name: 'Johnny' }, 'beforeUpdate should have received update props'); + assert.isObject(args[3], 'beforeUpdate should have received options'); + adapter.beforeUpdate.restore(); + + case 27: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + }))); + it('should allow re-assignment', asyncToGenerator(regeneratorRuntime.mark(function _callee2() { + var adapter, User, props, user, userId, updatedUser, args; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + sinon.stub(adapter, 'beforeUpdate').callsFake(function (mapper, id, props, opts) { + assert.isDefined(opts, 'beforeUpdate should have received options'); + assert.equal(opts.op, 'beforeUpdate', 'opts.op'); + return { name: 'Sally' }; + }); + + assert.debug('create', User.name, props); + _context2.next = 7; + return adapter.create(User, props); + + case 7: + user = _context2.sent; + userId = user[User.idAttribute]; + + assert.debug('created', User.name, user); + + assert.equal(user.name, props.name, 'name of user should be "' + props.name + '"'); + assert.isDefined(user[User.idAttribute], 'new user should have an id'); + + assert.debug('update', User.name, userId, { name: 'Johnny' }); + _context2.next = 15; + return adapter.update(User, userId, { name: 'Johnny' }); + + case 15: + updatedUser = _context2.sent; + + assert.debug('updated', User.name, updatedUser); + assert.equal(updatedUser.name, 'Sally'); + assert.equal(updatedUser[User.idAttribute], userId); + + assert.isTrue(adapter.beforeUpdate.calledOnce, 'beforeUpdate should have been called once'); + + args = adapter.beforeUpdate.firstCall.args; + + assert.equal(args.length, 4, 'beforeUpdate should have received 4 arguments'); + assert.isTrue(args[0] === User, 'beforeUpdate should have received User mapper'); + assert.isTrue(args[1] === userId, 'beforeUpdate should have received user id'); + assert.objectsEqual(args[2], { name: 'Johnny' }, 'beforeUpdate should have received update props'); + assert.isObject(args[3], 'beforeUpdate should have received options'); + adapter.beforeUpdate.restore(); + + case 27: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + }))); + it('should allow returning a promise', asyncToGenerator(regeneratorRuntime.mark(function _callee3() { + var adapter, User, props, user, userId, updatedUser, args; + return regeneratorRuntime.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + sinon.stub(adapter, 'beforeUpdate').callsFake(function (mapper, id, props, opts) { + assert.isDefined(opts, 'beforeUpdate should have received options'); + assert.equal(opts.op, 'beforeUpdate', 'opts.op'); + return Promise.resolve(); + }); + + assert.debug('create', User.name, props); + _context3.next = 7; + return adapter.create(User, props); + + case 7: + user = _context3.sent; + userId = user[User.idAttribute]; + + assert.debug('created', User.name, user); + + assert.equal(user.name, props.name, 'name of user should be "' + props.name + '"'); + assert.isDefined(user[User.idAttribute], 'new user should have an id'); + + assert.debug('update', User.name, userId, { name: 'Johnny' }); + _context3.next = 15; + return adapter.update(User, userId, { name: 'Johnny' }); + + case 15: + updatedUser = _context3.sent; + + assert.debug('updated', User.name, updatedUser); + assert.equal(updatedUser.name, 'Johnny'); + assert.equal(updatedUser[User.idAttribute], userId); + + assert.isTrue(adapter.beforeUpdate.calledOnce, 'beforeUpdate should have been called once'); + + args = adapter.beforeUpdate.firstCall.args; + + assert.equal(args.length, 4, 'beforeUpdate should have received 4 arguments'); + assert.isTrue(args[0] === User, 'beforeUpdate should have received User mapper'); + assert.isTrue(args[1] === userId, 'beforeUpdate should have received user id'); + assert.objectsEqual(args[2], { name: 'Johnny' }, 'beforeUpdate should have received update props'); + assert.isObject(args[3], 'beforeUpdate should have received options'); + adapter.beforeUpdate.restore(); + + case 27: + case 'end': + return _context3.stop(); + } + } + }, _callee3, this); + }))); + it('should allow returning a promise and re-assignment', asyncToGenerator(regeneratorRuntime.mark(function _callee4() { + var adapter, User, props, user, userId, updatedUser, args; + return regeneratorRuntime.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + sinon.stub(adapter, 'beforeUpdate').callsFake(function (mapper, id, props, opts) { + assert.isDefined(opts, 'beforeUpdate should have received options'); + assert.equal(opts.op, 'beforeUpdate', 'opts.op'); + return Promise.resolve({ name: 'Sally' }); + }); + + assert.debug('create', User.name, props); + _context4.next = 7; + return adapter.create(User, props); + + case 7: + user = _context4.sent; + userId = user[User.idAttribute]; + + assert.debug('created', User.name, user); + + assert.equal(user.name, props.name, 'name of user should be "' + props.name + '"'); + assert.isDefined(user[User.idAttribute], 'new user should have an id'); + + assert.debug('update', User.name, userId, { name: 'Johnny' }); + _context4.next = 15; + return adapter.update(User, userId, { name: 'Johnny' }); + + case 15: + updatedUser = _context4.sent; + + assert.debug('updated', User.name, updatedUser); + assert.equal(updatedUser.name, 'Sally'); + assert.equal(updatedUser[User.idAttribute], userId); + + assert.isTrue(adapter.beforeUpdate.calledOnce, 'beforeUpdate should have been called once'); + + args = adapter.beforeUpdate.firstCall.args; + + assert.equal(args.length, 4, 'beforeUpdate should have received 4 arguments'); + assert.isTrue(args[0] === User, 'beforeUpdate should have received User mapper'); + assert.isTrue(args[1] === userId, 'beforeUpdate should have received user id'); + assert.objectsEqual(args[2], { name: 'Johnny' }, 'beforeUpdate should have received update props'); + assert.isObject(args[3], 'beforeUpdate should have received options'); + adapter.beforeUpdate.restore(); + + case 27: + case 'end': + return _context4.stop(); + } + } + }, _callee4, this); + }))); + }); +}; + +/* global assert:true */ +var countTest = function (options) { + describe('Adapter#count', function () { + it('should exist', function () { + assert.equal(_typeof(this.$$adapter.count), 'function', 'adapter should have a "count" method'); + }); + it('should count users', asyncToGenerator(regeneratorRuntime.mark(function _callee() { + var adapter, User, props, count, user, user2; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + assert.debug('count', User.name, {}); + _context.next = 6; + return adapter.count(User); + + case 6: + count = _context.sent; + + assert.debug('counted', User.name, count); + assert.equal(count, 0); + + assert.debug('count', User.name, { name: 'John' }); + _context.next = 12; + return adapter.count(User, { name: 'John' }); + + case 12: + count = _context.sent; + + assert.debug('counted', User.name, count); + assert.equal(count, 0); + + assert.debug('count', User.name, { name: 'Sally' }); + _context.next = 18; + return adapter.count(User, { name: 'Sally' }); + + case 18: + count = _context.sent; + + assert.debug('counted', User.name, count); + assert.equal(count, 0); + + assert.debug('create', User.name, props); + _context.next = 24; + return adapter.create(User, props); + + case 24: + user = _context.sent; + + assert.debug('created', User.name, user); + + assert.debug('count', User.name, {}); + _context.next = 29; + return adapter.count(User); + + case 29: + count = _context.sent; + + assert.debug('counted', User.name, count); + assert.equal(count, 1); + + assert.debug('count', User.name, { name: 'John' }); + _context.next = 35; + return adapter.count(User, { name: 'John' }); + + case 35: + count = _context.sent; + + assert.debug('counted', User.name, count); + assert.equal(count, 1); + + assert.debug('count', User.name, { name: 'Sally' }); + _context.next = 41; + return adapter.count(User, { name: 'Sally' }); + + case 41: + count = _context.sent; + + assert.debug('counted', User.name, count); + assert.equal(count, 0); + + assert.debug('create', User.name, { name: 'Sally' }); + _context.next = 47; + return adapter.create(User, { name: 'Sally' }); + + case 47: + user2 = _context.sent; + + assert.debug('created', User.name, user2); + + assert.debug('count', User.name, {}); + _context.next = 52; + return adapter.count(User); + + case 52: + count = _context.sent; + + assert.debug('counted', User.name, count); + assert.equal(count, 2); + + assert.debug('count', User.name, { name: 'John' }); + _context.next = 58; + return adapter.count(User, { name: 'John' }); + + case 58: + count = _context.sent; + + assert.debug('counted', User.name, count); + assert.equal(count, 1); + + assert.debug('count', User.name, { name: 'Sally' }); + _context.next = 64; + return adapter.count(User, { name: 'Sally' }); + + case 64: + count = _context.sent; + + assert.debug('counted', User.name, count); + assert.equal(count, 1); + + case 67: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + }))); + it('should count users and return raw', asyncToGenerator(regeneratorRuntime.mark(function _callee2() { + var adapter, User, props, user, result; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + assert.debug('create', User.name, props); + _context2.next = 6; + return adapter.create(User, props); + + case 6: + user = _context2.sent; + + assert.debug('created', User.name, user); + + assert.debug('count', User.name, props); + _context2.next = 11; + return adapter.count(User, props, { raw: true }); + + case 11: + result = _context2.sent; + + assert.debug('counted', User.name, result); + assert.equal(result.data, 1, 'result.data'); + + case 14: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + }))); + }); +}; + +/* global assert:true */ +var createTest = function (options) { + describe('Adapter#create', function () { + it('should exist', function () { + assert.equal(_typeof(this.$$adapter.create), 'function', 'adapter should have a "create" method'); + }); + it('should create a user', asyncToGenerator(regeneratorRuntime.mark(function _callee() { + var adapter, User, props, user, userId, foundUser; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + assert.debug('create', User.name, props); + _context.next = 6; + return adapter.create(User, props); + + case 6: + user = _context.sent; + userId = user[User.idAttribute]; + + assert.debug('created', User.name, user); + + assert.equal(user.name, props.name, 'user.name'); + assert.isDefined(user[User.idAttribute], 'user[User.idAttribute]'); + + assert.debug('find', User.name, userId); + _context.next = 14; + return adapter.find(User, userId); + + case 14: + foundUser = _context.sent; + + assert.debug('found', User.name, foundUser); + + assert.equal(foundUser.name, props.name, 'foundUser.name'); + assert.isDefined(foundUser[User.idAttribute], 'foundUser[User.idAttribute]'); + assert.equal(foundUser[User.idAttribute], userId, 'foundUser[User.idAttribute]'); + + case 19: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + }))); + }); +}; + +/* global assert:true */ +var createManyTest = function (options) { + describe('Adapter#createMany', function () { + it('should exist', function () { + assert.equal(_typeof(this.$$adapter.createMany), 'function', 'adapter should have a "createMany" method'); + }); + it('should create multiple users', asyncToGenerator(regeneratorRuntime.mark(function _callee() { + var adapter, User, user1, user2, users, users3; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + user1 = { name: 'John', age: 20 }; + user2 = { name: 'John', age: 30 }; + + + assert.debug('createMany', User.name, [user1, user2]); + _context.next = 7; + return adapter.createMany(User, [user1, user2]); + + case 7: + users = _context.sent; + + assert.debug('created', User.name, users); + users.sort(function (a, b) { + return a.age - b.age; + }); + assert.isDefined(users[0][User.idAttribute]); + assert.isDefined(users[1][User.idAttribute]); + assert.equal(users.filter(function (x) { + return x.age === 20; + }).length, 1); + assert.equal(users.filter(function (x) { + return x.age === 30; + }).length, 1); + + assert.debug('findAll', User.name, { age: 20 }); + _context.next = 17; + return adapter.findAll(User, { age: 20 }); + + case 17: + users3 = _context.sent; + + assert.debug('found', User.name, users3); + assert.equal(users3.length, 1); + + case 20: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + }))); + }); +}; + +/* global assert:true */ +var destroyTest = function (options) { + describe('Adapter#destroy', function () { + it('should exist', function () { + assert.equal(_typeof(this.$$adapter.destroy), 'function', 'adapter should have a "destroy" method'); + }); + it('should destroy a user', asyncToGenerator(regeneratorRuntime.mark(function _callee() { + var adapter, User, props, user, userId, beforeDestroyCalled, afterDestroyCalled, destroyedUser; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + assert.debug('create', User.name, props); + _context.next = 6; + return adapter.create(User, props); + + case 6: + user = _context.sent; + userId = user[User.idAttribute]; + + assert.debug('created', User.name, user); + + beforeDestroyCalled = false; + afterDestroyCalled = false; + + // Test beforeDestroy and afterDestroy + + adapter.beforeDestroy = function (mapper, id, opts) { + beforeDestroyCalled = true; + assert.isObject(mapper, 'beforeDestroy should have received mapper argument'); + assert.isDefined(id, 'beforeDestroy should have received id argument'); + assert.isObject(opts, 'beforeDestroy should have received opts argument'); + // Test re-assignment + return Promise.resolve(); + }; + adapter.afterDestroy = function (mapper, id, opts) { + afterDestroyCalled = true; + assert.isObject(mapper, 'afterDestroy should have received mapper argument'); + assert.isDefined(id, 'afterDestroy should have received id argument'); + assert.isObject(opts, 'afterDestroy should have received opts argument'); + // Test re-assignment + return Promise.resolve(); + }; + + assert.debug('destroy', User.name, userId); + _context.next = 16; + return adapter.destroy(User, userId); + + case 16: + destroyedUser = _context.sent; + + assert.debug('destroyed', User.name, destroyedUser); + assert.isUndefined(destroyedUser, 'destroyedUser'); + assert.isTrue(beforeDestroyCalled, 'beforeDestroy should have been called'); + assert.isTrue(afterDestroyCalled, 'afterDestroy should have been called'); + + case 21: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + }))); + it('should destroy a user and allow afterDestroy re-assignment', asyncToGenerator(regeneratorRuntime.mark(function _callee2() { + var adapter, User, props, user, userId, beforeDestroyCalled, afterDestroyCalled, destroyedUser; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + assert.debug('create', User.name, props); + _context2.next = 6; + return adapter.create(User, props); + + case 6: + user = _context2.sent; + userId = user[User.idAttribute]; + + assert.debug('created', User.name, user); + + beforeDestroyCalled = false; + afterDestroyCalled = false; + + // Test beforeDestroy and afterDestroy + + adapter.beforeDestroy = function (mapper, id, opts) { + beforeDestroyCalled = true; + assert.isObject(mapper, 'beforeDestroy should have received mapper argument'); + assert.isDefined(id, 'beforeDestroy should have received id argument'); + assert.isObject(opts, 'beforeDestroy should have received opts argument'); + // Test re-assignment + return Promise.resolve(); + }; + adapter.afterDestroy = function (mapper, id, opts) { + afterDestroyCalled = true; + assert.isObject(mapper, 'afterDestroy should have received mapper argument'); + assert.isDefined(id, 'afterDestroy should have received id argument'); + assert.isObject(opts, 'afterDestroy should have received opts argument'); + // Test re-assignment + return Promise.resolve('foo'); + }; + + assert.debug('destroy', User.name, userId); + _context2.next = 16; + return adapter.destroy(User, userId, { raw: true }); + + case 16: + destroyedUser = _context2.sent; + + assert.debug('destroyed', User.name, destroyedUser); + assert.equal(destroyedUser, 'foo', 'destroyedUser'); + assert.isTrue(beforeDestroyCalled, 'beforeDestroy should have been called'); + assert.isTrue(afterDestroyCalled, 'afterDestroy should have been called'); + + case 21: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + }))); + it('should destroy a user and return raw', asyncToGenerator(regeneratorRuntime.mark(function _callee3() { + var adapter, User, props, user, userId, result; + return regeneratorRuntime.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + assert.debug('create', User.name, props); + _context3.next = 6; + return adapter.create(User, props); + + case 6: + user = _context3.sent; + userId = user[User.idAttribute]; + + assert.debug('created', User.name, user); + + assert.debug('destroy', User.name, userId); + _context3.next = 12; + return adapter.destroy(User, userId, { raw: true }); + + case 12: + result = _context3.sent; + + assert.debug('destroyed', User.name, result); + assert.isUndefined(result.data, 'result.data'); + if (result.hasOwnProperty('deleted')) { + assert.isDefined(result.deleted, 'result.deleted'); + assert.equal(result.deleted, 1, 'result.deleted'); + } + + case 16: + case 'end': + return _context3.stop(); + } + } + }, _callee3, this); + }))); + it('should destroy nothing', asyncToGenerator(regeneratorRuntime.mark(function _callee4() { + var adapter, User, result; + return regeneratorRuntime.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + + + assert.debug('destroy', User.name, 'non-existent-id'); + _context4.next = 5; + return adapter.destroy(User, 'non-existent-id'); + + case 5: + result = _context4.sent; + + assert.debug('destroyed', User.name, result); + assert.isUndefined(result, 'result'); + + case 8: + case 'end': + return _context4.stop(); + } + } + }, _callee4, this); + }))); + it('should destroy nothing and return raw', asyncToGenerator(regeneratorRuntime.mark(function _callee5() { + var adapter, User, result; + return regeneratorRuntime.wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + + + assert.debug('destroy', User.name, 'non-existent-id'); + _context5.next = 5; + return adapter.destroy(User, 'non-existent-id', { raw: true }); + + case 5: + result = _context5.sent; + + assert.debug('destroyed', User.name, result); + assert.isUndefined(result.data, 'result.data'); + if (result.hasOwnProperty('deleted')) { + assert.isDefined(result.deleted, 'result.deleted'); + assert.equal(result.deleted, 0, 'result.deleted'); + } + + case 9: + case 'end': + return _context5.stop(); + } + } + }, _callee5, this); + }))); + }); +}; + +/* global assert:true */ +var destroyAllTest = function (options) { + describe('Adapter#destroyAll', function () { + it('should exist', function () { + assert.equal(_typeof(this.$$adapter.destroyAll), 'function', 'adapter should have a "destroyAll" method'); + }); + it('should destroy all users', asyncToGenerator(regeneratorRuntime.mark(function _callee() { + var adapter, User, props, user, userId, user2, foundUsers, destroyedUsers; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + assert.debug('create', User.name, props); + _context.next = 6; + return adapter.create(User, props); + + case 6: + user = _context.sent; + userId = user[User.idAttribute]; + + assert.debug('created', User.name, user); + + assert.debug('create', User.name, { name: 'Sally' }); + _context.next = 12; + return adapter.create(User, { name: 'Sally' }); + + case 12: + user2 = _context.sent; + + assert.debug('created', User.name, user2); + + assert.debug('findAll', User.name, { name: 'John' }); + _context.next = 17; + return adapter.findAll(User, { name: 'John' }); + + case 17: + foundUsers = _context.sent; + + assert.debug('found', User.name, foundUsers); + assert.equal(foundUsers.length, 1, 'foundUsers.length'); + assert.equal(foundUsers[0][User.idAttribute], userId, 'foundUsers[0][User.idAttribute]'); + assert.equal(foundUsers[0].name, 'John', 'foundUsers[0].name'); + + assert.debug('destroyAll', User.name, { name: 'John' }); + _context.next = 25; + return adapter.destroyAll(User, { name: 'John' }); + + case 25: + destroyedUsers = _context.sent; + + assert.debug('destroyed', User.name, destroyedUsers); + assert.isUndefined(destroyedUsers, 'destroyedUsers'); + + assert.debug('findAll', User.name, { name: 'John' }); + _context.next = 31; + return adapter.findAll(User, { name: 'John' }); + + case 31: + foundUsers = _context.sent; + + assert.debug('found', User.name, foundUsers); + assert.equal(foundUsers.length, 0); + + assert.debug('findAll', User.name, {}); + _context.next = 37; + return adapter.findAll(User, {}); + + case 37: + foundUsers = _context.sent; + + assert.debug('found', User.name, foundUsers); + assert.equal(foundUsers.length, 1); + + case 40: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + }))); + it('should destroy users and return raw', asyncToGenerator(regeneratorRuntime.mark(function _callee2() { + var adapter, User, props, user, result; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + assert.debug('create', User.name, props); + _context2.next = 6; + return adapter.create(User, props); + + case 6: + user = _context2.sent; + + assert.debug('created', User.name, user); + + assert.debug('destroyAll', User.name, props); + _context2.next = 11; + return adapter.destroyAll(User, props, { raw: true }); + + case 11: + result = _context2.sent; + + assert.debug('destroyed', User.name, result); + assert.isUndefined(result.data, 'result.data'); + if (result.hasOwnProperty('deleted')) { + assert.isDefined(result.deleted, 'result.deleted'); + assert.equal(result.deleted, 1, 'result.deleted'); + } + + case 15: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + }))); + it('should destroy nothing', asyncToGenerator(regeneratorRuntime.mark(function _callee3() { + var adapter, User, result; + return regeneratorRuntime.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + + + assert.debug('destroyAll', User.name, {}); + _context3.next = 5; + return adapter.destroyAll(User, {}); + + case 5: + result = _context3.sent; + + assert.debug('destroyed', User.name, result); + assert.isUndefined(result, 'result'); + + case 8: + case 'end': + return _context3.stop(); + } + } + }, _callee3, this); + }))); + it('should destroy nothing and return raw', asyncToGenerator(regeneratorRuntime.mark(function _callee4() { + var adapter, User, result; + return regeneratorRuntime.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + + + assert.debug('destroyAll', User.name, {}); + _context4.next = 5; + return adapter.destroyAll(User, {}, { raw: true }); + + case 5: + result = _context4.sent; + + assert.debug('destroyed', User.name, result); + assert.isUndefined(result.data, 'result.data'); + if (result.hasOwnProperty('deleted')) { + assert.isDefined(result.deleted, 'result.deleted'); + assert.equal(result.deleted, 0, 'result.deleted'); + } + + case 9: + case 'end': + return _context4.stop(); + } + } + }, _callee4, this); + }))); + }); +}; + +/* global assert:true */ +var extendTest = function (options) { + describe('Adapter.extend', function () { + it('should exist', function () { + assert.equal(_typeof(this.$$adapter.constructor.extend), 'function', 'adapter constructor function should have an "extend" method'); + }); + it('should return a subclass of the adapter class using extend', function () { + var Adapter = this.$$adapter.constructor; + + var SubAdapter = Adapter.extend({ + foo: function foo() { + return 'foo'; + } + }, { + bar: function bar() { + return 'bar'; + } + }); + + assert.equal(SubAdapter.bar(), 'bar', 'SubAdapter.bar() should return "bar"'); + try { + assert.isTrue(SubAdapter.extend === Adapter.extend, 'should have same static methods'); + } catch (err) { + assert.equal(_typeof(SubAdapter.extend), 'function', 'should have same static methods'); + } + + var subAdapter = new SubAdapter(); + + assert.equal(subAdapter.foo(), 'foo', 'subAdapter.foo() should return "foo"'); + assert.isTrue(subAdapter.find === subAdapter.find, 'should have same instance methods'); + }); + it('should return a subclass of the adapter class using ES6 classes', function () { + var Adapter = this.$$adapter.constructor; + + var SubAdapter = function (_Adapter) { + inherits(SubAdapter, _Adapter); + + function SubAdapter() { + classCallCheck(this, SubAdapter); + return possibleConstructorReturn(this, (SubAdapter.__proto__ || Object.getPrototypeOf(SubAdapter)).apply(this, arguments)); + } + + createClass(SubAdapter, [{ + key: 'foo', + value: function foo() { + return 'foo'; + } + }], [{ + key: 'bar', + value: function bar() { + return 'bar'; + } + }]); + return SubAdapter; + }(Adapter); + + assert.equal(SubAdapter.bar(), 'bar', 'SubAdapter.bar() should return "bar"'); + try { + assert.isTrue(SubAdapter.extend === Adapter.extend, 'should have same static methods'); + } catch (err) { + try { + assert.equal(_typeof(SubAdapter.extend), 'function', 'should have same static methods'); + } catch (err) { + var obj = {}; + if (obj.setPrototypeOf) { + throw err; + } + } + } + + var subAdapter = new SubAdapter(); + + assert.equal(subAdapter.foo(), 'foo', 'subAdapter.foo() should return "foo"'); + assert.isTrue(subAdapter.find === subAdapter.find, 'should have same instance methods'); + }); + }); +}; + +/* global assert:true */ +var findTest = function (options) { + describe('Adapter#find', function () { + var adapter, User, Profile, Post, Comment, Tag; + + beforeEach(function () { + adapter = this.$$adapter; + User = this.$$User; + Profile = this.$$Profile; + Post = this.$$Post; + Comment = this.$$Comment; + Tag = this.$$Tag; + }); + + it('should exist', function () { + assert.equal(_typeof(adapter.find), 'function', 'adapter should have a "find" method'); + }); + + it('should find a user', asyncToGenerator(regeneratorRuntime.mark(function _callee() { + var props, user, userId, beforeFindCalled, afterFindCalled, foundUser, post, postId, comments, foundPost; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + this.toClear.push('Post'); + this.toClear.push('Comment'); + props = { name: 'John' }; + + assert.debug('create', User.name, props); + _context.next = 6; + return adapter.create(User, props); + + case 6: + user = _context.sent; + + assert.debug('created', User.name, user); + userId = user[User.idAttribute]; + + assert.equal(user.name, 'John', 'user.name'); + assert.isDefined(user[User.idAttribute], 'user[User.idAttribute]'); + + // Test beforeFind and afterFind + beforeFindCalled = false; + afterFindCalled = false; + + adapter.beforeFind = function (mapper, id, opts) { + beforeFindCalled = true; + assert.isObject(mapper, 'beforeFind should have received mapper argument'); + assert.isDefined(id, 'beforeFind should have received id argument'); + assert.equal(id, userId, 'beforeFind should have received correct id argument'); + assert.isObject(opts, 'beforeFind should have received opts argument'); + // Optionally return a promise for async + return Promise.resolve(); + }; + adapter.afterFind = function (mapper, id, opts, record) { + afterFindCalled = true; + assert.isObject(mapper, 'afterFind should have received mapper argument'); + assert.isDefined(id, 'afterFind should have received id argument'); + assert.equal(id, userId, 'afterFind should have received correct id argument'); + assert.isObject(opts, 'afterFind should have received opts argument'); + assert.isObject(record, 'afterFind should have received record argument'); + // Optionally return a promise for async + return Promise.resolve(); + }; + + assert.debug('find', User.name, userId); + _context.next = 18; + return adapter.find(User, userId); + + case 18: + foundUser = _context.sent; + + assert.debug('found', User.name, foundUser); + assert.equal(foundUser.name, 'John', 'name of found user should be "John"'); + assert.equal(foundUser[User.idAttribute], userId, 'found user should have correct id'); + assert.isTrue(beforeFindCalled, 'beforeFind should have been called'); + assert.isTrue(afterFindCalled, 'afterFind should have been called'); + + // should allow re-assignment + beforeFindCalled = false; + afterFindCalled = false; + adapter.afterFind = function (mapper, id, opts, record) { + afterFindCalled = true; + assert.isObject(mapper, 'afterFind should have received mapper argument'); + assert.isDefined(id, 'afterFind should have received id argument'); + assert.equal(id, userId, 'afterFind should have received correct id argument'); + assert.isObject(opts, 'afterFind should have received opts argument'); + assert.isObject(record, 'afterFind should have received record argument'); + // Test re-assignment + return Promise.resolve(defineProperty({ name: 'Sally' }, User.idAttribute, userId)); + }; + + assert.debug('find', User.name, userId); + _context.next = 30; + return adapter.find(User, userId); + + case 30: + foundUser = _context.sent; + + assert.debug('found', User.name, foundUser); + assert.equal(foundUser.name, 'Sally', 'foundUser.name'); + assert.equal(foundUser[User.idAttribute], userId, 'foundUser[User.idAttribute]'); + assert.isTrue(beforeFindCalled, 'beforeFind should have been called'); + assert.isTrue(afterFindCalled, 'afterFind should have been called'); + // clear hooks + delete adapter.beforeFind; + delete adapter.afterFind; + + props = { content: 'test', userId: userId }; + assert.debug('create', Post.name, props); + _context.next = 42; + return adapter.create(Post, props); + + case 42: + post = _context.sent; + + assert.debug('created', Post.name, post); + postId = post[Post.idAttribute]; + + + assert.equal(post.content, 'test', 'post.content'); + assert.isDefined(post[Post.idAttribute], 'post[Post.idAttribute]'); + assert.equal(post.userId, userId, 'post.userId'); + + props = [{ + content: 'test2', + postId: postId, + userId: userId + }, { + content: 'test3', + postId: postId, + userId: userId + }]; + assert.debug('create', Comment.name, props); + _context.next = 52; + return Promise.all([adapter.create(Comment, props[0]), adapter.create(Comment, props[1])]); + + case 52: + comments = _context.sent; + + assert.debug('created', Comment.name, comments); + + comments.sort(function (a, b) { + return a.content > b.content; + }); + + assert.debug('find', Post.name, postId); + _context.next = 58; + return adapter.find(Post, postId, { with: ['user', 'comment'] }); + + case 58: + foundPost = _context.sent; + + assert.debug('found', Post.name, foundPost); + foundPost.comments.sort(function (a, b) { + return a.content > b.content; + }); + assert.equalObjects(foundPost.user, user, 'foundPost.user'); + assert.equalObjects(foundPost.comments, comments, 'foundPost.comments'); + + case 63: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + }))); + + it('should return raw', asyncToGenerator(regeneratorRuntime.mark(function _callee2() { + var props, user, userId, result; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + props = { name: 'John' }; + + assert.debug('create', User.name, props); + _context2.next = 4; + return adapter.create(User, props); + + case 4: + user = _context2.sent; + + assert.debug('created', User.name, user); + userId = user[User.idAttribute]; + + assert.equal(user.name, 'John', 'user.name'); + assert.isDefined(user[User.idAttribute], 'user[User.idAttribute]'); + + assert.debug('find', User.name, userId); + _context2.next = 12; + return adapter.find(User, userId, { raw: true }); + + case 12: + result = _context2.sent; + + assert.debug('found', User.name, result); + assert.isDefined(result.data, 'result.data'); + assert.isDefined(result.found, 'result.found'); + assert.equal(result.data.name, 'John', 'result.data.name'); + assert.equal(result.data[User.idAttribute], userId, 'result.data.' + User.idAttribute); + assert.equal(result.found, 1, 'result.found'); + + case 19: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + }))); + + it('should return nothing', asyncToGenerator(regeneratorRuntime.mark(function _callee3() { + var result; + return regeneratorRuntime.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + assert.debug('find', User.name, 'non-existent-id'); + _context3.next = 3; + return adapter.find(User, 'non-existent-id'); + + case 3: + result = _context3.sent; + + assert.debug('found', User.name, result); + assert.isUndefined(result, 'result'); + + case 6: + case 'end': + return _context3.stop(); + } + } + }, _callee3, this); + }))); + + it('should return raw and nothing', asyncToGenerator(regeneratorRuntime.mark(function _callee4() { + var result; + return regeneratorRuntime.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + assert.debug('find', User.name, 'non-existent-id'); + _context4.next = 3; + return adapter.find(User, 'non-existent-id', { raw: true }); + + case 3: + result = _context4.sent; + + assert.debug('found', User.name, result); + assert.isUndefined(result.data, 'result.data'); + assert.isDefined(result.found, 'result.found'); + assert.equal(result.found, 0, 'result.found'); + + case 8: + case 'end': + return _context4.stop(); + } + } + }, _callee4, this); + }))); + + it('should load belongsTo relations', asyncToGenerator(regeneratorRuntime.mark(function _callee5() { + var props, user, profile, post, comment; + return regeneratorRuntime.wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + this.toClear.push('Post'); + this.toClear.push('Comment'); + this.toClear.push('Profile'); + props = { name: 'John' }; + + assert.debug('create', User.name, props); + _context5.next = 7; + return adapter.create(User, props); + + case 7: + user = _context5.sent; + + assert.debug('created', User.name, user); + + props = { email: 'foo@test.com', userId: user[User.idAttribute] }; + assert.debug('create', Profile.name, props); + _context5.next = 13; + return adapter.create(Profile, props); + + case 13: + profile = _context5.sent; + + assert.debug('created', Profile.name, profile); + + props = { content: 'foo', userId: user[User.idAttribute] }; + assert.debug('create', Post.name, props); + _context5.next = 19; + return adapter.create(Post, props); + + case 19: + post = _context5.sent; + + assert.debug('created', Post.name, post); + + props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }; + assert.debug('create', Comment.name, props); + _context5.next = 25; + return adapter.create(Comment, props); + + case 25: + comment = _context5.sent; + + assert.debug('created', Comment.name, comment); + + assert.debug('find', Comment.name, comment[Comment.idAttribute]); + _context5.next = 30; + return adapter.find(Comment, comment[Comment.idAttribute], { 'with': ['user', 'post'] }); + + case 30: + comment = _context5.sent; + + assert.debug('found', Comment.name, comment); + + assert.isDefined(comment, 'comment'); + assert.isDefined(comment.post, 'comment.post'); + assert.isDefined(comment.user, 'comment.user'); + + case 35: + case 'end': + return _context5.stop(); + } + } + }, _callee5, this); + }))); + + it('should load belongsTo relations and filter sub queries', asyncToGenerator(regeneratorRuntime.mark(function _callee6() { + var props, user, user2, post, post2, post3, post4; + return regeneratorRuntime.wrap(function _callee6$(_context6) { + while (1) { + switch (_context6.prev = _context6.next) { + case 0: + this.toClear.push('Post'); + this.toClear.push('Comment'); + props = { name: 'John' }; + + assert.debug('create', User.name, props); + _context6.next = 6; + return adapter.create(User, props); + + case 6: + user = _context6.sent; + + assert.debug('created', User.name, user); + + props = { name: 'Sally' }; + assert.debug('create', User.name, props); + _context6.next = 12; + return adapter.create(User, props); + + case 12: + user2 = _context6.sent; + + assert.debug('created', User.name, user); + + props = { status: 'draft', userId: user[User.idAttribute] }; + assert.debug('create', Post.name, props); + _context6.next = 18; + return adapter.create(Post, props); + + case 18: + post = _context6.sent; + + assert.debug('created', Post.name, post); + + props = { status: 'published', userId: user[User.idAttribute] }; + assert.debug('create', Post.name, props); + _context6.next = 24; + return adapter.create(Post, props); + + case 24: + post2 = _context6.sent; + + assert.debug('created', Post.name, post2); + + props = { status: 'draft', userId: user2[User.idAttribute] }; + assert.debug('create', Post.name, props); + _context6.next = 30; + return adapter.create(Post, props); + + case 30: + post3 = _context6.sent; + + assert.debug('created', Post.name, post3); + + props = { status: 'published', userId: user2[User.idAttribute] }; + assert.debug('create', Post.name, props); + _context6.next = 36; + return adapter.create(Post, props); + + case 36: + post4 = _context6.sent; + + assert.debug('created', Post.name, post4); + + assert.debug('find', User.name, user[User.idAttribute]); + _context6.next = 41; + return adapter.find(User, user[User.idAttribute], { 'with': ['post'] }); + + case 41: + user = _context6.sent; + + assert.debug('found', User.name, user); + + assert.isDefined(user, 'user'); + assert.isDefined(user.posts, 'user.posts'); + assert.equal(user.posts.length, 2, 'user.posts.length'); + + assert.debug('find', User.name, user[User.idAttribute]); + _context6.next = 49; + return adapter.find(User, user[User.idAttribute], { 'with': [{ + relation: 'post', + query: { + status: 'published' + } + }] }); + + case 49: + user = _context6.sent; + + assert.debug('found', User.name, user); + + assert.isDefined(user, 'user'); + assert.isDefined(user.posts, 'user.posts'); + assert.equal(user.posts.length, 1, 'user.posts.length'); + + assert.debug('find', User.name, user[User.idAttribute]); + _context6.next = 57; + return adapter.find(User, user[User.idAttribute], { 'with': [{ + relation: 'post', + replace: true, + query: { + status: 'published' + } + }] }); + + case 57: + user = _context6.sent; + + assert.debug('found', User.name, user); + + assert.isDefined(user, 'user'); + assert.isDefined(user.posts, 'user.posts'); + assert.equal(user.posts.length, 2, 'user.posts.length'); + + case 62: + case 'end': + return _context6.stop(); + } + } + }, _callee6, this); + }))); + + if (options.hasFeature('findBelongsToNested')) { + it('should load belongsTo relations (nested)', asyncToGenerator(regeneratorRuntime.mark(function _callee7() { + var props, user, profile, post, comment; + return regeneratorRuntime.wrap(function _callee7$(_context7) { + while (1) { + switch (_context7.prev = _context7.next) { + case 0: + this.toClear.push('Post'); + this.toClear.push('Comment'); + this.toClear.push('Profile'); + props = { name: 'John' }; + + assert.debug('create', User.name, props); + _context7.next = 7; + return adapter.create(User, props); + + case 7: + user = _context7.sent; + + assert.debug('created', User.name, user); + + props = { email: 'foo@test.com', userId: user[User.idAttribute] }; + assert.debug('create', Profile.name, props); + _context7.next = 13; + return adapter.create(Profile, props); + + case 13: + profile = _context7.sent; + + assert.debug('created', Profile.name, profile); + + props = { content: 'foo', userId: user[User.idAttribute] }; + assert.debug('create', Post.name, props); + _context7.next = 19; + return adapter.create(Post, props); + + case 19: + post = _context7.sent; + + assert.debug('created', Post.name, post); + + props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }; + assert.debug('create', Comment.name, props); + _context7.next = 25; + return adapter.create(Comment, props); + + case 25: + comment = _context7.sent; + + assert.debug('created', Comment.name, comment); + + assert.debug('find', Comment.name, comment[Comment.idAttribute]); + _context7.next = 30; + return adapter.find(Comment, comment[Comment.idAttribute], { 'with': ['user', 'user.profile', 'post', 'post.user'] }); + + case 30: + comment = _context7.sent; + + assert.debug('found', Comment.name, comment); + + assert.isDefined(comment, 'comment'); + assert.isDefined(comment.post, 'comment.post'); + assert.isDefined(comment.post.user, 'comment.post.user'); + assert.isDefined(comment.user, 'comment.user'); + assert.isDefined(comment.user.profile, 'comment.user.profile'); + + case 37: + case 'end': + return _context7.stop(); + } + } + }, _callee7, this); + }))); + } + + it('should load hasMany and belongsTo relations', asyncToGenerator(regeneratorRuntime.mark(function _callee8() { + var props, user, profile, post, postId, comment; + return regeneratorRuntime.wrap(function _callee8$(_context8) { + while (1) { + switch (_context8.prev = _context8.next) { + case 0: + this.toClear.push('Post'); + this.toClear.push('Comment'); + this.toClear.push('Profile'); + props = { name: 'John' }; + + assert.debug('create', User.name, props); + _context8.next = 7; + return adapter.create(User, props); + + case 7: + user = _context8.sent; + + assert.debug('created', User.name, user); + + props = { email: 'foo@test.com', userId: user[User.idAttribute] }; + assert.debug('create', Profile.name, props); + _context8.next = 13; + return adapter.create(Profile, props); + + case 13: + profile = _context8.sent; + + assert.debug('created', Profile.name, profile); + + props = { content: 'foo', userId: user[User.idAttribute] }; + assert.debug('create', Post.name, props); + _context8.next = 19; + return adapter.create(Post, props); + + case 19: + post = _context8.sent; + postId = post[Post.idAttribute]; + + assert.debug('created', Post.name, post); + + props = { content: 'test2', postId: postId, userId: post.userId }; + assert.debug('create', Comment.name, props); + _context8.next = 26; + return adapter.create(Comment, props); + + case 26: + comment = _context8.sent; + + assert.debug('created', Comment.name, comment); + + assert.debug('find', Post.name, postId); + _context8.next = 31; + return adapter.find(Post, postId, { 'with': ['user', 'comment'] }); + + case 31: + post = _context8.sent; + + assert.debug('found', Post.name, post); + + assert.isDefined(post.comments, 'post.comments'); + assert.isDefined(post.user, 'post.user'); + + case 35: + case 'end': + return _context8.stop(); + } + } + }, _callee8, this); + }))); + + if (options.hasFeature('findBelongsToHasManyNested')) { + it('should load hasMany and belongsTo relations (nested)', asyncToGenerator(regeneratorRuntime.mark(function _callee9() { + var props, user, profile, post, postId, comment; + return regeneratorRuntime.wrap(function _callee9$(_context9) { + while (1) { + switch (_context9.prev = _context9.next) { + case 0: + this.toClear.push('Post'); + this.toClear.push('Comment'); + this.toClear.push('Profile'); + props = { name: 'John' }; + + assert.debug('create', User.name, props); + _context9.next = 7; + return adapter.create(User, props); + + case 7: + user = _context9.sent; + + assert.debug('created', User.name, user); + + props = { email: 'foo@test.com', userId: user[User.idAttribute] }; + assert.debug('create', Profile.name, props); + _context9.next = 13; + return adapter.create(Profile, props); + + case 13: + profile = _context9.sent; + + assert.debug('created', Profile.name, profile); + + props = { content: 'foo', userId: user[User.idAttribute] }; + assert.debug('create', Post.name, props); + _context9.next = 19; + return adapter.create(Post, props); + + case 19: + post = _context9.sent; + postId = post[Post.idAttribute]; + + assert.debug('created', Post.name, post); + + props = { content: 'test2', postId: postId, userId: post.userId }; + assert.debug('create', Comment.name, props); + _context9.next = 26; + return adapter.create(Comment, props); + + case 26: + comment = _context9.sent; + + assert.debug('created', Comment.name, comment); + + assert.debug('find', Post.name, postId); + _context9.next = 31; + return adapter.find(Post, postId, { 'with': ['user', 'comment', 'comment.user', 'comment.user.profile'] }); + + case 31: + post = _context9.sent; + + assert.debug('found', Post.name, post); + + assert.isDefined(post.comments, 'post.comments'); + assert.isDefined(post.comments[0].user, 'post.comments[0].user'); + assert.isDefined(post.comments[0].user.profile, 'post.comments[0].user.profile'); + assert.isDefined(post.user, 'post.user'); + + case 37: + case 'end': + return _context9.stop(); + } + } + }, _callee9, this); + }))); + } + + if (options.hasFeature('findHasManyLocalKeys')) { + it('should load hasMany localKeys (array) relations', asyncToGenerator(regeneratorRuntime.mark(function _callee10() { + var props, tag, tag2, post, postId; + return regeneratorRuntime.wrap(function _callee10$(_context10) { + while (1) { + switch (_context10.prev = _context10.next) { + case 0: + this.toClear.push('Post'); + this.toClear.push('Tag'); + props = { value: 'big data' }; + + assert.debug('create', Tag.name, props); + _context10.next = 6; + return adapter.create(Tag, props); + + case 6: + tag = _context10.sent; + + assert.debug('created', Tag.name, tag); + + props = { value: 'servers' }; + assert.debug('create', Tag.name, props); + _context10.next = 12; + return adapter.create(Tag, props); + + case 12: + tag2 = _context10.sent; + + assert.debug('created', Tag.name, tag2); + + props = { content: 'test', tagIds: [tag[Tag.idAttribute], tag2[Tag.idAttribute]] }; + assert.debug('create', Post.name, props); + _context10.next = 18; + return adapter.create(Post, props); + + case 18: + post = _context10.sent; + postId = post[Post.idAttribute]; + + assert.debug('created', Post.name, post); + + assert.debug('find', Post.name, postId); + _context10.next = 24; + return adapter.find(Post, postId, { 'with': ['tag'] }); + + case 24: + post = _context10.sent; + + assert.debug('found', Post.name, post); + + assert.isDefined(post.tags, 'post.tags'); + assert.equal(post.content, 'test', 'post.content'); + assert.isDefined(post.tags[0][Tag.idAttribute], 'post.tags[0][Tag.idAttribute]'); + assert.isDefined(post.tags[1][Tag.idAttribute], 'post.tags[1][Tag.idAttribute]'); + + case 30: + case 'end': + return _context10.stop(); + } + } + }, _callee10, this); + }))); + it('should load hasMany localKeys (empty array) relations', asyncToGenerator(regeneratorRuntime.mark(function _callee11() { + var props, post, postId; + return regeneratorRuntime.wrap(function _callee11$(_context11) { + while (1) { + switch (_context11.prev = _context11.next) { + case 0: + this.toClear.push('Post'); + props = { content: 'test' }; + + assert.debug('create', Post.name, props); + _context11.next = 5; + return adapter.create(Post, props); + + case 5: + post = _context11.sent; + postId = post[Post.idAttribute]; + + assert.debug('created', Post.name, post); + + assert.debug('find', Post.name, postId); + _context11.next = 11; + return adapter.find(Post, postId, { 'with': ['tag'] }); + + case 11: + post = _context11.sent; + + assert.debug('found', Post.name, post); + + assert.isDefined(post.tags, 'post.tags'); + assert.equal(post.content, 'test', 'post.content'); + assert.deepEqual(post.tags, [], 'post.tags'); + + case 16: + case 'end': + return _context11.stop(); + } + } + }, _callee11, this); + }))); + it('should load hasMany localKeys (object) relations', asyncToGenerator(regeneratorRuntime.mark(function _callee12() { + var _tagIds; + + var props, tag, tag2, post, postId; + return regeneratorRuntime.wrap(function _callee12$(_context12) { + while (1) { + switch (_context12.prev = _context12.next) { + case 0: + this.toClear.push('Post'); + this.toClear.push('Tag'); + props = { value: 'big data' }; + + assert.debug('create', Tag.name, props); + _context12.next = 6; + return adapter.create(Tag, props); + + case 6: + tag = _context12.sent; + + assert.debug('created', Tag.name, tag); + + props = { value: 'servers' }; + assert.debug('create', Tag.name, props); + _context12.next = 12; + return adapter.create(Tag, props); + + case 12: + tag2 = _context12.sent; + + assert.debug('created', Tag.name, tag2); + + props = { content: 'test', tagIds: (_tagIds = {}, defineProperty(_tagIds, tag[Tag.idAttribute], true), defineProperty(_tagIds, tag2[Tag.idAttribute], true), _tagIds) }; + assert.debug('create', Post.name, props); + _context12.next = 18; + return adapter.create(Post, props); + + case 18: + post = _context12.sent; + postId = post[Post.idAttribute]; + + assert.debug('created', Post.name, post); + + assert.debug('find', Post.name, postId); + _context12.next = 24; + return adapter.find(Post, postId, { 'with': ['tag'] }); + + case 24: + post = _context12.sent; + + assert.debug('found', Post.name); + + assert.isDefined(post.tags, 'post.tags'); + assert.equal(post.content, 'test', 'post.content'); + assert.isDefined(post.tags[0][Tag.idAttribute], 'post.tags[0][Tag.idAttribute]'); + assert.isDefined(post.tags[1][Tag.idAttribute], 'post.tags[1][Tag.idAttribute]'); + + case 30: + case 'end': + return _context12.stop(); + } + } + }, _callee12, this); + }))); + } + + if (options.hasFeature('findHasManyForeignKeys')) { + it('should load hasMany foreignKeys (array) relations', asyncToGenerator(regeneratorRuntime.mark(function _callee13() { + var props, tag, tagId, tag2, tag2Id, post, post2; + return regeneratorRuntime.wrap(function _callee13$(_context13) { + while (1) { + switch (_context13.prev = _context13.next) { + case 0: + this.toClear.push('Post'); + this.toClear.push('Tag'); + props = { value: 'big data' }; + + assert.debug('create', Tag.name, props); + _context13.next = 6; + return adapter.create(Tag, props); + + case 6: + tag = _context13.sent; + tagId = tag[Tag.idAttribute]; + + assert.debug('created', Tag.name, tag); + + props = { value: 'servers' }; + assert.debug('create', Tag.name, props); + _context13.next = 13; + return adapter.create(Tag, props); + + case 13: + tag2 = _context13.sent; + tag2Id = tag2[Tag.idAttribute]; + + assert.debug('created', Tag.name, tag2); + + props = { content: 'test', tagIds: [tagId] }; + assert.debug('create', Post.name, props); + _context13.next = 20; + return adapter.create(Post, props); + + case 20: + post = _context13.sent; + + assert.debug('created', Post.name, post); + + props = { content: 'test2', tagIds: [tagId, tag2Id] }; + assert.debug('create', Post.name, props); + _context13.next = 26; + return adapter.create(Post, props); + + case 26: + post2 = _context13.sent; + + assert.debug('created', Post.name, post2); + + assert.debug('find', Tag.name, tagId); + _context13.next = 31; + return adapter.find(Tag, tagId, { 'with': ['post'] }); + + case 31: + tag = _context13.sent; + + assert.debug('found', Tag.name, tag); + + assert.isDefined(tag.posts, 'tag.posts'); + assert.equal(tag.value, 'big data', 'tag.value'); + assert.equal(tag.posts.length, 2, 'tag.posts.length'); + + assert.debug('find', Tag.name, tag2Id); + _context13.next = 39; + return adapter.find(Tag, tag2Id, { 'with': ['post'] }); + + case 39: + tag2 = _context13.sent; + + assert.debug('found', Tag.name, tag2); + + assert.isDefined(tag2.posts, 'tag2.posts'); + assert.equal(tag2.value, 'servers', 'tag2.value'); + assert.equal(tag2.posts.length, 1, 'tag2.posts.length'); + assert.objectsEqual(tag2.posts, [post2], 'tag2.posts'); + + case 45: + case 'end': + return _context13.stop(); + } + } + }, _callee13, this); + }))); + } + }); +}; + +/* global assert:true */ +var findAllTest = function (options) { + describe('Adapter#findAll', function () { + var adapter, User, Profile, Post, Comment; + + beforeEach(function () { + adapter = this.$$adapter; + User = this.$$User; + Profile = this.$$Profile; + Post = this.$$Post; + Comment = this.$$Comment; + }); + + it('should exist', function () { + assert.equal(_typeof(adapter.findAll), 'function', 'adapter should have a "findAll" method'); + }); + + it('should filter users', asyncToGenerator(regeneratorRuntime.mark(function _callee() { + var props, users, user, userId, users2; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + props = { name: 'John' }; + + assert.debug('findAll', User.name, { age: 30 }); + _context.next = 4; + return adapter.findAll(User, { age: 30 }); + + case 4: + users = _context.sent; + + assert.debug('found', User.name, users); + assert.equal(users.length, 0, 'users.length'); + + assert.debug('create', User.name, props); + _context.next = 10; + return adapter.create(User, props); + + case 10: + user = _context.sent; + + assert.debug('created', User.name, user); + userId = user[User.idAttribute]; + + + assert.debug('findAll', User.name, { name: 'John' }); + _context.next = 16; + return adapter.findAll(User, { name: 'John' }); + + case 16: + users2 = _context.sent; + + assert.debug('found', User.name, users2); + + assert.equal(users2.length, 1, 'users2.length'); + assert.equal(users2[0][User.idAttribute], userId, 'users2[0][User.idAttribute]'); + assert.equal(users2[0].name, 'John', users2[0].name); + + case 21: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + }))); + + it('should filter users with raw option', asyncToGenerator(regeneratorRuntime.mark(function _callee2() { + var props, result, users, user, userId, result2, users2; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + props = { name: 'John' }; + + assert.debug('findAll', User.name, { age: 30 }); + _context2.next = 4; + return adapter.findAll(User, { age: 30 }, { raw: true }); + + case 4: + result = _context2.sent; + users = result.data; + + assert.debug('found', User.name, users); + assert.equal(users.length, 0, 'users.length'); + + assert.debug('create', User.name, props); + _context2.next = 11; + return adapter.create(User, props); + + case 11: + user = _context2.sent; + + assert.debug('created', User.name, user); + userId = user[User.idAttribute]; + + + assert.debug('findAll', User.name, { name: 'John' }); + _context2.next = 17; + return adapter.findAll(User, { name: 'John' }, { raw: true }); + + case 17: + result2 = _context2.sent; + users2 = result2.data; + + assert.debug('found', User.name, users2); + + assert.equal(users2.length, 1, 'users2.length'); + assert.equal(users2[0][User.idAttribute], userId, 'users2[0][User.idAttribute]'); + assert.equal(users2[0].name, 'John', users2[0].name); + + case 23: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + }))); + + if (options.hasFeature('findAllInOp')) { + it('should filter users using the "in" operator', asyncToGenerator(regeneratorRuntime.mark(function _callee3() { + var users, user, id, users2; + return regeneratorRuntime.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + _context3.next = 2; + return adapter.findAll(User, { + where: { + age: { + 'in': [30] + } + } + }); + + case 2: + users = _context3.sent; + + assert.equal(users.length, 0, 'users.length'); + + _context3.next = 6; + return adapter.create(User, { name: 'John' }); + + case 6: + user = _context3.sent; + id = user[User.idAttribute]; + _context3.next = 10; + return adapter.findAll(User, { name: 'John' }); + + case 10: + users2 = _context3.sent; + + assert.equal(users2.length, 1, 'users2.length'); + assert.equal(users2[0][User.idAttribute], id, 'users2[0][User.idAttribute]'); + assert.equal(users2[0].name, 'John', 'users2[0].name'); + + case 14: + case 'end': + return _context3.stop(); + } + } + }, _callee3, this); + }))); + } + + if (options.hasFeature('findAllLikeOp')) { + it('should filter users using the "like" operator', asyncToGenerator(regeneratorRuntime.mark(function _callee4() { + var users, user, id, users2; + return regeneratorRuntime.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + _context4.next = 2; + return adapter.findAll(User, { + where: { + name: { + 'like': '%J%' + } + } + }); + + case 2: + users = _context4.sent; + + assert.equal(users.length, 0); + + _context4.next = 6; + return adapter.create(User, { name: 'John' }); + + case 6: + user = _context4.sent; + id = user.id; + _context4.next = 10; + return adapter.findAll(User, { + where: { + name: { + 'like': '%J%' + } + } + }); + + case 10: + users2 = _context4.sent; + + assert.equal(users2.length, 1); + assert.equal(users2[0].id, id); + assert.equal(users2[0].name, 'John'); + + case 14: + case 'end': + return _context4.stop(); + } + } + }, _callee4, this); + }))); + } + + if (options.hasFeature('findAllOpNotFound')) { + it('should throw "Operator not found" error', function () { + return adapter.findAll(User, { + where: { + name: { + op: 'John' + } + } + }).then(function () { + throw new Error('should have failed!'); + }, function (err) { + assert.equal(err.message, 'Operator op not supported!'); + }); + }); + } + + if (options.hasFeature('findAllBelongsTo')) { + it('should load belongsTo relations', asyncToGenerator(regeneratorRuntime.mark(function _callee5() { + var props, user, profile, post, comment, user2, post2, comment2, comments; + return regeneratorRuntime.wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + this.toClear.push('Post'); + this.toClear.push('Profile'); + this.toClear.push('Comment'); + props = { name: 'John' }; + + assert.debug('create', User.name, props); + _context5.next = 7; + return adapter.create(User, props); + + case 7: + user = _context5.sent; + + assert.debug('created', User.name, user); + + props = { email: 'foo@test.com', userId: user[User.idAttribute] }; + assert.debug('create', Profile.name, props); + _context5.next = 13; + return adapter.create(Profile, props); + + case 13: + profile = _context5.sent; + + assert.debug('created', Profile.name, profile); + + props = { content: 'foo', userId: user[User.idAttribute] }; + assert.debug('create', Post.name, props); + _context5.next = 19; + return adapter.create(Post, props); + + case 19: + post = _context5.sent; + + assert.debug('created', Post.name, post); + + props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }; + assert.debug('create', Comment.name, props); + _context5.next = 25; + return adapter.create(Comment, props); + + case 25: + comment = _context5.sent; + + assert.debug('created', Comment.name, comment); + + props = { name: 'Sally' }; + assert.debug('create', User.name, props); + _context5.next = 31; + return adapter.create(User, props); + + case 31: + user2 = _context5.sent; + + assert.debug('created', User.name, user2); + + props = { content: 'bar', userId: user2[User.idAttribute] }; + assert.debug('create', Post.name, props); + _context5.next = 37; + return adapter.create(Post, props); + + case 37: + post2 = _context5.sent; + + assert.debug('created', Post.name, post2); + + props = { content: 'test67', postId: post2[Post.idAttribute], userId: post2.userId }; + assert.debug('create', Comment.name, props); + _context5.next = 43; + return adapter.create(Comment, props); + + case 43: + comment2 = _context5.sent; + + assert.debug('created', Comment.name, comment2); + + assert.debug('findAll', Comment.name, {}); + _context5.next = 48; + return adapter.findAll(Comment, {}, { 'with': ['user', 'post'] }); + + case 48: + comments = _context5.sent; + + assert.debug('found', Comment.name, comments); + + assert.isDefined(comments[0].post, 'comments[0].post'); + assert.isDefined(comments[0].user, 'comments[0].user'); + assert.isDefined(comments[1].post, 'comments[1].post'); + assert.isDefined(comments[1].user, 'comments[1].user'); + + case 54: + case 'end': + return _context5.stop(); + } + } + }, _callee5, this); + }))); + + it('should load belongsTo relations and filter sub queries', asyncToGenerator(regeneratorRuntime.mark(function _callee6() { + var props, user, user2, post, post2, post3, post4, users; + return regeneratorRuntime.wrap(function _callee6$(_context6) { + while (1) { + switch (_context6.prev = _context6.next) { + case 0: + this.toClear.push('Post'); + this.toClear.push('Comment'); + props = { name: 'John' }; + + assert.debug('create', User.name, props); + _context6.next = 6; + return adapter.create(User, props); + + case 6: + user = _context6.sent; + + assert.debug('created', User.name, user); + + props = { name: 'Sally' }; + assert.debug('create', User.name, props); + _context6.next = 12; + return adapter.create(User, props); + + case 12: + user2 = _context6.sent; + + assert.debug('created', User.name, user); + + props = { status: 'draft', userId: user[User.idAttribute] }; + assert.debug('create', Post.name, props); + _context6.next = 18; + return adapter.create(Post, props); + + case 18: + post = _context6.sent; + + assert.debug('created', Post.name, post); + + props = { status: 'published', userId: user[User.idAttribute] }; + assert.debug('create', Post.name, props); + _context6.next = 24; + return adapter.create(Post, props); + + case 24: + post2 = _context6.sent; + + assert.debug('created', Post.name, post2); + + props = { status: 'draft', userId: user2[User.idAttribute] }; + assert.debug('create', Post.name, props); + _context6.next = 30; + return adapter.create(Post, props); + + case 30: + post3 = _context6.sent; + + assert.debug('created', Post.name, post3); + + props = { status: 'published', userId: user2[User.idAttribute] }; + assert.debug('create', Post.name, props); + _context6.next = 36; + return adapter.create(Post, props); + + case 36: + post4 = _context6.sent; + + assert.debug('created', Post.name, post4); + + assert.debug('findAll', User.name, defineProperty({}, User.idAttribute, user[User.idAttribute])); + _context6.next = 41; + return adapter.findAll(User, defineProperty({}, User.idAttribute, user[User.idAttribute]), { 'with': ['post'] }); + + case 41: + users = _context6.sent; + + assert.debug('found', User.name, users); + + assert.isDefined(users, 'users'); + assert.isDefined(users[0].posts, 'users[0].posts'); + assert.equal(users[0].posts.length, 2, 'users[0].posts.length'); + + assert.debug('findAll', User.name, defineProperty({}, User.idAttribute, user[User.idAttribute])); + _context6.next = 49; + return adapter.findAll(User, defineProperty({}, User.idAttribute, user[User.idAttribute]), { 'with': [{ + relation: 'post', + query: { + status: 'published' + } + }] }); + + case 49: + users = _context6.sent; + + assert.debug('found', User.name, users); + + assert.isDefined(users, 'users'); + assert.isDefined(users[0].posts, 'users[0].posts'); + assert.equal(users[0].posts.length, 1, 'users[0].posts.length'); + + assert.debug('findAll', User.name, defineProperty({}, User.idAttribute, user[User.idAttribute])); + _context6.next = 57; + return adapter.findAll(User, defineProperty({}, User.idAttribute, user[User.idAttribute]), { 'with': [{ + relation: 'post', + replace: true, + query: { + status: 'published' + } + }] }); + + case 57: + users = _context6.sent; + + assert.debug('found', User.name, users); + + assert.isDefined(user, 'user'); + assert.isDefined(users[0].posts, 'users[0].posts'); + assert.equal(users[0].posts.length, 1, 'users[0].posts.length'); + + case 62: + case 'end': + return _context6.stop(); + } + } + }, _callee6, this); + }))); + } + + if (options.hasFeature('findAllBelongsToNested')) { + it('should load belongsTo relations (nested)', asyncToGenerator(regeneratorRuntime.mark(function _callee7() { + var props, user, profile, post, comment, user2, post2, comment2, comments; + return regeneratorRuntime.wrap(function _callee7$(_context7) { + while (1) { + switch (_context7.prev = _context7.next) { + case 0: + this.toClear.push('Post'); + this.toClear.push('Profile'); + this.toClear.push('Comment'); + props = { name: 'John' }; + + assert.debug('create', User.name, props); + _context7.next = 7; + return adapter.create(User, props); + + case 7: + user = _context7.sent; + + assert.debug('created', User.name, user); + + props = { email: 'foo@test.com', userId: user[User.idAttribute] }; + assert.debug('create', Profile.name, props); + _context7.next = 13; + return adapter.create(Profile, props); + + case 13: + profile = _context7.sent; + + assert.debug('created', Profile.name, profile); + + props = { content: 'foo', userId: user[User.idAttribute] }; + assert.debug('create', Post.name, props); + _context7.next = 19; + return adapter.create(Post, props); + + case 19: + post = _context7.sent; + + assert.debug('created', Post.name, post); + + props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }; + assert.debug('create', Comment.name, props); + _context7.next = 25; + return adapter.create(Comment, props); + + case 25: + comment = _context7.sent; + + assert.debug('created', Comment.name, comment); + + props = { name: 'Sally' }; + assert.debug('create', User.name, props); + _context7.next = 31; + return adapter.create(User, props); + + case 31: + user2 = _context7.sent; + + assert.debug('created', User.name, user2); + + props = { content: 'bar', userId: user2[User.idAttribute] }; + assert.debug('create', Post.name, props); + _context7.next = 37; + return adapter.create(Post, props); + + case 37: + post2 = _context7.sent; + + assert.debug('created', Post.name, post2); + + props = { content: 'test67', postId: post2[Post.idAttribute], userId: post2.userId }; + assert.debug('create', Comment.name, props); + _context7.next = 43; + return adapter.create(Comment, props); + + case 43: + comment2 = _context7.sent; + + assert.debug('created', Comment.name, comment2); + + assert.debug('findAll', Comment.name, {}); + _context7.next = 48; + return adapter.findAll(Comment, {}, { 'with': ['user', 'user.profile', 'post', 'post.user'] }); + + case 48: + comments = _context7.sent; + + assert.debug('found', Comment.name, comments); + + assert.isDefined(comments[0].post, 'comments[0].post'); + assert.isDefined(comments[0].post.user, 'comments[0].post.user'); + assert.isDefined(comments[0].user, 'comments[0].user'); + assert.isDefined(comments[0].user.profile || comments[1].user.profile, 'comments[0].user.profile || comments[1].user.profile'); + assert.isDefined(comments[1].post, 'comments[1].post'); + assert.isDefined(comments[1].post.user, 'comments[1].post.user'); + assert.isDefined(comments[1].user, 'comments[1].user'); + + case 57: + case 'end': + return _context7.stop(); + } + } + }, _callee7, this); + }))); + } + + if (options.hasFeature('findAllBelongsToHasMany')) { + it('should load hasMany and belongsTo relations', asyncToGenerator(regeneratorRuntime.mark(function _callee8() { + var props, user, profile, post, comment, user2, post2, comment2, posts; + return regeneratorRuntime.wrap(function _callee8$(_context8) { + while (1) { + switch (_context8.prev = _context8.next) { + case 0: + this.toClear.push('Post'); + this.toClear.push('Profile'); + this.toClear.push('Comment'); + props = { name: 'John' }; + + assert.debug('create', User.name, props); + _context8.next = 7; + return adapter.create(User, props); + + case 7: + user = _context8.sent; + + assert.debug('created', User.name, user); + + props = { email: 'foo@test.com', userId: user[User.idAttribute] }; + assert.debug('create', Profile.name, props); + _context8.next = 13; + return adapter.create(Profile, props); + + case 13: + profile = _context8.sent; + + assert.debug('created', Profile.name, profile); + + props = { content: 'foo', userId: user[User.idAttribute] }; + assert.debug('create', Post.name, props); + _context8.next = 19; + return adapter.create(Post, props); + + case 19: + post = _context8.sent; + + assert.debug('created', Post.name, post); + + props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }; + assert.debug('create', Comment.name, props); + _context8.next = 25; + return adapter.create(Comment, props); + + case 25: + comment = _context8.sent; + + assert.debug('created', Comment.name, comment); + + props = { name: 'Sally' }; + assert.debug('create', User.name, props); + _context8.next = 31; + return adapter.create(User, props); + + case 31: + user2 = _context8.sent; + + assert.debug('created', User.name, user2); + + props = { content: 'bar', userId: user2[User.idAttribute] }; + assert.debug('create', Post.name, props); + _context8.next = 37; + return adapter.create(Post, props); + + case 37: + post2 = _context8.sent; + + assert.debug('created', Post.name, post2); + + props = { content: 'test67', postId: post2[Post.idAttribute], userId: post2.userId }; + assert.debug('create', Comment.name, props); + _context8.next = 43; + return adapter.create(Comment, props); + + case 43: + comment2 = _context8.sent; + + assert.debug('created', Comment.name, comment2); + + assert.debug('find', Post.name, {}); + _context8.next = 48; + return adapter.findAll(Post, {}, { 'with': ['user', 'comment'] }); + + case 48: + posts = _context8.sent; + + assert.debug('found', Post.name, posts); + + assert.isDefined(posts[0].comments, 'posts[0].comments'); + assert.isDefined(posts[0].user, 'posts[0].user'); + assert.isDefined(posts[1].comments, 'posts[1].comments'); + assert.isDefined(posts[1].user, 'posts[1].user'); + + case 54: + case 'end': + return _context8.stop(); + } + } + }, _callee8, this); + }))); + } + + if (options.hasFeature('findAllBelongsToHasManyNested')) { + it('should load hasMany and belongsTo relations', asyncToGenerator(regeneratorRuntime.mark(function _callee9() { + var props, user, profile, post, comment, user2, post2, comment2, posts; + return regeneratorRuntime.wrap(function _callee9$(_context9) { + while (1) { + switch (_context9.prev = _context9.next) { + case 0: + this.toClear.push('Post'); + this.toClear.push('Profile'); + this.toClear.push('Comment'); + props = { name: 'John' }; + + assert.debug('create', User.name, props); + _context9.next = 7; + return adapter.create(User, props); + + case 7: + user = _context9.sent; + + assert.debug('created', User.name, user); + + props = { email: 'foo@test.com', userId: user[User.idAttribute] }; + assert.debug('create', Profile.name, props); + _context9.next = 13; + return adapter.create(Profile, props); + + case 13: + profile = _context9.sent; + + assert.debug('created', Profile.name, profile); + + props = { content: 'foo', userId: user[User.idAttribute] }; + assert.debug('create', Post.name, props); + _context9.next = 19; + return adapter.create(Post, props); + + case 19: + post = _context9.sent; + + assert.debug('created', Post.name, post); + + props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }; + assert.debug('create', Comment.name, props); + _context9.next = 25; + return adapter.create(Comment, props); + + case 25: + comment = _context9.sent; + + assert.debug('created', Comment.name, comment); + + props = { name: 'Sally' }; + assert.debug('create', User.name, props); + _context9.next = 31; + return adapter.create(User, props); + + case 31: + user2 = _context9.sent; + + assert.debug('created', User.name, user2); + + props = { content: 'bar', userId: user2[User.idAttribute] }; + assert.debug('create', Post.name, props); + _context9.next = 37; + return adapter.create(Post, props); + + case 37: + post2 = _context9.sent; + + assert.debug('created', Post.name, post2); + + props = { content: 'test67', postId: post2[Post.idAttribute], userId: post2.userId }; + assert.debug('create', Comment.name, props); + _context9.next = 43; + return adapter.create(Comment, props); + + case 43: + comment2 = _context9.sent; + + assert.debug('created', Comment.name, comment2); + + assert.debug('find', Post.name, {}); + _context9.next = 48; + return adapter.findAll(Post, {}, { 'with': ['user', 'comment', 'comment.user', 'comment.user.profile'] }); + + case 48: + posts = _context9.sent; + + assert.debug('found', Post.name, posts); + + assert.isDefined(posts[0].comments, 'posts[0].comments'); + assert.isDefined(posts[0].comments[0].user, 'posts[0].comments[0].user'); + assert.isDefined(posts[0].comments[0].user.profile || posts[1].comments[0].user.profile, 'posts[0].comments[0].user.profile || posts[1].comments[0].user.profile'); + assert.isDefined(posts[0].user, 'posts[0].user'); + assert.isDefined(posts[1].comments, 'posts[1].comments'); + assert.isDefined(posts[1].comments[0].user, 'posts[1].comments[0].user'); + assert.isDefined(posts[1].user, 'posts[1].user'); + + case 57: + case 'end': + return _context9.stop(); + } + } + }, _callee9, this); + }))); + } + + if (options.hasFeature('filterOnRelations')) { + it('should filter using belongsTo relation', asyncToGenerator(regeneratorRuntime.mark(function _callee10() { + var profile1, user1, post1, user2, post2, users; + return regeneratorRuntime.wrap(function _callee10$(_context10) { + while (1) { + switch (_context10.prev = _context10.next) { + case 0: + this.toClear.push('Post'); + this.toClear.push('Profile'); + this.toClear.push('Comment'); + _context10.next = 5; + return adapter.create(Profile, { email: 'foo@test.com' }); + + case 5: + profile1 = _context10.sent; + _context10.next = 8; + return adapter.create(User, { name: 'John', profileId: profile1.id }); + + case 8: + user1 = _context10.sent; + _context10.next = 11; + return adapter.create(Post, { content: 'foo', userId: user1.id }); + + case 11: + post1 = _context10.sent; + _context10.next = 14; + return adapter.create(Comment, { content: 'test1', postId: post1.id, userId: post1.userId }); + + case 14: + _context10.next = 16; + return adapter.create(User, { name: 'Sally' }); + + case 16: + user2 = _context10.sent; + _context10.next = 19; + return adapter.create(Post, { content: 'bar', userId: user2.id }); + + case 19: + post2 = _context10.sent; + _context10.next = 22; + return adapter.create(Comment, { content: 'test2', postId: post2.id, userId: post2.userId }); + + case 22: + _context10.next = 24; + return adapter.findAll(User, { 'profile.email': 'foo@test.com' }); + + case 24: + users = _context10.sent; + + assert.equal(users.length, 1); + assert.equal(users[0].profileId, profile1.id); + assert.equal(users[0].name, 'John'); + + case 28: + case 'end': + return _context10.stop(); + } + } + }, _callee10, this); + }))); + + it('should filter through multiple hasOne/belongsTo relations', asyncToGenerator(regeneratorRuntime.mark(function _callee11() { + var profile1, user1, post1, profile2, user2, post2, comments; + return regeneratorRuntime.wrap(function _callee11$(_context11) { + while (1) { + switch (_context11.prev = _context11.next) { + case 0: + this.toClear.push('Post'); + this.toClear.push('Profile'); + this.toClear.push('Comment'); + _context11.next = 5; + return adapter.create(Profile, { email: 'foo@test.com' }); + + case 5: + profile1 = _context11.sent; + _context11.next = 8; + return adapter.create(User, { name: 'John', profileId: profile1.id }); + + case 8: + user1 = _context11.sent; + _context11.next = 11; + return adapter.create(Post, { content: 'foo', userId: user1.id }); + + case 11: + post1 = _context11.sent; + _context11.next = 14; + return adapter.create(Comment, { content: 'test1', postId: post1.id, userId: post1.userId }); + + case 14: + _context11.next = 16; + return adapter.create(Profile, { email: 'bar@test.com' }); + + case 16: + profile2 = _context11.sent; + _context11.next = 19; + return adapter.create(User, { name: 'Sally', profileId: profile2.id }); + + case 19: + user2 = _context11.sent; + _context11.next = 22; + return adapter.create(Post, { content: 'bar', userId: user2.id }); + + case 22: + post2 = _context11.sent; + _context11.next = 25; + return adapter.create(Comment, { content: 'test2', postId: post2.id, userId: post2.userId }); + + case 25: + _context11.next = 27; + return adapter.findAll(Comment, { 'user.profile.email': 'foo@test.com' }); + + case 27: + comments = _context11.sent; + + assert.equal(comments.length, 1); + assert.equal(comments[0].userId, user1.id); + assert.equal(comments[0].content, 'test1'); + + case 31: + case 'end': + return _context11.stop(); + } + } + }, _callee11, this); + }))); + + it('should filter using multiple hasOne/belongsTo relations', asyncToGenerator(regeneratorRuntime.mark(function _callee12() { + var profile1, user1, post1, profile2, user2, post2, comments; + return regeneratorRuntime.wrap(function _callee12$(_context12) { + while (1) { + switch (_context12.prev = _context12.next) { + case 0: + this.toClear.push('Post'); + this.toClear.push('Profile'); + this.toClear.push('Comment'); + _context12.next = 5; + return adapter.create(Profile, { email: 'foo@test.com' }); + + case 5: + profile1 = _context12.sent; + _context12.next = 8; + return adapter.create(User, { name: 'John', profileId: profile1.id }); + + case 8: + user1 = _context12.sent; + _context12.next = 11; + return adapter.create(Post, { content: 'foo', userId: user1.id }); + + case 11: + post1 = _context12.sent; + _context12.next = 14; + return adapter.create(Comment, { content: 'test1', postId: post1.id, userId: post1.userId }); + + case 14: + _context12.next = 16; + return adapter.create(Profile, { email: 'bar@test.com' }); + + case 16: + profile2 = _context12.sent; + _context12.next = 19; + return adapter.create(User, { name: 'Sally', profileId: profile2.id }); + + case 19: + user2 = _context12.sent; + _context12.next = 22; + return adapter.create(Post, { content: 'bar', userId: user2.id }); + + case 22: + post2 = _context12.sent; + _context12.next = 25; + return adapter.create(Comment, { content: 'test2', postId: post2.id, userId: post2.userId }); + + case 25: + _context12.next = 27; + return adapter.findAll(Comment, { 'user.name': 'John', 'user.profile.email': 'foo@test.com' }); + + case 27: + comments = _context12.sent; + + assert.equal(comments.length, 1); + assert.equal(comments[0].userId, user1.id); + assert.equal(comments[0].content, 'test1'); + + case 31: + case 'end': + return _context12.stop(); + } + } + }, _callee12, this); + }))); + } + + it('should allow passing limit and offset as strings', asyncToGenerator(regeneratorRuntime.mark(function _callee13() { + return regeneratorRuntime.wrap(function _callee13$(_context13) { + while (1) { + switch (_context13.prev = _context13.next) { + case 0: + _context13.next = 2; + return adapter.findAll(User, { limit: '10', offset: '20' }); + + case 2: + case 'end': + return _context13.stop(); + } + } + }, _callee13, this); + }))); + + if (options.hasFeature('findAllGroupedWhere')) { + it('should support filtering grouped "where" clauses', asyncToGenerator(regeneratorRuntime.mark(function _callee14() { + var posts, query; + return regeneratorRuntime.wrap(function _callee14$(_context14) { + while (1) { + switch (_context14.prev = _context14.next) { + case 0: + this.toClear.push('Post'); + _context14.next = 3; + return adapter.createMany(Post, [{ status: 'draft', content: 'foo' }, { status: 'broken', content: 'bar' }, { status: 'published', content: 'hi' }, { status: 'flagged', content: 'hello world' }, { status: 'flagged', content: 'test' }]); + + case 3: + posts = _context14.sent; + query = { + where: [[{ + content: { + '=': 'foo' + }, + status: { + '=': 'draft' + } + }, 'or', { + status: { + '=': 'published' + } + }], 'or', { + content: { + '=': 'test' + }, + status: { + '=': 'flagged' + } + }], + orderBy: 'status' + }; + _context14.t0 = assert; + _context14.next = 8; + return adapter.findAll(Post, query); + + case 8: + _context14.t1 = _context14.sent; + _context14.t2 = [posts[0], posts[4], posts[2]]; + + _context14.t0.objectsEqual.call(_context14.t0, _context14.t1, _context14.t2); + + case 11: + case 'end': + return _context14.stop(); + } + } + }, _callee14, this); + }))); + } + }); +}; + +/* global assert:true */ +var sumTest = function (options) { + describe('Adapter#sum', function () { + it('should exist', function () { + assert.equal(_typeof(this.$$adapter.sum), 'function', 'adapter should have a "sum" method'); + }); + it('should sum users\' age', asyncToGenerator(regeneratorRuntime.mark(function _callee() { + var adapter, User, props, sum, user, user2; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John', age: 30 }; + + + assert.debug('sum', User.name, {}); + _context.next = 6; + return adapter.sum(User, 'age'); + + case 6: + sum = _context.sent; + + assert.debug('summed', User.name, sum); + assert.equal(sum, 0); + + assert.debug('sum', User.name, { name: 'John' }); + _context.next = 12; + return adapter.sum(User, 'age', { name: 'John' }); + + case 12: + sum = _context.sent; + + assert.debug('summed', User.name, sum); + assert.equal(sum, 0); + + assert.debug('sum', User.name, { name: 'Sally' }); + _context.next = 18; + return adapter.sum(User, 'age', { name: 'Sally' }); + + case 18: + sum = _context.sent; + + assert.debug('summed', User.name, sum); + assert.equal(sum, 0); + + assert.debug('create', User.name, props); + _context.next = 24; + return adapter.create(User, props); + + case 24: + user = _context.sent; + + assert.debug('created', User.name, user); + + assert.debug('sum', User.name, {}); + _context.next = 29; + return adapter.sum(User, 'age'); + + case 29: + sum = _context.sent; + + assert.debug('summed', User.name, sum); + assert.equal(sum, 30); + + assert.debug('sum', User.name, { name: 'John' }); + _context.next = 35; + return adapter.sum(User, 'age', { name: 'John' }); + + case 35: + sum = _context.sent; + + assert.debug('summed', User.name, sum); + assert.equal(sum, 30); + + assert.debug('sum', User.name, { name: 'Sally' }); + _context.next = 41; + return adapter.sum(User, 'age', { name: 'Sally' }); + + case 41: + sum = _context.sent; + + assert.debug('summed', User.name, sum); + assert.equal(sum, 0); + + assert.debug('create', User.name, { name: 'Sally' }); + _context.next = 47; + return adapter.create(User, { name: 'Sally', age: 27 }); + + case 47: + user2 = _context.sent; + + assert.debug('created', User.name, user2); + + assert.debug('sum', User.name, {}); + _context.next = 52; + return adapter.sum(User, 'age'); + + case 52: + sum = _context.sent; + + assert.debug('summed', User.name, sum); + assert.equal(sum, 57); + + assert.debug('sum', User.name, { name: 'John' }); + _context.next = 58; + return adapter.sum(User, 'age', { name: 'John' }); + + case 58: + sum = _context.sent; + + assert.debug('summed', User.name, sum); + assert.equal(sum, 30); + + assert.debug('sum', User.name, { name: 'Sally' }); + _context.next = 64; + return adapter.sum(User, 'age', { name: 'Sally' }); + + case 64: + sum = _context.sent; + + assert.debug('summed', User.name, sum); + assert.equal(sum, 27); + + case 67: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + }))); + it('should sum users\' age and return raw', asyncToGenerator(regeneratorRuntime.mark(function _callee2() { + var adapter, User, props, user, result; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John', age: 30 }; + + + assert.debug('create', User.name, props); + _context2.next = 6; + return adapter.create(User, props); + + case 6: + user = _context2.sent; + + assert.debug('created', User.name, user); + + assert.debug('sum', User.name, props); + _context2.next = 11; + return adapter.sum(User, 'age', props, { raw: true }); + + case 11: + result = _context2.sent; + + assert.debug('summed', User.name, result); + assert.equal(result.data, 30, 'result.data'); + + case 14: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + }))); + }); +}; + +/* global assert:true */ +var updateTest = function (options) { + describe('Adapter#update', function () { + it('should exist', function () { + assert.equal(_typeof(this.$$adapter.update), 'function', 'adapter should have a "update" method'); + }); + it('should update a user', asyncToGenerator(regeneratorRuntime.mark(function _callee() { + var adapter, User, props, user, foundUser, updatedUser; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + assert.debug('create', User.name, props); + _context.next = 6; + return adapter.create(User, props); + + case 6: + user = _context.sent; + + assert.debug('created', User.name, user); + + assert.equal(user.name, props.name, 'name of user should be "' + props.name + '"'); + assert.isDefined(user[User.idAttribute], 'new user should have an id'); + + assert.debug('find', User.name, user[User.idAttribute]); + _context.next = 13; + return adapter.find(User, user[User.idAttribute]); + + case 13: + foundUser = _context.sent; + + assert.debug('found', User.name, foundUser); + + assert.equal(foundUser.name, props.name, 'name of user should be "' + props.name + '"'); + assert.isDefined(foundUser[User.idAttribute], 'new user should have an id'); + assert.equal(foundUser[User.idAttribute], user[User.idAttribute]); + + assert.debug('update', User.name, user[User.idAttribute], { name: 'Johnny' }); + _context.next = 21; + return adapter.update(User, user[User.idAttribute], { name: 'Johnny' }); + + case 21: + updatedUser = _context.sent; + + assert.debug('updated', User.name, updatedUser); + assert.equal(updatedUser.name, 'Johnny'); + assert.equal(updatedUser[User.idAttribute], user[User.idAttribute]); + + assert.debug('find', User.name, user[User.idAttribute]); + _context.next = 28; + return adapter.find(User, user[User.idAttribute]); + + case 28: + foundUser = _context.sent; + + assert.debug('found', User.name, foundUser); + assert.equal(foundUser.name, 'Johnny'); + assert.equal(foundUser[User.idAttribute], user[User.idAttribute]); + + case 32: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + }))); + it('should update a user and return raw', asyncToGenerator(regeneratorRuntime.mark(function _callee2() { + var adapter, User, props, user, result; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John' }; + + + assert.debug('create', User.name, props); + _context2.next = 6; + return adapter.create(User, props); + + case 6: + user = _context2.sent; + + assert.debug('created', User.name, user); + + assert.equal(user.name, props.name, 'name of user should be "' + props.name + '"'); + assert.isDefined(user[User.idAttribute], 'new user should have an id'); + + assert.debug('update', User.name, user[User.idAttribute], { name: 'Johnny' }); + _context2.next = 13; + return adapter.update(User, user[User.idAttribute], { name: 'Johnny' }, { raw: true }); + + case 13: + result = _context2.sent; + + assert.debug('updated', User.name, result); + assert.isDefined(result.data, 'result.data is defined'); + assert.isDefined(result.updated, 'result.updated is defined'); + assert.equal(result.data.name, 'Johnny', 'result.data.name should be "Johnny"'); + assert.equal(result.data[User.idAttribute], user[User.idAttribute], 'result.data.' + User.idAttribute + ' should be ' + user[User.idAttribute]); + assert.equal(result.updated, 1, 'result.updated should be 1'); + + case 20: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + }))); + it('should throw when updating non-existent row', asyncToGenerator(regeneratorRuntime.mark(function _callee3() { + var adapter, User; + return regeneratorRuntime.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + + + assert.debug('update', 'non-existent-id', { name: 'Johnny' }); + _context3.prev = 3; + _context3.next = 6; + return adapter.update(User, 'non-existent-id', { name: 'Johnny' }); + + case 6: + throw new Error('update should have failed!'); + + case 9: + _context3.prev = 9; + _context3.t0 = _context3['catch'](3); + + assert.debug('correctly threw error', _context3.t0.message); + assert.isDefined(_context3.t0.message, 'err.message is defined'); + assert.equal(_context3.t0.message, 'Not Found', 'err.message should be "Not Found"'); + + case 14: + case 'end': + return _context3.stop(); + } + } + }, _callee3, this, [[3, 9]]); + }))); + it('should keep relations specified by "with"', asyncToGenerator(regeneratorRuntime.mark(function _callee4() { + var adapter, store, result; + return regeneratorRuntime.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + adapter = this.$$adapter; + store = this.$$container; + + + sinon.stub(adapter, '_update').callsFake(function (mapper, id, props, opts) { + assert.deepEqual(props.posts, [{ + id: 1234, + userId: 1 + }]); + assert.deepEqual(props.profile, { + id: 238, + userId: 1 + }); + assert.equal(props.address, undefined); + assert.equal(props.organization, undefined); + return [props, {}]; + }); + + assert.debug('update', 1, { id: 1 }); + _context4.next = 6; + return store.update('user', 1, { + id: 1, + posts: [{ + id: 1234, + userId: 1 + }], + address: { + id: 412, + userId: 1 + }, + profile: { + id: 238, + userId: 1 + }, + organizationId: 333, + organization: { + id: 333 + } + }, { with: ['posts', 'profile'] }); + + case 6: + result = _context4.sent; + + assert.debug('updated', 1, result); + adapter._update.restore(); + + case 9: + case 'end': + return _context4.stop(); + } + } + }, _callee4, this); + }))); + }); +}; + +/* global assert:true */ +var updateAllTest = function (options) { + describe('Adapter#updateAll', function () { + it('should exist', function () { + assert.equal(_typeof(this.$$adapter.updateAll), 'function', 'adapter should have a "updateAll" method'); + }); + it('should update multiple users', asyncToGenerator(regeneratorRuntime.mark(function _callee() { + var adapter, User, props, user1, userId1, user2, userId2, users, users2, users3, users4; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + props = { name: 'John', age: 20 }; + + + assert.debug('create', User.name, props); + _context.next = 6; + return adapter.create(User, props); + + case 6: + user1 = _context.sent; + + assert.debug('created', User.name, user1); + userId1 = user1[User.idAttribute]; + + + props = { name: 'John', age: 30 }; + + assert.debug('create', User.name, props); + _context.next = 13; + return adapter.create(User, props); + + case 13: + user2 = _context.sent; + + assert.debug('created', User.name, user2); + userId2 = user2[User.idAttribute]; + + + assert.debug('findAll', User.name, { name: 'John' }); + _context.next = 19; + return adapter.findAll(User, { name: 'John' }); + + case 19: + users = _context.sent; + + assert.debug('found', User.name, users); + users.sort(function (a, b) { + return a.age - b.age; + }); + assert.equal(users[0].name, 'John'); + assert.equal(users[0].name, 'John'); + assert.equal(users.filter(function (x) { + return x[User.idAttribute] === userId1; + }).length, 1); + assert.equal(users.filter(function (x) { + return x[User.idAttribute] === userId2; + }).length, 1); + assert.equal(users.filter(function (x) { + return x.age === 20; + }).length, 1); + assert.equal(users.filter(function (x) { + return x.age === 30; + }).length, 1); + + assert.debug('updateAll', User.name, { name: 'Johnny' }, { name: 'John' }); + _context.next = 31; + return adapter.updateAll(User, { name: 'Johnny' }, { name: 'John' }); + + case 31: + users2 = _context.sent; + + assert.debug('updated', User.name, users2); + users2.sort(function (a, b) { + return a.age - b.age; + }); + assert.equal(users2[0].name, 'Johnny'); + assert.equal(users2[0].name, 'Johnny'); + assert.equal(users2.filter(function (x) { + return x[User.idAttribute] === userId1; + }).length, 1); + assert.equal(users2.filter(function (x) { + return x[User.idAttribute] === userId2; + }).length, 1); + assert.equal(users2.filter(function (x) { + return x.age === 20; + }).length, 1); + assert.equal(users2.filter(function (x) { + return x.age === 30; + }).length, 1); + + assert.debug('findAll', User.name, { name: 'John' }); + _context.next = 43; + return adapter.findAll(User, { name: 'John' }); + + case 43: + users3 = _context.sent; + + assert.debug('found', User.name, users3); + assert.equalObjects(users3, []); + assert.equal(users3.length, 0); + + assert.debug('findAll', User.name, { name: 'Johnny' }); + _context.next = 50; + return adapter.findAll(User, { name: 'Johnny' }); + + case 50: + users4 = _context.sent; + + assert.debug('found', User.name, users4); + + users4.sort(function (a, b) { + return a.age - b.age; + }); + assert.equal(users4[0].name, 'Johnny'); + assert.equal(users4[0].name, 'Johnny'); + assert.equal(users4.filter(function (x) { + return x[User.idAttribute] === userId1; + }).length, 1); + assert.equal(users4.filter(function (x) { + return x[User.idAttribute] === userId2; + }).length, 1); + assert.equal(users4.filter(function (x) { + return x.age === 20; + }).length, 1); + assert.equal(users4.filter(function (x) { + return x.age === 30; + }).length, 1); + + case 59: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + }))); + }); +}; + +/* global assert:true */ +var updateManyTest = function (options) { + describe('Adapter#updateMany', function () { + it('should exist', function () { + assert.equal(_typeof(this.$$adapter.updateMany), 'function', 'adapter should have a "updateMany" method'); + }); + it('should update multiple users', asyncToGenerator(regeneratorRuntime.mark(function _callee() { + var adapter, User, user1, userId1, user2, userId2, users, users2, users3, users4; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + adapter = this.$$adapter; + User = this.$$User; + _context.next = 4; + return adapter.create(User, { name: 'John', age: 20 }); + + case 4: + user1 = _context.sent; + userId1 = user1.id; + _context.next = 8; + return adapter.create(User, { name: 'John', age: 30 }); + + case 8: + user2 = _context.sent; + userId2 = user2.id; + _context.next = 12; + return adapter.findAll(User, { name: 'John' }); + + case 12: + users = _context.sent; + + users.sort(function (a, b) { + return a.age - b.age; + }); + assert.equal(users[0].name, 'John'); + assert.equal(users[0].name, 'John'); + assert.equal(users.filter(function (x) { + return x.id === userId1; + }).length, 1); + assert.equal(users.filter(function (x) { + return x.id === userId2; + }).length, 1); + assert.equal(users.filter(function (x) { + return x.age === 20; + }).length, 1); + assert.equal(users.filter(function (x) { + return x.age === 30; + }).length, 1); + + user1.age = 101; + user2.age = 202; + _context.next = 24; + return adapter.updateMany(User, [user1, user2]); + + case 24: + users2 = _context.sent; + + users2.sort(function (a, b) { + return a.age - b.age; + }); + assert.equal(users2.filter(function (x) { + return x.id === userId1; + }).length, 1); + assert.equal(users2.filter(function (x) { + return x.id === userId2; + }).length, 1); + assert.equal(users2.filter(function (x) { + return x.age === 101; + }).length, 1); + assert.equal(users2.filter(function (x) { + return x.age === 202; + }).length, 1); + + _context.next = 32; + return adapter.findAll(User, { age: 20 }); + + case 32: + users3 = _context.sent; + + assert.objectsEqual(users3, []); + assert.equal(users3.length, 0); + + _context.next = 37; + return adapter.findAll(User, { age: 101 }); + + case 37: + users4 = _context.sent; + + users4.sort(function (a, b) { + return a.age - b.age; + }); + assert.equal(users4.filter(function (x) { + return x.id === userId1; + }).length, 1); + assert.equal(users4.filter(function (x) { + return x.id === userId2; + }).length, 0); + assert.equal(users4.filter(function (x) { + return x.age === 101; + }).length, 1); + assert.equal(users4.filter(function (x) { + return x.age === 202; + }).length, 0); + + case 43: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + }))); + }); +}; + +chai.assert.equalObjects = function (a, b, m) { + chai.assert.deepEqual(JSON.parse(JSON.stringify(a)), JSON.parse(JSON.stringify(b)), m || JSON.stringify(a) + ' should be equal to ' + JSON.stringify(b)); +}; + +chai.assert.objectsEqual = function (a, b, m) { + chai.assert.deepEqual(JSON.parse(JSON.stringify(a)), JSON.parse(JSON.stringify(b)), m || JSON.stringify(a) + ' should be equal to ' + JSON.stringify(b)); +}; + +var debug = false; + +chai.assert.debug = function () { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + if (debug) { + var _console; + + args.forEach(function (arg, i) { + args[i] = JSON.stringify(arg, null, 2); + }); + (_console = console).log.apply(_console, ['DEBUG (TEST):'].concat(args)); + } +}; + +var prefix = 'TestRunner.init(options): options'; + +var index = { + init: function init(options) { + options = options || {}; + debug = !!options.debug; + options.hasMethod = function (method) { + options.methods || (options.methods = 'all'); + options.xmethods || (options.xmethods = []); + return (options.methods === 'all' || options.methods.indexOf(method) !== -1) && options.xmethods.indexOf(method) === -1; + }; + options.hasFeature = function (feature) { + options.features || (options.features = 'all'); + options.xfeatures || (options.xfeatures = []); + return (options.features === 'all' || options.features.indexOf(feature) !== -1) && options.xfeatures.indexOf(feature) === -1; + }; + if (!options.Adapter || typeof options.Adapter !== 'function') { + throw new Error(prefix + '.Adapter: Expected function, Actual: ' + _typeof(options.Adapter)); + } + beforeEach(function () { + this.$$adapter = new options.Adapter(options.adapterConfig); + this.$$container = new options.JSData.Container(options.containerConfig || { + mapperDefaults: { + debug: false + } + }); + this.$$store = new options.JSData.DataStore(options.storeConfig || { + mapperDefaults: { + debug: false + } + }); + this.$$container.registerAdapter('adapter', this.$$adapter, { 'default': true }); + this.$$store.registerAdapter('adapter', this.$$adapter, { 'default': true }); + var userOptions = { + name: 'user', + relations: { + hasMany: { + post: { + localField: 'posts', + foreignKey: 'userId' + } + }, + hasOne: { + profile: { + localField: 'profile', + foreignKey: 'userId' + }, + address: { + localField: 'address', + foreignKey: 'userId' + } + }, + belongsTo: { + organization: { + localField: 'organization', + foreignKey: 'organizationId' + } + } + } + }; + var organizationOptions = { + name: 'organization', + relations: { + hasMany: { + user: { + localField: 'users', + foreignKey: 'organizationId' + } + } + } + }; + var postOptions = { + name: 'post', + relations: { + belongsTo: { + user: { + localField: 'user', + foreignKey: 'userId' + } + }, + hasMany: { + comment: { + localField: 'comments', + foreignKey: 'postId' + }, + tag: { + localField: 'tags', + localKeys: 'tagIds' + } + } + } + }; + var commentOptions = { + name: 'comment', + relations: { + belongsTo: { + post: { + localField: 'post', + foreignKey: 'postId' + }, + user: { + localField: 'user', + foreignKey: 'userId' + } + } + } + }; + var tagOptions = { + name: 'tag', + relations: { + hasMany: { + post: { + localField: 'posts', + foreignKeys: 'tagIds' + } + } + } + }; + this.$$User = this.$$container.defineMapper('user', options.userConfig || options.JSData.utils.copy(userOptions)); + this.$$store.defineMapper('user', options.userConfig || options.JSData.utils.copy(userOptions)); + this.$$Organization = this.$$container.defineMapper('organization', options.organizationConfig || options.JSData.utils.copy(organizationOptions)); + this.$$store.defineMapper('organization', options.organizationConfig || options.JSData.utils.copy(organizationOptions)); + this.$$Profile = this.$$container.defineMapper('profile', options.profileConfig || {}); + this.$$store.defineMapper('profile', options.profileConfig || {}); + this.$$Address = this.$$container.defineMapper('address', options.addressConfig || {}); + this.$$store.defineMapper('address', options.addressConfig || {}); + this.$$Post = this.$$container.defineMapper('post', options.postConfig || options.JSData.utils.copy(postOptions)); + this.$$store.defineMapper('post', options.postConfig || options.JSData.utils.copy(postOptions)); + this.$$Comment = this.$$container.defineMapper('comment', options.commentConfig || options.JSData.utils.copy(commentOptions)); + this.$$store.defineMapper('comment', options.commentConfig || options.JSData.utils.copy(commentOptions)); + this.$$Tag = this.$$container.defineMapper('tag', options.tagConfig || options.JSData.utils.copy(tagOptions)); + this.$$store.defineMapper('tag', options.tagConfig || options.JSData.utils.copy(tagOptions)); + this.toClear = ['User']; + }); + + describe('js-data-adapter-tests', function () { + if (options.hasMethod('beforeCreate')) { + beforeCreateTest(options); + } + if (options.hasMethod('count')) { + countTest(options); + } + if (options.hasMethod('create')) { + createTest(options); + } + if (options.hasMethod('afterCreate')) { + afterCreateTest(options); + } + if (options.hasMethod('createMany')) { + createManyTest(options); + } + if (options.hasMethod('extend')) { + extendTest(options); + } + if (options.hasMethod('find')) { + findTest(options); + } + if (options.hasMethod('findAll')) { + findAllTest(options); + } + if (options.hasMethod('destroy')) { + destroyTest(options); + } + if (options.hasMethod('destroyAll')) { + destroyAllTest(options); + } + if (options.hasMethod('beforeUpdate')) { + beforeUpdateTest(options); + } + if (options.hasMethod('sum')) { + sumTest(options); + } + if (options.hasMethod('update')) { + updateTest(options); + } + if (options.hasMethod('afterUpdate')) { + afterUpdateTest(options); + } + if (options.hasMethod('updateAll')) { + updateAllTest(options); + } + if (options.hasMethod('updateMany')) { + updateManyTest(options); + } + }); + + afterEach(asyncToGenerator(regeneratorRuntime.mark(function _callee() { + var Test, toClear, promise; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + Test = this; + toClear = []; + + if (Test.toClear.indexOf('Tag') !== -1) { + toClear.push('Tag'); + } + if (Test.toClear.indexOf('Comment') !== -1) { + toClear.push('Comment'); + } + if (Test.toClear.indexOf('Post') !== -1) { + toClear.push('Post'); + } + if (Test.toClear.indexOf('Profile') !== -1) { + toClear.push('Profile'); + } + if (Test.toClear.indexOf('User') !== -1) { + toClear.push('User'); + } + if (Test.toClear.indexOf('Address') !== -1) { + toClear.push('Address'); + } + promise = Promise.resolve(); + + toClear.forEach(function (Mapper) { + promise = promise.then(function () { + return Test.$$adapter.destroyAll(Test['$$' + Mapper]); + }); + }); + _context.next = 12; + return promise; + + case 12: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + }))); + }, + assert: chai.assert, + sinon: sinon$1, + fail: function fail(msg) { + chai.assert.equal('should not reach this!: ' + msg, 'failure'); + }, + TYPES_EXCEPT_STRING: [123, 123.123, null, undefined, {}, [], true, false, function () {}], + TYPES_EXCEPT_STRING_OR_ARRAY: [123, 123.123, null, undefined, {}, true, false, function () {}], + TYPES_EXCEPT_STRING_OR_NUMBER: [null, undefined, {}, [], true, false, function () {}], + TYPES_EXCEPT_STRING_OR_OBJECT: [123, 123.123, null, undefined, [], true, false, function () {}], + TYPES_EXCEPT_STRING_OR_NUMBER_OBJECT: [null, undefined, [], true, false, function () {}], + TYPES_EXCEPT_STRING_OR_ARRAY_OR_NUMBER: [null, undefined, {}, true, false, function () {}], + TYPES_EXCEPT_NUMBER: ['string', null, undefined, {}, [], true, false, function () {}], + TYPES_EXCEPT_OBJECT: ['string', 123, 123.123, null, undefined, true, false, function () {}], + TYPES_EXCEPT_BOOLEAN: ['string', 123, 123.123, null, undefined, {}, [], function () {}], + TYPES_EXCEPT_FUNCTION: ['string', 123, 123.123, null, undefined, {}, [], true, false] +}; + +return index; + +}))); +//# sourceMappingURL=js-data-adapter-tests.js.map diff --git a/dist/js-data-adapter-tests.js.map b/dist/js-data-adapter-tests.js.map new file mode 100644 index 0000000..1c76257 --- /dev/null +++ b/dist/js-data-adapter-tests.js.map @@ -0,0 +1 @@ +{"version":3,"file":"js-data-adapter-tests.js","sources":["../test/afterCreate.test.js","../test/afterUpdate.test.js","../test/beforeCreate.test.js","../test/beforeUpdate.test.js","../test/count.test.js","../test/create.test.js","../test/createMany.test.js","../test/destroy.test.js","../test/destroyAll.test.js","../test/extend.test.js","../test/find.test.js","../test/findAll.test.js","../test/sum.test.js","../test/update.test.js","../test/updateAll.test.js","../test/updateMany.test.js","../test/index.js"],"sourcesContent":["/* global assert:true */\nexport default function (options) {\n describe('Adapter#afterCreate', function () {\n it('should exist', function () {\n assert.equal(typeof this.$$adapter.afterCreate, 'function', 'adapter should have a \"afterCreate\" method')\n })\n it('should call afterCreate', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n sinon.stub(adapter, 'afterCreate').callsFake(function (mapper, props, opts) {\n assert.isDefined(opts, 'afterCreate should have received options')\n assert.equal(opts.op, 'afterCreate', 'opts.op')\n })\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n assert.equal(user.name, props.name, `name of user should be \"${props.name}\"`)\n assert.isDefined(user[User.idAttribute], 'new user should have an id')\n\n assert.isTrue(adapter.afterCreate.calledOnce, 'afterCreate should have been called once')\n\n const args = adapter.afterCreate.firstCall.args\n assert.equal(args.length, 4, 'afterCreate should have received 4 arguments')\n assert.isTrue(args[0] === User, 'afterCreate should have received User mapper')\n assert.objectsEqual(args[1], { name: 'John' }, 'afterCreate should have received create props')\n assert.isObject(args[2], 'afterCreate should have received options')\n assert.isObject(args[3], 'afterCreate should have received record')\n adapter.afterCreate.restore()\n })\n it('should allow re-assignment', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n sinon.stub(adapter, 'afterCreate').callsFake(function (mapper, props, opts) {\n assert.isDefined(opts, 'afterCreate should have received options')\n assert.equal(opts.op, 'afterCreate', 'opts.op')\n return 'foo'\n })\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n assert.equal(user, 'foo', 'result should be \"foo\"')\n\n assert.isTrue(adapter.afterCreate.calledOnce, 'afterCreate should have been called once')\n\n const args = adapter.afterCreate.firstCall.args\n assert.equal(args.length, 4, 'afterCreate should have received 4 arguments')\n assert.isTrue(args[0] === User, 'afterCreate should have received User mapper')\n assert.objectsEqual(args[1], { name: 'John' }, 'afterCreate should have received create props')\n assert.isObject(args[2], 'afterCreate should have received options')\n assert.isObject(args[3], 'afterCreate should have received record')\n adapter.afterCreate.restore()\n })\n it('should allow returning a promise', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n sinon.stub(adapter, 'afterCreate').callsFake(function (mapper, props, opts, record) {\n assert.isDefined(opts, 'afterCreate should have received options')\n assert.equal(opts.op, 'afterCreate', 'opts.op')\n return Promise.resolve()\n })\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n assert.equal(user.name, props.name, `name of user should be \"${props.name}\"`)\n assert.isDefined(user[User.idAttribute], 'new user should have an id')\n\n assert.isTrue(adapter.afterCreate.calledOnce, 'afterCreate should have been called once')\n\n const args = adapter.afterCreate.firstCall.args\n assert.equal(args.length, 4, 'afterCreate should have received 4 arguments')\n assert.isTrue(args[0] === User, 'afterCreate should have received User mapper')\n assert.objectsEqual(args[1], { name: 'John' }, 'afterCreate should have received create props')\n assert.isDefined(args[2], 'afterCreate should have received options')\n assert.isObject(args[3], 'afterCreate should have received record')\n adapter.afterCreate.restore()\n })\n it('should allow returning a promise and re-assignment', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n sinon.stub(adapter, 'afterCreate').callsFake(function (mapper, props, opts) {\n assert.isDefined(opts, 'afterCreate should have received options')\n assert.equal(opts.op, 'afterCreate', 'opts.op')\n return 'foo'\n })\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n assert.equal(user, 'foo', 'result should be \"foo\"')\n\n assert.isTrue(adapter.afterCreate.calledOnce, 'afterCreate should have been called once')\n\n const args = adapter.afterCreate.firstCall.args\n assert.equal(args.length, 4, 'afterCreate should have received 4 arguments')\n assert.isTrue(args[0] === User, 'afterCreate should have received User mapper')\n assert.objectsEqual(args[1], { name: 'John' }, 'afterCreate should have received create props')\n assert.isObject(args[2], 'afterCreate should have received options')\n assert.isObject(args[3], 'afterCreate should have received record')\n adapter.afterCreate.restore()\n })\n it('should receive raw', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n sinon.stub(adapter, 'afterCreate').callsFake(function (mapper, props, opts) {\n assert.isDefined(opts, 'afterCreate should have received options')\n assert.equal(opts.op, 'afterCreate', 'opts.op')\n })\n\n assert.debug('create', User.name, props)\n const result = await adapter.create(User, props, { raw: true })\n assert.debug('created', User.name, result)\n\n assert.equal(result.created, 1, 'result.created')\n assert.equal(result.data.name, props.name, 'result.data.name')\n assert.isDefined(result.data[User.idAttribute], `result.data[${User.idAttribute}]`)\n\n assert.isTrue(adapter.afterCreate.calledOnce, 'afterCreate should have been called once')\n\n const args = adapter.afterCreate.firstCall.args\n assert.equal(args.length, 4, 'afterCreate should have received 4 arguments')\n assert.isTrue(args[0] === User, 'afterCreate should have received User mapper')\n assert.objectsEqual(args[1], { name: 'John' }, 'afterCreate should have received create props')\n assert.isObject(args[2], 'afterCreate should have received options')\n assert.isObject(args[3], 'afterCreate should have received result')\n assert.equal(args[3].created, 1, 'result.created')\n assert.isObject(args[3].data, 'result.data')\n adapter.afterCreate.restore()\n })\n })\n}\n","/* global assert:true */\nexport default function (options) {\n describe('Adapter#afterUpdate', function () {\n it('should exist', function () {\n assert.equal(typeof this.$$adapter.afterUpdate, 'function', 'adapter should have a \"afterUpdate\" method')\n })\n it('should call afterUpdate', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n sinon.stub(adapter, 'afterUpdate').callsFake(function (mapper, id, props, opts) {\n assert.isDefined(opts, 'afterUpdate should have received options')\n assert.equal(opts.op, 'afterUpdate', 'opts.op')\n })\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n const userId = user[User.idAttribute]\n assert.debug('created', User.name, user)\n\n assert.equal(user.name, props.name, `name of user should be \"${props.name}\"`)\n assert.isDefined(user[User.idAttribute], 'new user should have an id')\n\n assert.debug('update', User.name, userId, { name: 'Johnny' })\n let updatedUser = await adapter.update(User, userId, { name: 'Johnny' })\n assert.debug('updated', User.name, updatedUser)\n assert.equal(updatedUser.name, 'Johnny')\n assert.equal(updatedUser[User.idAttribute], userId)\n\n assert.isTrue(adapter.afterUpdate.calledOnce, 'afterUpdate should have been called once')\n\n const args = adapter.afterUpdate.firstCall.args\n assert.equal(args.length, 5, 'beforeUpdate should have received 5 arguments')\n assert.isTrue(args[0] === User, 'afterUpdate should have received User mapper')\n assert.isTrue(args[1] === userId, 'afterUpdate should have received user id')\n assert.objectsEqual(args[2], { name: 'Johnny' }, 'afterUpdate should have received update props')\n assert.isDefined(args[3], 'afterUpdate should have received options')\n assert.equal(args[3].op, 'afterUpdate', 'args[3].op')\n assert.isDefined(args[4], 'afterUpdate should have received updated record')\n assert.equal(args[4][User.idAttribute], userId, `args[4].${User.idAttribute}`)\n assert.equal(args[4].name, 'Johnny', 'args[4].name')\n adapter.afterUpdate.restore()\n })\n it('should receive raw', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n sinon.stub(adapter, 'afterUpdate').callsFake(function (mapper, id, props, opts) {\n assert.isDefined(opts, 'afterUpdate should have received options')\n assert.equal(opts.op, 'afterUpdate', 'opts.op')\n })\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n const userId = user[User.idAttribute]\n assert.debug('created', User.name, user)\n\n assert.equal(user.name, props.name, `name of user should be \"${props.name}\"`)\n assert.isDefined(user[User.idAttribute], 'new user should have an id')\n\n assert.debug('update', User.name, userId, { name: 'Johnny' })\n let result = await adapter.update(User, userId, { name: 'Johnny' }, { raw: true })\n assert.debug('updated', User.name, result)\n assert.isDefined(result.data, 'result.data')\n assert.equal(result.data.name, 'Johnny', result.data.name)\n assert.equal(result.data[User.idAttribute], userId, `result.data.${User.idAttribute}`)\n\n assert.isTrue(adapter.afterUpdate.calledOnce, 'afterUpdate should have been called once')\n\n const args = adapter.afterUpdate.firstCall.args\n assert.equal(args.length, 5, 'beforeUpdate should have received 5 arguments')\n assert.isTrue(args[0] === User, 'afterUpdate should have received User mapper')\n assert.isTrue(args[1] === userId, 'afterUpdate should have received user id')\n assert.objectsEqual(args[2], { name: 'Johnny' }, 'afterUpdate should have received update props')\n assert.isDefined(args[3], 'afterUpdate should have received options')\n assert.equal(args[3].op, 'afterUpdate', 'args[3].op')\n assert.isDefined(args[4], 'afterUpdate should have received update result')\n assert.equal(args[4].updated, 1, 'args[4].updated')\n assert.isDefined(args[4].data, 'args[4].data')\n assert.equal(args[4].data[User.idAttribute], userId, `args[4].data.${User.idAttribute}`)\n assert.equal(args[4].data.name, 'Johnny', 'args[4].data.name')\n adapter.afterUpdate.restore()\n })\n it('should allow re-assignment', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n sinon.stub(adapter, 'afterUpdate').callsFake(function (mapper, id, props, opts) {\n assert.isDefined(opts, 'afterUpdate should have received options')\n assert.equal(opts.op, 'afterUpdate', 'opts.op')\n return 'foo'\n })\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n const userId = user[User.idAttribute]\n assert.debug('created', User.name, user)\n\n assert.equal(user.name, props.name, `name of user should be \"${props.name}\"`)\n assert.isDefined(user[User.idAttribute], 'new user should have an id')\n\n assert.debug('update', User.name, userId, { name: 'Johnny' })\n let updatedUser = await adapter.update(User, userId, { name: 'Johnny' })\n assert.debug('updated', User.name, updatedUser)\n assert.equal(updatedUser, 'foo', 'should have received re-assigned value')\n\n assert.isTrue(adapter.afterUpdate.calledOnce, 'afterUpdate should have been called once')\n\n const args = adapter.afterUpdate.firstCall.args\n assert.equal(args.length, 5, 'beforeUpdate should have received 5 arguments')\n assert.isTrue(args[0] === User, 'afterUpdate should have received User mapper')\n assert.isTrue(args[1] === userId, 'afterUpdate should have received user id')\n assert.objectsEqual(args[2], { name: 'Johnny' }, 'afterUpdate should have received update props')\n assert.isDefined(args[3], 'afterUpdate should have received options')\n assert.equal(args[3].op, 'afterUpdate', 'args[3].op')\n assert.isDefined(args[4], 'afterUpdate should have received updated record')\n assert.equal(args[4][User.idAttribute], userId, `args[4].${User.idAttribute}`)\n assert.equal(args[4].name, 'Johnny', 'args[4].name')\n adapter.afterUpdate.restore()\n })\n it('should allow returning a promise', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n sinon.stub(adapter, 'afterUpdate').callsFake(function (mapper, id, props, opts) {\n assert.isDefined(opts, 'afterUpdate should have received options')\n assert.equal(opts.op, 'afterUpdate', 'opts.op')\n return Promise.resolve()\n })\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n const userId = user[User.idAttribute]\n assert.debug('created', User.name, user)\n\n assert.equal(user.name, props.name, `name of user should be \"${props.name}\"`)\n assert.isDefined(user[User.idAttribute], 'new user should have an id')\n\n assert.debug('update', User.name, userId, { name: 'Johnny' })\n let updatedUser = await adapter.update(User, userId, { name: 'Johnny' })\n assert.debug('updated', User.name, updatedUser)\n assert.equal(updatedUser.name, 'Johnny')\n assert.equal(updatedUser[User.idAttribute], userId)\n\n assert.isTrue(adapter.afterUpdate.calledOnce, 'afterUpdate should have been called once')\n\n const args = adapter.afterUpdate.firstCall.args\n assert.equal(args.length, 5, 'beforeUpdate should have received 5 arguments')\n assert.isTrue(args[0] === User, 'afterUpdate should have received User mapper')\n assert.isTrue(args[1] === userId, 'afterUpdate should have received user id')\n assert.objectsEqual(args[2], { name: 'Johnny' }, 'afterUpdate should have received update props')\n assert.isDefined(args[3], 'afterUpdate should have received options')\n assert.equal(args[3].op, 'afterUpdate', 'args[3].op')\n assert.isDefined(args[4], 'afterUpdate should have received updated record')\n assert.equal(args[4][User.idAttribute], userId, `args[4].${User.idAttribute}`)\n assert.equal(args[4].name, 'Johnny', 'args[4].name')\n adapter.afterUpdate.restore()\n })\n it('should allow returning a promise and re-assignment', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n sinon.stub(adapter, 'afterUpdate').callsFake(function (mapper, id, props, opts) {\n assert.isDefined(opts, 'afterUpdate should have received options')\n assert.equal(opts.op, 'afterUpdate', 'opts.op')\n return Promise.resolve('foo')\n })\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n const userId = user[User.idAttribute]\n assert.debug('created', User.name, user)\n\n assert.equal(user.name, props.name, `name of user should be \"${props.name}\"`)\n assert.isDefined(user[User.idAttribute], 'new user should have an id')\n\n assert.debug('update', User.name, userId, { name: 'Johnny' })\n let updatedUser = await adapter.update(User, userId, { name: 'Johnny' })\n assert.debug('updated', User.name, updatedUser)\n assert.equal(updatedUser, 'foo', 'should have received re-assigned value')\n\n assert.isTrue(adapter.afterUpdate.calledOnce, 'afterUpdate should have been called once')\n\n const args = adapter.afterUpdate.firstCall.args\n assert.equal(args.length, 5, 'beforeUpdate should have received 5 arguments')\n assert.isTrue(args[0] === User, 'afterUpdate should have received User mapper')\n assert.isTrue(args[1] === userId, 'afterUpdate should have received user id')\n assert.objectsEqual(args[2], { name: 'Johnny' }, 'afterUpdate should have received update props')\n assert.isDefined(args[3], 'afterUpdate should have received options')\n assert.equal(args[3].op, 'afterUpdate', 'args[3].op')\n assert.isDefined(args[4], 'afterUpdate should have received updated record')\n assert.equal(args[4][User.idAttribute], userId, `args[4].${User.idAttribute}`)\n assert.equal(args[4].name, 'Johnny', 'args[4].name')\n adapter.afterUpdate.restore()\n })\n })\n}\n","/* global assert:true */\nexport default function (options) {\n describe('Adapter#beforeCreate', function () {\n it('should exist', function () {\n assert.equal(typeof this.$$adapter.beforeCreate, 'function', 'adapter should have a \"beforeCreate\" method')\n })\n it('should call beforeCreate', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n sinon.stub(adapter, 'beforeCreate').callsFake(function (mapper, props, opts) {\n assert.isDefined(opts, 'beforeCreate should have received options')\n assert.equal(opts.op, 'beforeCreate', 'opts.op')\n })\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n assert.equal(user.name, props.name, `name of user should be \"${props.name}\"`)\n assert.isDefined(user[User.idAttribute], 'new user should have an id')\n\n assert.isTrue(adapter.beforeCreate.calledOnce, 'beforeCreate should have been called once')\n\n const args = adapter.beforeCreate.firstCall.args\n assert.equal(args.length, 3, 'beforeCreate should have received 3 arguments')\n assert.isTrue(args[0] === User, 'beforeCreate should have received User mapper')\n assert.objectsEqual(args[1], { name: 'John' }, 'beforeCreate should have received create props')\n assert.isObject(args[2], 'beforeCreate should have received options')\n adapter.beforeCreate.restore()\n })\n it('should allow re-assignment', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n sinon.stub(adapter, 'beforeCreate').callsFake(function (mapper, props, opts) {\n assert.isDefined(opts, 'beforeCreate should have received options')\n assert.equal(opts.op, 'beforeCreate', 'opts.op')\n return { name: 'Sally' }\n })\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n assert.equal(user.name, 'Sally', 'name of user should be \"Sally\"')\n assert.isDefined(user[User.idAttribute], 'new user should have an id')\n\n assert.isTrue(adapter.beforeCreate.calledOnce, 'beforeCreate should have been called once')\n\n const args = adapter.beforeCreate.firstCall.args\n assert.equal(args.length, 3, 'beforeCreate should have received 3 arguments')\n assert.isTrue(args[0] === User, 'beforeCreate should have received User mapper')\n assert.objectsEqual(args[1], { name: 'John' }, 'beforeCreate should have received create props')\n assert.isObject(args[2], 'beforeCreate should have received options')\n adapter.beforeCreate.restore()\n })\n it('should allow returning a promise', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n sinon.stub(adapter, 'beforeCreate').callsFake(function (mapper, props, opts) {\n assert.isDefined(opts, 'beforeCreate should have received options')\n assert.equal(opts.op, 'beforeCreate', 'opts.op')\n return Promise.resolve()\n })\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n assert.equal(user.name, props.name, `name of user should be \"${props.name}\"`)\n assert.isDefined(user[User.idAttribute], 'new user should have an id')\n\n assert.isTrue(adapter.beforeCreate.calledOnce, 'beforeCreate should have been called once')\n\n const args = adapter.beforeCreate.firstCall.args\n assert.equal(args.length, 3, 'beforeCreate should have received 3 arguments')\n assert.isTrue(args[0] === User, 'beforeCreate should have received User mapper')\n assert.objectsEqual(args[1], { name: 'John' }, 'beforeCreate should have received create props')\n assert.isDefined(args[2], 'beforeCreate should have received options')\n adapter.beforeCreate.restore()\n })\n it('should allow returning a promise and re-assignment', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n sinon.stub(adapter, 'beforeCreate').callsFake(function (mapper, props, opts) {\n assert.isDefined(opts, 'beforeCreate should have received options')\n assert.equal(opts.op, 'beforeCreate', 'opts.op')\n return Promise.resolve({ name: 'Sally' })\n })\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n assert.equal(user.name, 'Sally', 'name of user should be \"Sally\"')\n assert.isDefined(user[User.idAttribute], 'new user should have an id')\n\n assert.isTrue(adapter.beforeCreate.calledOnce, 'beforeCreate should have been called once')\n\n const args = adapter.beforeCreate.firstCall.args\n assert.equal(args.length, 3, 'beforeCreate should have received 3 arguments')\n assert.isTrue(args[0] === User, 'beforeCreate should have received User mapper')\n assert.objectsEqual(args[1], { name: 'John' }, 'beforeCreate should have received create props')\n assert.isObject(args[2], 'beforeCreate should have received options')\n adapter.beforeCreate.restore()\n })\n })\n}\n","/* global assert:true */\nexport default function (options) {\n describe('Adapter#beforeUpdate', function () {\n it('should exist', function () {\n assert.equal(typeof this.$$adapter.beforeUpdate, 'function', 'adapter should have a \"beforeUpdate\" method')\n })\n it('should call beforeUpdate', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n sinon.stub(adapter, 'beforeUpdate').callsFake(function (mapper, id, props, opts) {\n assert.isDefined(opts, 'beforeUpdate should have received options')\n assert.equal(opts.op, 'beforeUpdate', 'opts.op')\n })\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n const userId = user[User.idAttribute]\n assert.debug('created', User.name, user)\n\n assert.equal(user.name, props.name, `name of user should be \"${props.name}\"`)\n assert.isDefined(user[User.idAttribute], 'new user should have an id')\n\n assert.debug('update', User.name, userId, { name: 'Johnny' })\n let updatedUser = await adapter.update(User, userId, { name: 'Johnny' })\n assert.debug('updated', User.name, updatedUser)\n assert.equal(updatedUser.name, 'Johnny')\n assert.equal(updatedUser[User.idAttribute], userId)\n\n assert.isTrue(adapter.beforeUpdate.calledOnce, 'beforeUpdate should have been called once')\n\n const args = adapter.beforeUpdate.firstCall.args\n assert.equal(args.length, 4, 'beforeUpdate should have received 4 arguments')\n assert.isTrue(args[0] === User, 'beforeUpdate should have received User mapper')\n assert.isTrue(args[1] === userId, 'beforeUpdate should have received user id')\n assert.objectsEqual(args[2], { name: 'Johnny' }, 'beforeUpdate should have received update props')\n assert.isObject(args[3], 'beforeUpdate should have received options')\n adapter.beforeUpdate.restore()\n })\n it('should allow re-assignment', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n sinon.stub(adapter, 'beforeUpdate').callsFake(function (mapper, id, props, opts) {\n assert.isDefined(opts, 'beforeUpdate should have received options')\n assert.equal(opts.op, 'beforeUpdate', 'opts.op')\n return { name: 'Sally' }\n })\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n const userId = user[User.idAttribute]\n assert.debug('created', User.name, user)\n\n assert.equal(user.name, props.name, `name of user should be \"${props.name}\"`)\n assert.isDefined(user[User.idAttribute], 'new user should have an id')\n\n assert.debug('update', User.name, userId, { name: 'Johnny' })\n let updatedUser = await adapter.update(User, userId, { name: 'Johnny' })\n assert.debug('updated', User.name, updatedUser)\n assert.equal(updatedUser.name, 'Sally')\n assert.equal(updatedUser[User.idAttribute], userId)\n\n assert.isTrue(adapter.beforeUpdate.calledOnce, 'beforeUpdate should have been called once')\n\n const args = adapter.beforeUpdate.firstCall.args\n assert.equal(args.length, 4, 'beforeUpdate should have received 4 arguments')\n assert.isTrue(args[0] === User, 'beforeUpdate should have received User mapper')\n assert.isTrue(args[1] === userId, 'beforeUpdate should have received user id')\n assert.objectsEqual(args[2], { name: 'Johnny' }, 'beforeUpdate should have received update props')\n assert.isObject(args[3], 'beforeUpdate should have received options')\n adapter.beforeUpdate.restore()\n })\n it('should allow returning a promise', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n sinon.stub(adapter, 'beforeUpdate').callsFake(function (mapper, id, props, opts) {\n assert.isDefined(opts, 'beforeUpdate should have received options')\n assert.equal(opts.op, 'beforeUpdate', 'opts.op')\n return Promise.resolve()\n })\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n const userId = user[User.idAttribute]\n assert.debug('created', User.name, user)\n\n assert.equal(user.name, props.name, `name of user should be \"${props.name}\"`)\n assert.isDefined(user[User.idAttribute], 'new user should have an id')\n\n assert.debug('update', User.name, userId, { name: 'Johnny' })\n let updatedUser = await adapter.update(User, userId, { name: 'Johnny' })\n assert.debug('updated', User.name, updatedUser)\n assert.equal(updatedUser.name, 'Johnny')\n assert.equal(updatedUser[User.idAttribute], userId)\n\n assert.isTrue(adapter.beforeUpdate.calledOnce, 'beforeUpdate should have been called once')\n\n const args = adapter.beforeUpdate.firstCall.args\n assert.equal(args.length, 4, 'beforeUpdate should have received 4 arguments')\n assert.isTrue(args[0] === User, 'beforeUpdate should have received User mapper')\n assert.isTrue(args[1] === userId, 'beforeUpdate should have received user id')\n assert.objectsEqual(args[2], { name: 'Johnny' }, 'beforeUpdate should have received update props')\n assert.isObject(args[3], 'beforeUpdate should have received options')\n adapter.beforeUpdate.restore()\n })\n it('should allow returning a promise and re-assignment', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n sinon.stub(adapter, 'beforeUpdate').callsFake(function (mapper, id, props, opts) {\n assert.isDefined(opts, 'beforeUpdate should have received options')\n assert.equal(opts.op, 'beforeUpdate', 'opts.op')\n return Promise.resolve({ name: 'Sally' })\n })\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n const userId = user[User.idAttribute]\n assert.debug('created', User.name, user)\n\n assert.equal(user.name, props.name, `name of user should be \"${props.name}\"`)\n assert.isDefined(user[User.idAttribute], 'new user should have an id')\n\n assert.debug('update', User.name, userId, { name: 'Johnny' })\n let updatedUser = await adapter.update(User, userId, { name: 'Johnny' })\n assert.debug('updated', User.name, updatedUser)\n assert.equal(updatedUser.name, 'Sally')\n assert.equal(updatedUser[User.idAttribute], userId)\n\n assert.isTrue(adapter.beforeUpdate.calledOnce, 'beforeUpdate should have been called once')\n\n const args = adapter.beforeUpdate.firstCall.args\n assert.equal(args.length, 4, 'beforeUpdate should have received 4 arguments')\n assert.isTrue(args[0] === User, 'beforeUpdate should have received User mapper')\n assert.isTrue(args[1] === userId, 'beforeUpdate should have received user id')\n assert.objectsEqual(args[2], { name: 'Johnny' }, 'beforeUpdate should have received update props')\n assert.isObject(args[3], 'beforeUpdate should have received options')\n adapter.beforeUpdate.restore()\n })\n })\n}\n","/* global assert:true */\nexport default function (options) {\n describe('Adapter#count', function () {\n it('should exist', function () {\n assert.equal(typeof this.$$adapter.count, 'function', 'adapter should have a \"count\" method')\n })\n it('should count users', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n assert.debug('count', User.name, {})\n let count = await adapter.count(User)\n assert.debug('counted', User.name, count)\n assert.equal(count, 0)\n\n assert.debug('count', User.name, { name: 'John' })\n count = await adapter.count(User, { name: 'John' })\n assert.debug('counted', User.name, count)\n assert.equal(count, 0)\n\n assert.debug('count', User.name, { name: 'Sally' })\n count = await adapter.count(User, { name: 'Sally' })\n assert.debug('counted', User.name, count)\n assert.equal(count, 0)\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n assert.debug('count', User.name, {})\n count = await adapter.count(User)\n assert.debug('counted', User.name, count)\n assert.equal(count, 1)\n\n assert.debug('count', User.name, { name: 'John' })\n count = await adapter.count(User, { name: 'John' })\n assert.debug('counted', User.name, count)\n assert.equal(count, 1)\n\n assert.debug('count', User.name, { name: 'Sally' })\n count = await adapter.count(User, { name: 'Sally' })\n assert.debug('counted', User.name, count)\n assert.equal(count, 0)\n\n assert.debug('create', User.name, { name: 'Sally' })\n const user2 = await adapter.create(User, { name: 'Sally' })\n assert.debug('created', User.name, user2)\n\n assert.debug('count', User.name, {})\n count = await adapter.count(User)\n assert.debug('counted', User.name, count)\n assert.equal(count, 2)\n\n assert.debug('count', User.name, { name: 'John' })\n count = await adapter.count(User, { name: 'John' })\n assert.debug('counted', User.name, count)\n assert.equal(count, 1)\n\n assert.debug('count', User.name, { name: 'Sally' })\n count = await adapter.count(User, { name: 'Sally' })\n assert.debug('counted', User.name, count)\n assert.equal(count, 1)\n })\n it('should count users and return raw', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n assert.debug('create', User.name, props)\n let user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n assert.debug('count', User.name, props)\n const result = await adapter.count(User, props, { raw: true })\n assert.debug('counted', User.name, result)\n assert.equal(result.data, 1, 'result.data')\n })\n })\n}\n","/* global assert:true */\nexport default function (options) {\n describe('Adapter#create', function () {\n it('should exist', function () {\n assert.equal(typeof this.$$adapter.create, 'function', 'adapter should have a \"create\" method')\n })\n it('should create a user', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n const userId = user[User.idAttribute]\n assert.debug('created', User.name, user)\n\n assert.equal(user.name, props.name, 'user.name')\n assert.isDefined(user[User.idAttribute], 'user[User.idAttribute]')\n\n assert.debug('find', User.name, userId)\n const foundUser = await adapter.find(User, userId)\n assert.debug('found', User.name, foundUser)\n\n assert.equal(foundUser.name, props.name, 'foundUser.name')\n assert.isDefined(foundUser[User.idAttribute], 'foundUser[User.idAttribute]')\n assert.equal(foundUser[User.idAttribute], userId, 'foundUser[User.idAttribute]')\n })\n })\n}\n","/* global assert:true */\nexport default function (options) {\n describe('Adapter#createMany', function () {\n it('should exist', function () {\n assert.equal(typeof this.$$adapter.createMany, 'function', 'adapter should have a \"createMany\" method')\n })\n it('should create multiple users', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n let user1 = { name: 'John', age: 20 }\n\n let user2 = { name: 'John', age: 30 }\n\n assert.debug('createMany', User.name, [user1, user2])\n const users = await adapter.createMany(User, [user1, user2])\n assert.debug('created', User.name, users)\n users.sort(function (a, b) {\n return a.age - b.age\n })\n assert.isDefined(users[0][User.idAttribute])\n assert.isDefined(users[1][User.idAttribute])\n assert.equal(users.filter(function (x) { return x.age === 20 }).length, 1)\n assert.equal(users.filter(function (x) { return x.age === 30 }).length, 1)\n\n assert.debug('findAll', User.name, { age: 20 })\n const users3 = await adapter.findAll(User, { age: 20 })\n assert.debug('found', User.name, users3)\n assert.equal(users3.length, 1)\n })\n })\n}\n","/* global assert:true */\nexport default function (options) {\n describe('Adapter#destroy', function () {\n it('should exist', function () {\n assert.equal(typeof this.$$adapter.destroy, 'function', 'adapter should have a \"destroy\" method')\n })\n it('should destroy a user', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n assert.debug('create', User.name, props)\n let user = await adapter.create(User, props)\n let userId = user[User.idAttribute]\n assert.debug('created', User.name, user)\n\n let beforeDestroyCalled = false\n let afterDestroyCalled = false\n\n // Test beforeDestroy and afterDestroy\n adapter.beforeDestroy = function (mapper, id, opts) {\n beforeDestroyCalled = true\n assert.isObject(mapper, 'beforeDestroy should have received mapper argument')\n assert.isDefined(id, 'beforeDestroy should have received id argument')\n assert.isObject(opts, 'beforeDestroy should have received opts argument')\n // Test re-assignment\n return Promise.resolve()\n }\n adapter.afterDestroy = function (mapper, id, opts) {\n afterDestroyCalled = true\n assert.isObject(mapper, 'afterDestroy should have received mapper argument')\n assert.isDefined(id, 'afterDestroy should have received id argument')\n assert.isObject(opts, 'afterDestroy should have received opts argument')\n // Test re-assignment\n return Promise.resolve()\n }\n\n assert.debug('destroy', User.name, userId)\n const destroyedUser = await adapter.destroy(User, userId)\n assert.debug('destroyed', User.name, destroyedUser)\n assert.isUndefined(destroyedUser, 'destroyedUser')\n assert.isTrue(beforeDestroyCalled, 'beforeDestroy should have been called')\n assert.isTrue(afterDestroyCalled, 'afterDestroy should have been called')\n })\n it('should destroy a user and allow afterDestroy re-assignment', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n assert.debug('create', User.name, props)\n let user = await adapter.create(User, props)\n let userId = user[User.idAttribute]\n assert.debug('created', User.name, user)\n\n let beforeDestroyCalled = false\n let afterDestroyCalled = false\n\n // Test beforeDestroy and afterDestroy\n adapter.beforeDestroy = function (mapper, id, opts) {\n beforeDestroyCalled = true\n assert.isObject(mapper, 'beforeDestroy should have received mapper argument')\n assert.isDefined(id, 'beforeDestroy should have received id argument')\n assert.isObject(opts, 'beforeDestroy should have received opts argument')\n // Test re-assignment\n return Promise.resolve()\n }\n adapter.afterDestroy = function (mapper, id, opts) {\n afterDestroyCalled = true\n assert.isObject(mapper, 'afterDestroy should have received mapper argument')\n assert.isDefined(id, 'afterDestroy should have received id argument')\n assert.isObject(opts, 'afterDestroy should have received opts argument')\n // Test re-assignment\n return Promise.resolve('foo')\n }\n\n assert.debug('destroy', User.name, userId)\n const destroyedUser = await adapter.destroy(User, userId, { raw: true })\n assert.debug('destroyed', User.name, destroyedUser)\n assert.equal(destroyedUser, 'foo', 'destroyedUser')\n assert.isTrue(beforeDestroyCalled, 'beforeDestroy should have been called')\n assert.isTrue(afterDestroyCalled, 'afterDestroy should have been called')\n })\n it('should destroy a user and return raw', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n assert.debug('create', User.name, props)\n let user = await adapter.create(User, props)\n let userId = user[User.idAttribute]\n assert.debug('created', User.name, user)\n\n assert.debug('destroy', User.name, userId)\n const result = await adapter.destroy(User, userId, { raw: true })\n assert.debug('destroyed', User.name, result)\n assert.isUndefined(result.data, 'result.data')\n if (result.hasOwnProperty('deleted')) {\n assert.isDefined(result.deleted, 'result.deleted')\n assert.equal(result.deleted, 1, 'result.deleted')\n }\n })\n it('should destroy nothing', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n\n assert.debug('destroy', User.name, 'non-existent-id')\n const result = await adapter.destroy(User, 'non-existent-id')\n assert.debug('destroyed', User.name, result)\n assert.isUndefined(result, 'result')\n })\n it('should destroy nothing and return raw', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n\n assert.debug('destroy', User.name, 'non-existent-id')\n const result = await adapter.destroy(User, 'non-existent-id', { raw: true })\n assert.debug('destroyed', User.name, result)\n assert.isUndefined(result.data, 'result.data')\n if (result.hasOwnProperty('deleted')) {\n assert.isDefined(result.deleted, 'result.deleted')\n assert.equal(result.deleted, 0, 'result.deleted')\n }\n })\n })\n}\n","/* global assert:true */\nexport default function (options) {\n describe('Adapter#destroyAll', function () {\n it('should exist', function () {\n assert.equal(typeof this.$$adapter.destroyAll, 'function', 'adapter should have a \"destroyAll\" method')\n })\n it('should destroy all users', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n const userId = user[User.idAttribute]\n assert.debug('created', User.name, user)\n\n assert.debug('create', User.name, { name: 'Sally' })\n const user2 = await adapter.create(User, { name: 'Sally' })\n assert.debug('created', User.name, user2)\n\n assert.debug('findAll', User.name, { name: 'John' })\n let foundUsers = await adapter.findAll(User, { name: 'John' })\n assert.debug('found', User.name, foundUsers)\n assert.equal(foundUsers.length, 1, 'foundUsers.length')\n assert.equal(foundUsers[0][User.idAttribute], userId, 'foundUsers[0][User.idAttribute]')\n assert.equal(foundUsers[0].name, 'John', 'foundUsers[0].name')\n\n assert.debug('destroyAll', User.name, { name: 'John' })\n const destroyedUsers = await adapter.destroyAll(User, { name: 'John' })\n assert.debug('destroyed', User.name, destroyedUsers)\n assert.isUndefined(destroyedUsers, 'destroyedUsers')\n\n assert.debug('findAll', User.name, { name: 'John' })\n foundUsers = await adapter.findAll(User, { name: 'John' })\n assert.debug('found', User.name, foundUsers)\n assert.equal(foundUsers.length, 0)\n\n assert.debug('findAll', User.name, {})\n foundUsers = await adapter.findAll(User, {})\n assert.debug('found', User.name, foundUsers)\n assert.equal(foundUsers.length, 1)\n })\n it('should destroy users and return raw', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n assert.debug('create', User.name, props)\n let user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n assert.debug('destroyAll', User.name, props)\n const result = await adapter.destroyAll(User, props, { raw: true })\n assert.debug('destroyed', User.name, result)\n assert.isUndefined(result.data, 'result.data')\n if (result.hasOwnProperty('deleted')) {\n assert.isDefined(result.deleted, 'result.deleted')\n assert.equal(result.deleted, 1, 'result.deleted')\n }\n })\n it('should destroy nothing', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n\n assert.debug('destroyAll', User.name, {})\n const result = await adapter.destroyAll(User, {})\n assert.debug('destroyed', User.name, result)\n assert.isUndefined(result, 'result')\n })\n it('should destroy nothing and return raw', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n\n assert.debug('destroyAll', User.name, {})\n const result = await adapter.destroyAll(User, {}, { raw: true })\n assert.debug('destroyed', User.name, result)\n assert.isUndefined(result.data, 'result.data')\n if (result.hasOwnProperty('deleted')) {\n assert.isDefined(result.deleted, 'result.deleted')\n assert.equal(result.deleted, 0, 'result.deleted')\n }\n })\n })\n}\n","/* global assert:true */\nexport default function (options) {\n describe('Adapter.extend', function () {\n it('should exist', function () {\n assert.equal(typeof this.$$adapter.constructor.extend, 'function', 'adapter constructor function should have an \"extend\" method')\n })\n it('should return a subclass of the adapter class using extend', function () {\n const Adapter = this.$$adapter.constructor\n\n const SubAdapter = Adapter.extend({\n foo () {\n return 'foo'\n }\n }, {\n bar () {\n return 'bar'\n }\n })\n\n assert.equal(SubAdapter.bar(), 'bar', 'SubAdapter.bar() should return \"bar\"')\n try {\n assert.isTrue(SubAdapter.extend === Adapter.extend, 'should have same static methods')\n } catch (err) {\n assert.equal(typeof SubAdapter.extend, 'function', 'should have same static methods')\n }\n\n const subAdapter = new SubAdapter()\n\n assert.equal(subAdapter.foo(), 'foo', 'subAdapter.foo() should return \"foo\"')\n assert.isTrue(subAdapter.find === subAdapter.find, 'should have same instance methods')\n })\n it('should return a subclass of the adapter class using ES6 classes', function () {\n const Adapter = this.$$adapter.constructor\n\n class SubAdapter extends Adapter {\n foo () {\n return 'foo'\n }\n static bar () {\n return 'bar'\n }\n }\n\n assert.equal(SubAdapter.bar(), 'bar', 'SubAdapter.bar() should return \"bar\"')\n try {\n assert.isTrue(SubAdapter.extend === Adapter.extend, 'should have same static methods')\n } catch (err) {\n try {\n assert.equal(typeof SubAdapter.extend, 'function', 'should have same static methods')\n } catch (err) {\n var obj = {}\n if (obj.setPrototypeOf) {\n throw err\n }\n }\n }\n\n const subAdapter = new SubAdapter()\n\n assert.equal(subAdapter.foo(), 'foo', 'subAdapter.foo() should return \"foo\"')\n assert.isTrue(subAdapter.find === subAdapter.find, 'should have same instance methods')\n })\n })\n}\n","/* global assert:true */\nexport default function (options) {\n describe('Adapter#find', function () {\n var adapter, User, Profile, Post, Comment, Tag\n\n beforeEach(function () {\n adapter = this.$$adapter\n User = this.$$User\n Profile = this.$$Profile\n Post = this.$$Post\n Comment = this.$$Comment\n Tag = this.$$Tag\n })\n\n it('should exist', function () {\n assert.equal(typeof adapter.find, 'function', 'adapter should have a \"find\" method')\n })\n\n it('should find a user', async function () {\n this.toClear.push('Post')\n this.toClear.push('Comment')\n let props = { name: 'John' }\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n const userId = user[User.idAttribute]\n assert.equal(user.name, 'John', 'user.name')\n assert.isDefined(user[User.idAttribute], 'user[User.idAttribute]')\n\n // Test beforeFind and afterFind\n let beforeFindCalled = false\n let afterFindCalled = false\n adapter.beforeFind = function (mapper, id, opts) {\n beforeFindCalled = true\n assert.isObject(mapper, 'beforeFind should have received mapper argument')\n assert.isDefined(id, 'beforeFind should have received id argument')\n assert.equal(id, userId, 'beforeFind should have received correct id argument')\n assert.isObject(opts, 'beforeFind should have received opts argument')\n // Optionally return a promise for async\n return Promise.resolve()\n }\n adapter.afterFind = function (mapper, id, opts, record) {\n afterFindCalled = true\n assert.isObject(mapper, 'afterFind should have received mapper argument')\n assert.isDefined(id, 'afterFind should have received id argument')\n assert.equal(id, userId, 'afterFind should have received correct id argument')\n assert.isObject(opts, 'afterFind should have received opts argument')\n assert.isObject(record, 'afterFind should have received record argument')\n // Optionally return a promise for async\n return Promise.resolve()\n }\n\n assert.debug('find', User.name, userId)\n let foundUser = await adapter.find(User, userId)\n assert.debug('found', User.name, foundUser)\n assert.equal(foundUser.name, 'John', 'name of found user should be \"John\"')\n assert.equal(foundUser[User.idAttribute], userId, 'found user should have correct id')\n assert.isTrue(beforeFindCalled, 'beforeFind should have been called')\n assert.isTrue(afterFindCalled, 'afterFind should have been called')\n\n // should allow re-assignment\n beforeFindCalled = false\n afterFindCalled = false\n adapter.afterFind = function (mapper, id, opts, record) {\n afterFindCalled = true\n assert.isObject(mapper, 'afterFind should have received mapper argument')\n assert.isDefined(id, 'afterFind should have received id argument')\n assert.equal(id, userId, 'afterFind should have received correct id argument')\n assert.isObject(opts, 'afterFind should have received opts argument')\n assert.isObject(record, 'afterFind should have received record argument')\n // Test re-assignment\n return Promise.resolve({ name: 'Sally', [User.idAttribute]: userId })\n }\n\n assert.debug('find', User.name, userId)\n foundUser = await adapter.find(User, userId)\n assert.debug('found', User.name, foundUser)\n assert.equal(foundUser.name, 'Sally', 'foundUser.name')\n assert.equal(foundUser[User.idAttribute], userId, 'foundUser[User.idAttribute]')\n assert.isTrue(beforeFindCalled, 'beforeFind should have been called')\n assert.isTrue(afterFindCalled, 'afterFind should have been called')\n // clear hooks\n delete adapter.beforeFind\n delete adapter.afterFind\n\n props = { content: 'test', userId: userId }\n assert.debug('create', Post.name, props)\n const post = await adapter.create(Post, props)\n assert.debug('created', Post.name, post)\n const postId = post[Post.idAttribute]\n\n assert.equal(post.content, 'test', 'post.content')\n assert.isDefined(post[Post.idAttribute], 'post[Post.idAttribute]')\n assert.equal(post.userId, userId, 'post.userId')\n\n props = [\n {\n content: 'test2',\n postId,\n userId\n },\n {\n content: 'test3',\n postId,\n userId\n }\n ]\n assert.debug('create', Comment.name, props)\n const comments = await Promise.all([\n adapter.create(Comment, props[0]),\n adapter.create(Comment, props[1])\n ])\n assert.debug('created', Comment.name, comments)\n\n comments.sort(function (a, b) {\n return a.content > b.content\n })\n\n assert.debug('find', Post.name, postId)\n const foundPost = await adapter.find(Post, postId, { with: ['user', 'comment'] })\n assert.debug('found', Post.name, foundPost)\n foundPost.comments.sort(function (a, b) {\n return a.content > b.content\n })\n assert.equalObjects(foundPost.user, user, 'foundPost.user')\n assert.equalObjects(foundPost.comments, comments, 'foundPost.comments')\n })\n\n it('should return raw', async function () {\n let props = { name: 'John' }\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n const userId = user[User.idAttribute]\n assert.equal(user.name, 'John', 'user.name')\n assert.isDefined(user[User.idAttribute], 'user[User.idAttribute]')\n\n assert.debug('find', User.name, userId)\n const result = await adapter.find(User, userId, { raw: true })\n assert.debug('found', User.name, result)\n assert.isDefined(result.data, 'result.data')\n assert.isDefined(result.found, 'result.found')\n assert.equal(result.data.name, 'John', 'result.data.name')\n assert.equal(result.data[User.idAttribute], userId, `result.data.${User.idAttribute}`)\n assert.equal(result.found, 1, 'result.found')\n })\n\n it('should return nothing', async function () {\n assert.debug('find', User.name, 'non-existent-id')\n const result = await adapter.find(User, 'non-existent-id')\n assert.debug('found', User.name, result)\n assert.isUndefined(result, 'result')\n })\n\n it('should return raw and nothing', async function () {\n assert.debug('find', User.name, 'non-existent-id')\n const result = await adapter.find(User, 'non-existent-id', { raw: true })\n assert.debug('found', User.name, result)\n assert.isUndefined(result.data, 'result.data')\n assert.isDefined(result.found, 'result.found')\n assert.equal(result.found, 0, 'result.found')\n })\n\n it('should load belongsTo relations', async function () {\n this.toClear.push('Post')\n this.toClear.push('Comment')\n this.toClear.push('Profile')\n let props = { name: 'John' }\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n props = { email: 'foo@test.com', userId: user[User.idAttribute] }\n assert.debug('create', Profile.name, props)\n const profile = await adapter.create(Profile, props)\n assert.debug('created', Profile.name, profile)\n\n props = { content: 'foo', userId: user[User.idAttribute] }\n assert.debug('create', Post.name, props)\n const post = await adapter.create(Post, props)\n assert.debug('created', Post.name, post)\n\n props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }\n assert.debug('create', Comment.name, props)\n let comment = await adapter.create(Comment, props)\n assert.debug('created', Comment.name, comment)\n\n assert.debug('find', Comment.name, comment[Comment.idAttribute])\n comment = await adapter.find(Comment, comment[Comment.idAttribute], {'with': ['user', 'post']})\n assert.debug('found', Comment.name, comment)\n\n assert.isDefined(comment, 'comment')\n assert.isDefined(comment.post, 'comment.post')\n assert.isDefined(comment.user, 'comment.user')\n })\n\n it('should load belongsTo relations and filter sub queries', async function () {\n this.toClear.push('Post')\n this.toClear.push('Comment')\n let props = { name: 'John' }\n assert.debug('create', User.name, props)\n let user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n props = { name: 'Sally' }\n assert.debug('create', User.name, props)\n let user2 = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n props = { status: 'draft', userId: user[User.idAttribute] }\n assert.debug('create', Post.name, props)\n const post = await adapter.create(Post, props)\n assert.debug('created', Post.name, post)\n\n props = { status: 'published', userId: user[User.idAttribute] }\n assert.debug('create', Post.name, props)\n const post2 = await adapter.create(Post, props)\n assert.debug('created', Post.name, post2)\n\n props = { status: 'draft', userId: user2[User.idAttribute] }\n assert.debug('create', Post.name, props)\n const post3 = await adapter.create(Post, props)\n assert.debug('created', Post.name, post3)\n\n props = { status: 'published', userId: user2[User.idAttribute] }\n assert.debug('create', Post.name, props)\n const post4 = await adapter.create(Post, props)\n assert.debug('created', Post.name, post4)\n\n assert.debug('find', User.name, user[User.idAttribute])\n user = await adapter.find(User, user[User.idAttribute], {'with': ['post']})\n assert.debug('found', User.name, user)\n\n assert.isDefined(user, 'user')\n assert.isDefined(user.posts, 'user.posts')\n assert.equal(user.posts.length, 2, 'user.posts.length')\n\n assert.debug('find', User.name, user[User.idAttribute])\n user = await adapter.find(User, user[User.idAttribute], {'with': [{\n relation: 'post',\n query: {\n status: 'published'\n }\n }]})\n assert.debug('found', User.name, user)\n\n assert.isDefined(user, 'user')\n assert.isDefined(user.posts, 'user.posts')\n assert.equal(user.posts.length, 1, 'user.posts.length')\n\n assert.debug('find', User.name, user[User.idAttribute])\n user = await adapter.find(User, user[User.idAttribute], {'with': [{\n relation: 'post',\n replace: true,\n query: {\n status: 'published'\n }\n }]})\n assert.debug('found', User.name, user)\n\n assert.isDefined(user, 'user')\n assert.isDefined(user.posts, 'user.posts')\n assert.equal(user.posts.length, 2, 'user.posts.length')\n })\n\n if (options.hasFeature('findBelongsToNested')) {\n it('should load belongsTo relations (nested)', async function () {\n this.toClear.push('Post')\n this.toClear.push('Comment')\n this.toClear.push('Profile')\n let props = { name: 'John' }\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n props = { email: 'foo@test.com', userId: user[User.idAttribute] }\n assert.debug('create', Profile.name, props)\n const profile = await adapter.create(Profile, props)\n assert.debug('created', Profile.name, profile)\n\n props = { content: 'foo', userId: user[User.idAttribute] }\n assert.debug('create', Post.name, props)\n const post = await adapter.create(Post, props)\n assert.debug('created', Post.name, post)\n\n props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }\n assert.debug('create', Comment.name, props)\n let comment = await adapter.create(Comment, props)\n assert.debug('created', Comment.name, comment)\n\n assert.debug('find', Comment.name, comment[Comment.idAttribute])\n comment = await adapter.find(Comment, comment[Comment.idAttribute], {'with': ['user', 'user.profile', 'post', 'post.user']})\n assert.debug('found', Comment.name, comment)\n\n assert.isDefined(comment, 'comment')\n assert.isDefined(comment.post, 'comment.post')\n assert.isDefined(comment.post.user, 'comment.post.user')\n assert.isDefined(comment.user, 'comment.user')\n assert.isDefined(comment.user.profile, 'comment.user.profile')\n })\n }\n\n it('should load hasMany and belongsTo relations', async function () {\n this.toClear.push('Post')\n this.toClear.push('Comment')\n this.toClear.push('Profile')\n let props = { name: 'John' }\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n props = { email: 'foo@test.com', userId: user[User.idAttribute] }\n assert.debug('create', Profile.name, props)\n const profile = await adapter.create(Profile, props)\n assert.debug('created', Profile.name, profile)\n\n props = { content: 'foo', userId: user[User.idAttribute] }\n assert.debug('create', Post.name, props)\n let post = await adapter.create(Post, props)\n let postId = post[Post.idAttribute]\n assert.debug('created', Post.name, post)\n\n props = { content: 'test2', postId, userId: post.userId }\n assert.debug('create', Comment.name, props)\n const comment = await adapter.create(Comment, props)\n assert.debug('created', Comment.name, comment)\n\n assert.debug('find', Post.name, postId)\n post = await adapter.find(Post, postId, {'with': ['user', 'comment']})\n assert.debug('found', Post.name, post)\n\n assert.isDefined(post.comments, 'post.comments')\n assert.isDefined(post.user, 'post.user')\n })\n\n if (options.hasFeature('findBelongsToHasManyNested')) {\n it('should load hasMany and belongsTo relations (nested)', async function () {\n this.toClear.push('Post')\n this.toClear.push('Comment')\n this.toClear.push('Profile')\n let props = { name: 'John' }\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n props = { email: 'foo@test.com', userId: user[User.idAttribute] }\n assert.debug('create', Profile.name, props)\n const profile = await adapter.create(Profile, props)\n assert.debug('created', Profile.name, profile)\n\n props = { content: 'foo', userId: user[User.idAttribute] }\n assert.debug('create', Post.name, props)\n let post = await adapter.create(Post, props)\n let postId = post[Post.idAttribute]\n assert.debug('created', Post.name, post)\n\n props = { content: 'test2', postId, userId: post.userId }\n assert.debug('create', Comment.name, props)\n const comment = await adapter.create(Comment, props)\n assert.debug('created', Comment.name, comment)\n\n assert.debug('find', Post.name, postId)\n post = await adapter.find(Post, postId, {'with': ['user', 'comment', 'comment.user', 'comment.user.profile']})\n assert.debug('found', Post.name, post)\n\n assert.isDefined(post.comments, 'post.comments')\n assert.isDefined(post.comments[0].user, 'post.comments[0].user')\n assert.isDefined(post.comments[0].user.profile, 'post.comments[0].user.profile')\n assert.isDefined(post.user, 'post.user')\n })\n }\n\n if (options.hasFeature('findHasManyLocalKeys')) {\n it('should load hasMany localKeys (array) relations', async function () {\n this.toClear.push('Post')\n this.toClear.push('Tag')\n let props = { value: 'big data' }\n assert.debug('create', Tag.name, props)\n const tag = await adapter.create(Tag, props)\n assert.debug('created', Tag.name, tag)\n\n props = { value: 'servers' }\n assert.debug('create', Tag.name, props)\n const tag2 = await adapter.create(Tag, props)\n assert.debug('created', Tag.name, tag2)\n\n props = { content: 'test', tagIds: [tag[Tag.idAttribute], tag2[Tag.idAttribute]] }\n assert.debug('create', Post.name, props)\n let post = await adapter.create(Post, props)\n let postId = post[Post.idAttribute]\n assert.debug('created', Post.name, post)\n\n assert.debug('find', Post.name, postId)\n post = await adapter.find(Post, postId, { 'with': ['tag'] })\n assert.debug('found', Post.name, post)\n\n assert.isDefined(post.tags, 'post.tags')\n assert.equal(post.content, 'test', 'post.content')\n assert.isDefined(post.tags[0][Tag.idAttribute], 'post.tags[0][Tag.idAttribute]')\n assert.isDefined(post.tags[1][Tag.idAttribute], 'post.tags[1][Tag.idAttribute]')\n })\n it('should load hasMany localKeys (empty array) relations', async function () {\n this.toClear.push('Post')\n let props = { content: 'test' }\n assert.debug('create', Post.name, props)\n let post = await adapter.create(Post, props)\n let postId = post[Post.idAttribute]\n assert.debug('created', Post.name, post)\n\n assert.debug('find', Post.name, postId)\n post = await adapter.find(Post, postId, { 'with': ['tag'] })\n assert.debug('found', Post.name, post)\n\n assert.isDefined(post.tags, 'post.tags')\n assert.equal(post.content, 'test', 'post.content')\n assert.deepEqual(post.tags, [], 'post.tags')\n })\n it('should load hasMany localKeys (object) relations', async function () {\n this.toClear.push('Post')\n this.toClear.push('Tag')\n let props = { value: 'big data' }\n assert.debug('create', Tag.name, props)\n const tag = await adapter.create(Tag, props)\n assert.debug('created', Tag.name, tag)\n\n props = { value: 'servers' }\n assert.debug('create', Tag.name, props)\n const tag2 = await adapter.create(Tag, props)\n assert.debug('created', Tag.name, tag2)\n\n props = { content: 'test', tagIds: { [tag[Tag.idAttribute]]: true, [tag2[Tag.idAttribute]]: true } }\n assert.debug('create', Post.name, props)\n let post = await adapter.create(Post, props)\n let postId = post[Post.idAttribute]\n assert.debug('created', Post.name, post)\n\n assert.debug('find', Post.name, postId)\n post = await adapter.find(Post, postId, { 'with': ['tag'] })\n assert.debug('found', Post.name)\n\n assert.isDefined(post.tags, 'post.tags')\n assert.equal(post.content, 'test', 'post.content')\n assert.isDefined(post.tags[0][Tag.idAttribute], 'post.tags[0][Tag.idAttribute]')\n assert.isDefined(post.tags[1][Tag.idAttribute], 'post.tags[1][Tag.idAttribute]')\n })\n }\n\n if (options.hasFeature('findHasManyForeignKeys')) {\n it('should load hasMany foreignKeys (array) relations', async function () {\n this.toClear.push('Post')\n this.toClear.push('Tag')\n let props = { value: 'big data' }\n assert.debug('create', Tag.name, props)\n let tag = await adapter.create(Tag, props)\n let tagId = tag[Tag.idAttribute]\n assert.debug('created', Tag.name, tag)\n\n props = { value: 'servers' }\n assert.debug('create', Tag.name, props)\n let tag2 = await adapter.create(Tag, props)\n let tag2Id = tag2[Tag.idAttribute]\n assert.debug('created', Tag.name, tag2)\n\n props = { content: 'test', tagIds: [tagId] }\n assert.debug('create', Post.name, props)\n let post = await adapter.create(Post, props)\n assert.debug('created', Post.name, post)\n\n props = { content: 'test2', tagIds: [tagId, tag2Id] }\n assert.debug('create', Post.name, props)\n let post2 = await adapter.create(Post, props)\n assert.debug('created', Post.name, post2)\n\n assert.debug('find', Tag.name, tagId)\n tag = await adapter.find(Tag, tagId, { 'with': ['post'] })\n assert.debug('found', Tag.name, tag)\n\n assert.isDefined(tag.posts, 'tag.posts')\n assert.equal(tag.value, 'big data', 'tag.value')\n assert.equal(tag.posts.length, 2, 'tag.posts.length')\n\n assert.debug('find', Tag.name, tag2Id)\n tag2 = await adapter.find(Tag, tag2Id, { 'with': ['post'] })\n assert.debug('found', Tag.name, tag2)\n\n assert.isDefined(tag2.posts, 'tag2.posts')\n assert.equal(tag2.value, 'servers', 'tag2.value')\n assert.equal(tag2.posts.length, 1, 'tag2.posts.length')\n assert.objectsEqual(tag2.posts, [post2], 'tag2.posts')\n })\n }\n })\n}\n","/* global assert:true */\nexport default function (options) {\n describe('Adapter#findAll', function () {\n var adapter, User, Profile, Post, Comment\n\n beforeEach(function () {\n adapter = this.$$adapter\n User = this.$$User\n Profile = this.$$Profile\n Post = this.$$Post\n Comment = this.$$Comment\n })\n\n it('should exist', function () {\n assert.equal(typeof adapter.findAll, 'function', 'adapter should have a \"findAll\" method')\n })\n\n it('should filter users', async function () {\n let props = { name: 'John' }\n assert.debug('findAll', User.name, { age: 30 })\n const users = await adapter.findAll(User, { age: 30 })\n assert.debug('found', User.name, users)\n assert.equal(users.length, 0, 'users.length')\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n const userId = user[User.idAttribute]\n\n assert.debug('findAll', User.name, { name: 'John' })\n const users2 = await adapter.findAll(User, { name: 'John' })\n assert.debug('found', User.name, users2)\n\n assert.equal(users2.length, 1, 'users2.length')\n assert.equal(users2[0][User.idAttribute], userId, 'users2[0][User.idAttribute]')\n assert.equal(users2[0].name, 'John', users2[0].name)\n })\n\n it('should filter users with raw option', async function () {\n let props = { name: 'John' }\n assert.debug('findAll', User.name, { age: 30 })\n const result = await adapter.findAll(User, { age: 30 }, { raw: true })\n const users = result.data\n assert.debug('found', User.name, users)\n assert.equal(users.length, 0, 'users.length')\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n const userId = user[User.idAttribute]\n\n assert.debug('findAll', User.name, { name: 'John' })\n const result2 = await adapter.findAll(User, { name: 'John' }, { raw: true })\n const users2 = result2.data\n assert.debug('found', User.name, users2)\n\n assert.equal(users2.length, 1, 'users2.length')\n assert.equal(users2[0][User.idAttribute], userId, 'users2[0][User.idAttribute]')\n assert.equal(users2[0].name, 'John', users2[0].name)\n })\n\n if (options.hasFeature('findAllInOp')) {\n it('should filter users using the \"in\" operator', async function () {\n var users = await adapter.findAll(User, {\n where: {\n age: {\n 'in': [30]\n }\n }\n })\n assert.equal(users.length, 0, 'users.length')\n\n var user = await adapter.create(User, {name: 'John'})\n var id = user[User.idAttribute]\n\n var users2 = await adapter.findAll(User, { name: 'John' })\n assert.equal(users2.length, 1, 'users2.length')\n assert.equal(users2[0][User.idAttribute], id, 'users2[0][User.idAttribute]')\n assert.equal(users2[0].name, 'John', 'users2[0].name')\n })\n }\n\n if (options.hasFeature('findAllLikeOp')) {\n it('should filter users using the \"like\" operator', async function () {\n var users = await adapter.findAll(User, {\n where: {\n name: {\n 'like': '%J%'\n }\n }\n })\n assert.equal(users.length, 0)\n\n var user = await adapter.create(User, {name: 'John'})\n var id = user.id\n\n var users2 = await adapter.findAll(User, {\n where: {\n name: {\n 'like': '%J%'\n }\n }\n })\n assert.equal(users2.length, 1)\n assert.equal(users2[0].id, id)\n assert.equal(users2[0].name, 'John')\n })\n }\n\n if (options.hasFeature('findAllOpNotFound')) {\n it('should throw \"Operator not found\" error', function () {\n return adapter.findAll(User, {\n where: {\n name: {\n op: 'John'\n }\n }\n }).then(function () {\n throw new Error('should have failed!')\n }, function (err) {\n assert.equal(err.message, 'Operator op not supported!')\n })\n })\n }\n\n if (options.hasFeature('findAllBelongsTo')) {\n it('should load belongsTo relations', async function () {\n this.toClear.push('Post')\n this.toClear.push('Profile')\n this.toClear.push('Comment')\n let props = { name: 'John' }\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n props = { email: 'foo@test.com', userId: user[User.idAttribute] }\n assert.debug('create', Profile.name, props)\n const profile = await adapter.create(Profile, props)\n assert.debug('created', Profile.name, profile)\n\n props = { content: 'foo', userId: user[User.idAttribute] }\n assert.debug('create', Post.name, props)\n const post = await adapter.create(Post, props)\n assert.debug('created', Post.name, post)\n\n props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }\n assert.debug('create', Comment.name, props)\n let comment = await adapter.create(Comment, props)\n assert.debug('created', Comment.name, comment)\n\n props = { name: 'Sally' }\n assert.debug('create', User.name, props)\n const user2 = await adapter.create(User, props)\n assert.debug('created', User.name, user2)\n\n props = { content: 'bar', userId: user2[User.idAttribute] }\n assert.debug('create', Post.name, props)\n const post2 = await adapter.create(Post, props)\n assert.debug('created', Post.name, post2)\n\n props = { content: 'test67', postId: post2[Post.idAttribute], userId: post2.userId }\n assert.debug('create', Comment.name, props)\n let comment2 = await adapter.create(Comment, props)\n assert.debug('created', Comment.name, comment2)\n\n assert.debug('findAll', Comment.name, {})\n const comments = await adapter.findAll(Comment, {}, {'with': ['user', 'post']})\n assert.debug('found', Comment.name, comments)\n\n assert.isDefined(comments[0].post, 'comments[0].post')\n assert.isDefined(comments[0].user, 'comments[0].user')\n assert.isDefined(comments[1].post, 'comments[1].post')\n assert.isDefined(comments[1].user, 'comments[1].user')\n })\n\n it('should load belongsTo relations and filter sub queries', async function () {\n this.toClear.push('Post')\n this.toClear.push('Comment')\n let props = { name: 'John' }\n assert.debug('create', User.name, props)\n let user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n props = { name: 'Sally' }\n assert.debug('create', User.name, props)\n let user2 = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n props = { status: 'draft', userId: user[User.idAttribute] }\n assert.debug('create', Post.name, props)\n const post = await adapter.create(Post, props)\n assert.debug('created', Post.name, post)\n\n props = { status: 'published', userId: user[User.idAttribute] }\n assert.debug('create', Post.name, props)\n const post2 = await adapter.create(Post, props)\n assert.debug('created', Post.name, post2)\n\n props = { status: 'draft', userId: user2[User.idAttribute] }\n assert.debug('create', Post.name, props)\n const post3 = await adapter.create(Post, props)\n assert.debug('created', Post.name, post3)\n\n props = { status: 'published', userId: user2[User.idAttribute] }\n assert.debug('create', Post.name, props)\n const post4 = await adapter.create(Post, props)\n assert.debug('created', Post.name, post4)\n\n assert.debug('findAll', User.name, { [User.idAttribute]: user[User.idAttribute] })\n let users = await adapter.findAll(User, { [User.idAttribute]: user[User.idAttribute] }, {'with': ['post']})\n assert.debug('found', User.name, users)\n\n assert.isDefined(users, 'users')\n assert.isDefined(users[0].posts, 'users[0].posts')\n assert.equal(users[0].posts.length, 2, 'users[0].posts.length')\n\n assert.debug('findAll', User.name, { [User.idAttribute]: user[User.idAttribute] })\n users = await adapter.findAll(User, { [User.idAttribute]: user[User.idAttribute] }, {'with': [{\n relation: 'post',\n query: {\n status: 'published'\n }\n }]})\n assert.debug('found', User.name, users)\n\n assert.isDefined(users, 'users')\n assert.isDefined(users[0].posts, 'users[0].posts')\n assert.equal(users[0].posts.length, 1, 'users[0].posts.length')\n\n assert.debug('findAll', User.name, { [User.idAttribute]: user[User.idAttribute] })\n users = await adapter.findAll(User, { [User.idAttribute]: user[User.idAttribute] }, {'with': [{\n relation: 'post',\n replace: true,\n query: {\n status: 'published'\n }\n }]})\n assert.debug('found', User.name, users)\n\n assert.isDefined(user, 'user')\n assert.isDefined(users[0].posts, 'users[0].posts')\n assert.equal(users[0].posts.length, 1, 'users[0].posts.length')\n })\n }\n\n if (options.hasFeature('findAllBelongsToNested')) {\n it('should load belongsTo relations (nested)', async function () {\n this.toClear.push('Post')\n this.toClear.push('Profile')\n this.toClear.push('Comment')\n let props = { name: 'John' }\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n props = { email: 'foo@test.com', userId: user[User.idAttribute] }\n assert.debug('create', Profile.name, props)\n const profile = await adapter.create(Profile, props)\n assert.debug('created', Profile.name, profile)\n\n props = { content: 'foo', userId: user[User.idAttribute] }\n assert.debug('create', Post.name, props)\n const post = await adapter.create(Post, props)\n assert.debug('created', Post.name, post)\n\n props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }\n assert.debug('create', Comment.name, props)\n let comment = await adapter.create(Comment, props)\n assert.debug('created', Comment.name, comment)\n\n props = { name: 'Sally' }\n assert.debug('create', User.name, props)\n const user2 = await adapter.create(User, props)\n assert.debug('created', User.name, user2)\n\n props = { content: 'bar', userId: user2[User.idAttribute] }\n assert.debug('create', Post.name, props)\n const post2 = await adapter.create(Post, props)\n assert.debug('created', Post.name, post2)\n\n props = { content: 'test67', postId: post2[Post.idAttribute], userId: post2.userId }\n assert.debug('create', Comment.name, props)\n let comment2 = await adapter.create(Comment, props)\n assert.debug('created', Comment.name, comment2)\n\n assert.debug('findAll', Comment.name, {})\n const comments = await adapter.findAll(Comment, {}, {'with': ['user', 'user.profile', 'post', 'post.user']})\n assert.debug('found', Comment.name, comments)\n\n assert.isDefined(comments[0].post, 'comments[0].post')\n assert.isDefined(comments[0].post.user, 'comments[0].post.user')\n assert.isDefined(comments[0].user, 'comments[0].user')\n assert.isDefined(comments[0].user.profile || comments[1].user.profile, 'comments[0].user.profile || comments[1].user.profile')\n assert.isDefined(comments[1].post, 'comments[1].post')\n assert.isDefined(comments[1].post.user, 'comments[1].post.user')\n assert.isDefined(comments[1].user, 'comments[1].user')\n })\n }\n\n if (options.hasFeature('findAllBelongsToHasMany')) {\n it('should load hasMany and belongsTo relations', async function () {\n this.toClear.push('Post')\n this.toClear.push('Profile')\n this.toClear.push('Comment')\n let props = { name: 'John' }\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n props = { email: 'foo@test.com', userId: user[User.idAttribute] }\n assert.debug('create', Profile.name, props)\n const profile = await adapter.create(Profile, props)\n assert.debug('created', Profile.name, profile)\n\n props = { content: 'foo', userId: user[User.idAttribute] }\n assert.debug('create', Post.name, props)\n const post = await adapter.create(Post, props)\n assert.debug('created', Post.name, post)\n\n props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }\n assert.debug('create', Comment.name, props)\n let comment = await adapter.create(Comment, props)\n assert.debug('created', Comment.name, comment)\n\n props = { name: 'Sally' }\n assert.debug('create', User.name, props)\n const user2 = await adapter.create(User, props)\n assert.debug('created', User.name, user2)\n\n props = { content: 'bar', userId: user2[User.idAttribute] }\n assert.debug('create', Post.name, props)\n const post2 = await adapter.create(Post, props)\n assert.debug('created', Post.name, post2)\n\n props = { content: 'test67', postId: post2[Post.idAttribute], userId: post2.userId }\n assert.debug('create', Comment.name, props)\n let comment2 = await adapter.create(Comment, props)\n assert.debug('created', Comment.name, comment2)\n\n assert.debug('find', Post.name, {})\n const posts = await adapter.findAll(Post, {}, {'with': ['user', 'comment']})\n assert.debug('found', Post.name, posts)\n\n assert.isDefined(posts[0].comments, 'posts[0].comments')\n assert.isDefined(posts[0].user, 'posts[0].user')\n assert.isDefined(posts[1].comments, 'posts[1].comments')\n assert.isDefined(posts[1].user, 'posts[1].user')\n })\n }\n\n if (options.hasFeature('findAllBelongsToHasManyNested')) {\n it('should load hasMany and belongsTo relations', async function () {\n this.toClear.push('Post')\n this.toClear.push('Profile')\n this.toClear.push('Comment')\n let props = { name: 'John' }\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n props = { email: 'foo@test.com', userId: user[User.idAttribute] }\n assert.debug('create', Profile.name, props)\n const profile = await adapter.create(Profile, props)\n assert.debug('created', Profile.name, profile)\n\n props = { content: 'foo', userId: user[User.idAttribute] }\n assert.debug('create', Post.name, props)\n const post = await adapter.create(Post, props)\n assert.debug('created', Post.name, post)\n\n props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }\n assert.debug('create', Comment.name, props)\n let comment = await adapter.create(Comment, props)\n assert.debug('created', Comment.name, comment)\n\n props = { name: 'Sally' }\n assert.debug('create', User.name, props)\n const user2 = await adapter.create(User, props)\n assert.debug('created', User.name, user2)\n\n props = { content: 'bar', userId: user2[User.idAttribute] }\n assert.debug('create', Post.name, props)\n const post2 = await adapter.create(Post, props)\n assert.debug('created', Post.name, post2)\n\n props = { content: 'test67', postId: post2[Post.idAttribute], userId: post2.userId }\n assert.debug('create', Comment.name, props)\n let comment2 = await adapter.create(Comment, props)\n assert.debug('created', Comment.name, comment2)\n\n assert.debug('find', Post.name, {})\n const posts = await adapter.findAll(Post, {}, {'with': ['user', 'comment', 'comment.user', 'comment.user.profile']})\n assert.debug('found', Post.name, posts)\n\n assert.isDefined(posts[0].comments, 'posts[0].comments')\n assert.isDefined(posts[0].comments[0].user, 'posts[0].comments[0].user')\n assert.isDefined(posts[0].comments[0].user.profile || posts[1].comments[0].user.profile, 'posts[0].comments[0].user.profile || posts[1].comments[0].user.profile')\n assert.isDefined(posts[0].user, 'posts[0].user')\n assert.isDefined(posts[1].comments, 'posts[1].comments')\n assert.isDefined(posts[1].comments[0].user, 'posts[1].comments[0].user')\n assert.isDefined(posts[1].user, 'posts[1].user')\n })\n }\n\n if (options.hasFeature('filterOnRelations')) {\n it('should filter using belongsTo relation', async function () {\n this.toClear.push('Post')\n this.toClear.push('Profile')\n this.toClear.push('Comment')\n var profile1 = await adapter.create(Profile, { email: 'foo@test.com' })\n var user1 = await adapter.create(User, {name: 'John', profileId: profile1.id})\n\n var post1 = await adapter.create(Post, {content: 'foo', userId: user1.id})\n await adapter.create(Comment, {content: 'test1', postId: post1.id, userId: post1.userId})\n\n var user2 = await adapter.create(User, {name: 'Sally'})\n var post2 = await adapter.create(Post, {content: 'bar', userId: user2.id})\n await adapter.create(Comment, {content: 'test2', postId: post2.id, userId: post2.userId})\n\n var users = await adapter.findAll(User, {'profile.email': 'foo@test.com'})\n assert.equal(users.length, 1)\n assert.equal(users[0].profileId, profile1.id)\n assert.equal(users[0].name, 'John')\n })\n\n it('should filter through multiple hasOne/belongsTo relations', async function () {\n this.toClear.push('Post')\n this.toClear.push('Profile')\n this.toClear.push('Comment')\n var profile1 = await adapter.create(Profile, { email: 'foo@test.com' })\n var user1 = await adapter.create(User, {name: 'John', profileId: profile1.id})\n\n var post1 = await adapter.create(Post, {content: 'foo', userId: user1.id})\n await adapter.create(Comment, {content: 'test1', postId: post1.id, userId: post1.userId})\n\n var profile2 = await adapter.create(Profile, { email: 'bar@test.com' })\n var user2 = await adapter.create(User, {name: 'Sally', profileId: profile2.id})\n var post2 = await adapter.create(Post, {content: 'bar', userId: user2.id})\n await adapter.create(Comment, {content: 'test2', postId: post2.id, userId: post2.userId})\n\n var comments = await adapter.findAll(Comment, { 'user.profile.email': 'foo@test.com' })\n assert.equal(comments.length, 1)\n assert.equal(comments[0].userId, user1.id)\n assert.equal(comments[0].content, 'test1')\n })\n\n it('should filter using multiple hasOne/belongsTo relations', async function () {\n this.toClear.push('Post')\n this.toClear.push('Profile')\n this.toClear.push('Comment')\n var profile1 = await adapter.create(Profile, { email: 'foo@test.com' })\n var user1 = await adapter.create(User, {name: 'John', profileId: profile1.id})\n\n var post1 = await adapter.create(Post, {content: 'foo', userId: user1.id})\n await adapter.create(Comment, {content: 'test1', postId: post1.id, userId: post1.userId})\n\n var profile2 = await adapter.create(Profile, { email: 'bar@test.com' })\n var user2 = await adapter.create(User, {name: 'Sally', profileId: profile2.id})\n var post2 = await adapter.create(Post, {content: 'bar', userId: user2.id})\n await adapter.create(Comment, {content: 'test2', postId: post2.id, userId: post2.userId})\n\n var comments = await adapter.findAll(Comment, { 'user.name': 'John', 'user.profile.email': 'foo@test.com' })\n assert.equal(comments.length, 1)\n assert.equal(comments[0].userId, user1.id)\n assert.equal(comments[0].content, 'test1')\n })\n }\n\n it('should allow passing limit and offset as strings', async function () {\n await adapter.findAll(User, { limit: '10', offset: '20' })\n })\n\n if (options.hasFeature('findAllGroupedWhere')) {\n it('should support filtering grouped \"where\" clauses', async function () {\n this.toClear.push('Post')\n const posts = await adapter.createMany(Post, [\n { status: 'draft', content: 'foo' },\n { status: 'broken', content: 'bar' },\n { status: 'published', content: 'hi' },\n { status: 'flagged', content: 'hello world' },\n { status: 'flagged', content: 'test' }\n ])\n\n let query = {\n where: [\n [\n {\n content: {\n '=': 'foo'\n },\n status: {\n '=': 'draft'\n }\n },\n 'or',\n {\n status: {\n '=': 'published'\n }\n }\n ],\n 'or',\n {\n content: {\n '=': 'test'\n },\n status: {\n '=': 'flagged'\n }\n }\n ],\n orderBy: 'status'\n }\n\n assert.objectsEqual(await adapter.findAll(Post, query), [posts[0], posts[4], posts[2]])\n })\n }\n })\n}\n","/* global assert:true */\nexport default function (options) {\n describe('Adapter#sum', function () {\n it('should exist', function () {\n assert.equal(typeof this.$$adapter.sum, 'function', 'adapter should have a \"sum\" method')\n })\n it('should sum users\\' age', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John', age: 30 }\n\n assert.debug('sum', User.name, {})\n let sum = await adapter.sum(User, 'age')\n assert.debug('summed', User.name, sum)\n assert.equal(sum, 0)\n\n assert.debug('sum', User.name, { name: 'John' })\n sum = await adapter.sum(User, 'age', { name: 'John' })\n assert.debug('summed', User.name, sum)\n assert.equal(sum, 0)\n\n assert.debug('sum', User.name, { name: 'Sally' })\n sum = await adapter.sum(User, 'age', { name: 'Sally' })\n assert.debug('summed', User.name, sum)\n assert.equal(sum, 0)\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n assert.debug('sum', User.name, {})\n sum = await adapter.sum(User, 'age')\n assert.debug('summed', User.name, sum)\n assert.equal(sum, 30)\n\n assert.debug('sum', User.name, { name: 'John' })\n sum = await adapter.sum(User, 'age', { name: 'John' })\n assert.debug('summed', User.name, sum)\n assert.equal(sum, 30)\n\n assert.debug('sum', User.name, { name: 'Sally' })\n sum = await adapter.sum(User, 'age', { name: 'Sally' })\n assert.debug('summed', User.name, sum)\n assert.equal(sum, 0)\n\n assert.debug('create', User.name, { name: 'Sally' })\n const user2 = await adapter.create(User, { name: 'Sally', age: 27 })\n assert.debug('created', User.name, user2)\n\n assert.debug('sum', User.name, {})\n sum = await adapter.sum(User, 'age')\n assert.debug('summed', User.name, sum)\n assert.equal(sum, 57)\n\n assert.debug('sum', User.name, { name: 'John' })\n sum = await adapter.sum(User, 'age', { name: 'John' })\n assert.debug('summed', User.name, sum)\n assert.equal(sum, 30)\n\n assert.debug('sum', User.name, { name: 'Sally' })\n sum = await adapter.sum(User, 'age', { name: 'Sally' })\n assert.debug('summed', User.name, sum)\n assert.equal(sum, 27)\n })\n it('should sum users\\' age and return raw', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John', age: 30 }\n\n assert.debug('create', User.name, props)\n let user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n assert.debug('sum', User.name, props)\n const result = await adapter.sum(User, 'age', props, { raw: true })\n assert.debug('summed', User.name, result)\n assert.equal(result.data, 30, 'result.data')\n })\n })\n}\n","/* global assert:true */\nexport default function (options) {\n describe('Adapter#update', function () {\n it('should exist', function () {\n assert.equal(typeof this.$$adapter.update, 'function', 'adapter should have a \"update\" method')\n })\n it('should update a user', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n assert.equal(user.name, props.name, `name of user should be \"${props.name}\"`)\n assert.isDefined(user[User.idAttribute], 'new user should have an id')\n\n assert.debug('find', User.name, user[User.idAttribute])\n let foundUser = await adapter.find(User, user[User.idAttribute])\n assert.debug('found', User.name, foundUser)\n\n assert.equal(foundUser.name, props.name, `name of user should be \"${props.name}\"`)\n assert.isDefined(foundUser[User.idAttribute], 'new user should have an id')\n assert.equal(foundUser[User.idAttribute], user[User.idAttribute])\n\n assert.debug('update', User.name, user[User.idAttribute], { name: 'Johnny' })\n let updatedUser = await adapter.update(User, user[User.idAttribute], { name: 'Johnny' })\n assert.debug('updated', User.name, updatedUser)\n assert.equal(updatedUser.name, 'Johnny')\n assert.equal(updatedUser[User.idAttribute], user[User.idAttribute])\n\n assert.debug('find', User.name, user[User.idAttribute])\n foundUser = await adapter.find(User, user[User.idAttribute])\n assert.debug('found', User.name, foundUser)\n assert.equal(foundUser.name, 'Johnny')\n assert.equal(foundUser[User.idAttribute], user[User.idAttribute])\n })\n it('should update a user and return raw', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n const props = { name: 'John' }\n\n assert.debug('create', User.name, props)\n const user = await adapter.create(User, props)\n assert.debug('created', User.name, user)\n\n assert.equal(user.name, props.name, `name of user should be \"${props.name}\"`)\n assert.isDefined(user[User.idAttribute], 'new user should have an id')\n\n assert.debug('update', User.name, user[User.idAttribute], { name: 'Johnny' })\n const result = await adapter.update(User, user[User.idAttribute], { name: 'Johnny' }, { raw: true })\n assert.debug('updated', User.name, result)\n assert.isDefined(result.data, 'result.data is defined')\n assert.isDefined(result.updated, 'result.updated is defined')\n assert.equal(result.data.name, 'Johnny', 'result.data.name should be \"Johnny\"')\n assert.equal(result.data[User.idAttribute], user[User.idAttribute], `result.data.${User.idAttribute} should be ${user[User.idAttribute]}`)\n assert.equal(result.updated, 1, 'result.updated should be 1')\n })\n it('should throw when updating non-existent row', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n\n assert.debug('update', 'non-existent-id', { name: 'Johnny' })\n try {\n await adapter.update(User, 'non-existent-id', { name: 'Johnny' })\n throw new Error('update should have failed!')\n } catch (err) {\n assert.debug('correctly threw error', err.message)\n assert.isDefined(err.message, 'err.message is defined')\n assert.equal(err.message, 'Not Found', 'err.message should be \"Not Found\"')\n }\n })\n it('should keep relations specified by \"with\"', async function () {\n const adapter = this.$$adapter\n const store = this.$$container\n\n sinon.stub(adapter, '_update').callsFake(function (mapper, id, props, opts) {\n assert.deepEqual(props.posts, [\n {\n id: 1234,\n userId: 1\n }\n ])\n assert.deepEqual(props.profile, {\n id: 238,\n userId: 1\n })\n assert.equal(props.address, undefined)\n assert.equal(props.organization, undefined)\n return [props, {}]\n })\n\n assert.debug('update', 1, { id: 1 })\n const result = await store.update('user', 1, {\n id: 1,\n posts: [\n {\n id: 1234,\n userId: 1\n }\n ],\n address: {\n id: 412,\n userId: 1\n },\n profile: {\n id: 238,\n userId: 1\n },\n organizationId: 333,\n organization: {\n id: 333\n }\n }, { with: ['posts', 'profile'] })\n assert.debug('updated', 1, result)\n adapter._update.restore()\n })\n })\n}\n","/* global assert:true */\nexport default function (options) {\n describe('Adapter#updateAll', function () {\n it('should exist', function () {\n assert.equal(typeof this.$$adapter.updateAll, 'function', 'adapter should have a \"updateAll\" method')\n })\n it('should update multiple users', async function () {\n const adapter = this.$$adapter\n const User = this.$$User\n let props = { name: 'John', age: 20 }\n\n assert.debug('create', User.name, props)\n const user1 = await adapter.create(User, props)\n assert.debug('created', User.name, user1)\n const userId1 = user1[User.idAttribute]\n\n props = { name: 'John', age: 30 }\n\n assert.debug('create', User.name, props)\n const user2 = await adapter.create(User, props)\n assert.debug('created', User.name, user2)\n const userId2 = user2[User.idAttribute]\n\n assert.debug('findAll', User.name, { name: 'John' })\n const users = await adapter.findAll(User, { name: 'John' })\n assert.debug('found', User.name, users)\n users.sort(function (a, b) {\n return a.age - b.age\n })\n assert.equal(users[0].name, 'John')\n assert.equal(users[0].name, 'John')\n assert.equal(users.filter(function (x) { return x[User.idAttribute] === userId1 }).length, 1)\n assert.equal(users.filter(function (x) { return x[User.idAttribute] === userId2 }).length, 1)\n assert.equal(users.filter(function (x) { return x.age === 20 }).length, 1)\n assert.equal(users.filter(function (x) { return x.age === 30 }).length, 1)\n\n assert.debug('updateAll', User.name, { name: 'Johnny' }, { name: 'John' })\n const users2 = await adapter.updateAll(User, { name: 'Johnny' }, { name: 'John' })\n assert.debug('updated', User.name, users2)\n users2.sort(function (a, b) {\n return a.age - b.age\n })\n assert.equal(users2[0].name, 'Johnny')\n assert.equal(users2[0].name, 'Johnny')\n assert.equal(users2.filter(function (x) { return x[User.idAttribute] === userId1 }).length, 1)\n assert.equal(users2.filter(function (x) { return x[User.idAttribute] === userId2 }).length, 1)\n assert.equal(users2.filter(function (x) { return x.age === 20 }).length, 1)\n assert.equal(users2.filter(function (x) { return x.age === 30 }).length, 1)\n\n assert.debug('findAll', User.name, { name: 'John' })\n const users3 = await adapter.findAll(User, { name: 'John' })\n assert.debug('found', User.name, users3)\n assert.equalObjects(users3, [])\n assert.equal(users3.length, 0)\n\n assert.debug('findAll', User.name, { name: 'Johnny' })\n const users4 = await adapter.findAll(User, { name: 'Johnny' })\n assert.debug('found', User.name, users4)\n\n users4.sort(function (a, b) {\n return a.age - b.age\n })\n assert.equal(users4[0].name, 'Johnny')\n assert.equal(users4[0].name, 'Johnny')\n assert.equal(users4.filter(function (x) { return x[User.idAttribute] === userId1 }).length, 1)\n assert.equal(users4.filter(function (x) { return x[User.idAttribute] === userId2 }).length, 1)\n assert.equal(users4.filter(function (x) { return x.age === 20 }).length, 1)\n assert.equal(users4.filter(function (x) { return x.age === 30 }).length, 1)\n })\n })\n}\n","/* global assert:true */\nexport default function (options) {\n describe('Adapter#updateMany', function () {\n it('should exist', function () {\n assert.equal(typeof this.$$adapter.updateMany, 'function', 'adapter should have a \"updateMany\" method')\n })\n it('should update multiple users', async function () {\n var adapter = this.$$adapter\n var User = this.$$User\n var user1 = await adapter.create(User, {name: 'John', age: 20})\n var userId1 = user1.id\n\n var user2 = await adapter.create(User, {name: 'John', age: 30})\n var userId2 = user2.id\n\n var users = await adapter.findAll(User, { name: 'John' })\n users.sort(function (a, b) {\n return a.age - b.age\n })\n assert.equal(users[0].name, 'John')\n assert.equal(users[0].name, 'John')\n assert.equal(users.filter(function (x) { return x.id === userId1 }).length, 1)\n assert.equal(users.filter(function (x) { return x.id === userId2 }).length, 1)\n assert.equal(users.filter(function (x) { return x.age === 20 }).length, 1)\n assert.equal(users.filter(function (x) { return x.age === 30 }).length, 1)\n\n user1.age = 101\n user2.age = 202\n var users2 = await adapter.updateMany(User, [user1, user2])\n users2.sort(function (a, b) {\n return a.age - b.age\n })\n assert.equal(users2.filter(function (x) { return x.id === userId1 }).length, 1)\n assert.equal(users2.filter(function (x) { return x.id === userId2 }).length, 1)\n assert.equal(users2.filter(function (x) { return x.age === 101 }).length, 1)\n assert.equal(users2.filter(function (x) { return x.age === 202 }).length, 1)\n\n var users3 = await adapter.findAll(User, { age: 20 })\n assert.objectsEqual(users3, [])\n assert.equal(users3.length, 0)\n\n var users4 = await adapter.findAll(User, { age: 101 })\n users4.sort(function (a, b) {\n return a.age - b.age\n })\n assert.equal(users4.filter(function (x) { return x.id === userId1 }).length, 1)\n assert.equal(users4.filter(function (x) { return x.id === userId2 }).length, 0)\n assert.equal(users4.filter(function (x) { return x.age === 101 }).length, 1)\n assert.equal(users4.filter(function (x) { return x.age === 202 }).length, 0)\n })\n })\n}\n","import afterCreateTest from './afterCreate.test'\nimport afterUpdateTest from './afterUpdate.test'\nimport beforeCreateTest from './beforeCreate.test'\nimport beforeUpdateTest from './beforeUpdate.test'\nimport countTest from './count.test'\nimport createTest from './create.test'\nimport createManyTest from './createMany.test'\nimport destroyTest from './destroy.test'\nimport destroyAllTest from './destroyAll.test'\nimport extendTest from './extend.test'\nimport findTest from './find.test'\nimport findAllTest from './findAll.test'\nimport sumTest from './sum.test'\nimport updateTest from './update.test'\nimport updateAllTest from './updateAll.test'\nimport updateManyTest from './updateMany.test'\n\nimport {assert} from 'chai'\nimport sinon from 'sinon'\n\nassert.equalObjects = function (a, b, m) {\n assert.deepEqual(JSON.parse(JSON.stringify(a)), JSON.parse(JSON.stringify(b)), m || (JSON.stringify(a) + ' should be equal to ' + JSON.stringify(b)))\n}\n\nassert.objectsEqual = function (a, b, m) {\n assert.deepEqual(JSON.parse(JSON.stringify(a)), JSON.parse(JSON.stringify(b)), m || (JSON.stringify(a) + ' should be equal to ' + JSON.stringify(b)))\n}\n\nlet debug = false\n\nassert.debug = function (...args) {\n if (debug) {\n args.forEach(function (arg, i) {\n args[i] = JSON.stringify(arg, null, 2)\n })\n console.log('DEBUG (TEST):', ...args)\n }\n}\n\nvar prefix = 'TestRunner.init(options): options'\n\nexport default {\n init: function (options) {\n options = options || {}\n debug = !!options.debug\n options.hasMethod = function (method) {\n options.methods || (options.methods = 'all')\n options.xmethods || (options.xmethods = [])\n return (options.methods === 'all' || options.methods.indexOf(method) !== -1) && options.xmethods.indexOf(method) === -1\n }\n options.hasFeature = function (feature) {\n options.features || (options.features = 'all')\n options.xfeatures || (options.xfeatures = [])\n return (options.features === 'all' || options.features.indexOf(feature) !== -1) && options.xfeatures.indexOf(feature) === -1\n }\n if (!options.Adapter || typeof options.Adapter !== 'function') {\n throw new Error(prefix + '.Adapter: Expected function, Actual: ' + typeof options.Adapter)\n }\n beforeEach(function () {\n this.$$adapter = new options.Adapter(options.adapterConfig)\n this.$$container = new options.JSData.Container(options.containerConfig || {\n mapperDefaults: {\n debug: false\n }\n })\n this.$$store = new options.JSData.DataStore(options.storeConfig || {\n mapperDefaults: {\n debug: false\n }\n })\n this.$$container.registerAdapter('adapter', this.$$adapter, { 'default': true })\n this.$$store.registerAdapter('adapter', this.$$adapter, { 'default': true })\n var userOptions = {\n name: 'user',\n relations: {\n hasMany: {\n post: {\n localField: 'posts',\n foreignKey: 'userId'\n }\n },\n hasOne: {\n profile: {\n localField: 'profile',\n foreignKey: 'userId'\n },\n address: {\n localField: 'address',\n foreignKey: 'userId'\n }\n },\n belongsTo: {\n organization: {\n localField: 'organization',\n foreignKey: 'organizationId'\n }\n }\n }\n }\n var organizationOptions = {\n name: 'organization',\n relations: {\n hasMany: {\n user: {\n localField: 'users',\n foreignKey: 'organizationId'\n }\n }\n }\n }\n var postOptions = {\n name: 'post',\n relations: {\n belongsTo: {\n user: {\n localField: 'user',\n foreignKey: 'userId'\n }\n },\n hasMany: {\n comment: {\n localField: 'comments',\n foreignKey: 'postId'\n },\n tag: {\n localField: 'tags',\n localKeys: 'tagIds'\n }\n }\n }\n }\n var commentOptions = {\n name: 'comment',\n relations: {\n belongsTo: {\n post: {\n localField: 'post',\n foreignKey: 'postId'\n },\n user: {\n localField: 'user',\n foreignKey: 'userId'\n }\n }\n }\n }\n var tagOptions = {\n name: 'tag',\n relations: {\n hasMany: {\n post: {\n localField: 'posts',\n foreignKeys: 'tagIds'\n }\n }\n }\n }\n this.$$User = this.$$container.defineMapper('user', options.userConfig || options.JSData.utils.copy(userOptions))\n this.$$store.defineMapper('user', options.userConfig || options.JSData.utils.copy(userOptions))\n this.$$Organization = this.$$container.defineMapper('organization', options.organizationConfig || options.JSData.utils.copy(organizationOptions))\n this.$$store.defineMapper('organization', options.organizationConfig || options.JSData.utils.copy(organizationOptions))\n this.$$Profile = this.$$container.defineMapper('profile', options.profileConfig || {})\n this.$$store.defineMapper('profile', options.profileConfig || {})\n this.$$Address = this.$$container.defineMapper('address', options.addressConfig || {})\n this.$$store.defineMapper('address', options.addressConfig || {})\n this.$$Post = this.$$container.defineMapper('post', options.postConfig || options.JSData.utils.copy(postOptions))\n this.$$store.defineMapper('post', options.postConfig || options.JSData.utils.copy(postOptions))\n this.$$Comment = this.$$container.defineMapper('comment', options.commentConfig || options.JSData.utils.copy(commentOptions))\n this.$$store.defineMapper('comment', options.commentConfig || options.JSData.utils.copy(commentOptions))\n this.$$Tag = this.$$container.defineMapper('tag', options.tagConfig || options.JSData.utils.copy(tagOptions))\n this.$$store.defineMapper('tag', options.tagConfig || options.JSData.utils.copy(tagOptions))\n this.toClear = ['User']\n })\n\n describe('js-data-adapter-tests', function () {\n if (options.hasMethod('beforeCreate')) {\n beforeCreateTest(options)\n }\n if (options.hasMethod('count')) {\n countTest(options)\n }\n if (options.hasMethod('create')) {\n createTest(options)\n }\n if (options.hasMethod('afterCreate')) {\n afterCreateTest(options)\n }\n if (options.hasMethod('createMany')) {\n createManyTest(options)\n }\n if (options.hasMethod('extend')) {\n extendTest(options)\n }\n if (options.hasMethod('find')) {\n findTest(options)\n }\n if (options.hasMethod('findAll')) {\n findAllTest(options)\n }\n if (options.hasMethod('destroy')) {\n destroyTest(options)\n }\n if (options.hasMethod('destroyAll')) {\n destroyAllTest(options)\n }\n if (options.hasMethod('beforeUpdate')) {\n beforeUpdateTest(options)\n }\n if (options.hasMethod('sum')) {\n sumTest(options)\n }\n if (options.hasMethod('update')) {\n updateTest(options)\n }\n if (options.hasMethod('afterUpdate')) {\n afterUpdateTest(options)\n }\n if (options.hasMethod('updateAll')) {\n updateAllTest(options)\n }\n if (options.hasMethod('updateMany')) {\n updateManyTest(options)\n }\n })\n\n afterEach(async function () {\n const Test = this\n const toClear = []\n if (Test.toClear.indexOf('Tag') !== -1) {\n toClear.push('Tag')\n }\n if (Test.toClear.indexOf('Comment') !== -1) {\n toClear.push('Comment')\n }\n if (Test.toClear.indexOf('Post') !== -1) {\n toClear.push('Post')\n }\n if (Test.toClear.indexOf('Profile') !== -1) {\n toClear.push('Profile')\n }\n if (Test.toClear.indexOf('User') !== -1) {\n toClear.push('User')\n }\n if (Test.toClear.indexOf('Address') !== -1) {\n toClear.push('Address')\n }\n let promise = Promise.resolve()\n toClear.forEach(function (Mapper) {\n promise = promise.then(function () {\n return Test.$$adapter.destroyAll(Test['$$' + Mapper])\n })\n })\n await promise\n })\n },\n assert,\n sinon,\n fail: function (msg) {\n assert.equal('should not reach this!: ' + msg, 'failure')\n },\n TYPES_EXCEPT_STRING: [123, 123.123, null, undefined, {}, [], true, false, function () {\n }],\n TYPES_EXCEPT_STRING_OR_ARRAY: [123, 123.123, null, undefined, {}, true, false, function () {\n }],\n TYPES_EXCEPT_STRING_OR_NUMBER: [null, undefined, {}, [], true, false, function () {\n }],\n TYPES_EXCEPT_STRING_OR_OBJECT: [123, 123.123, null, undefined, [], true, false, function () {\n }],\n TYPES_EXCEPT_STRING_OR_NUMBER_OBJECT: [null, undefined, [], true, false, function () {\n }],\n TYPES_EXCEPT_STRING_OR_ARRAY_OR_NUMBER: [null, undefined, {}, true, false, function () {\n }],\n TYPES_EXCEPT_NUMBER: ['string', null, undefined, {}, [], true, false, function () {\n }],\n TYPES_EXCEPT_OBJECT: ['string', 123, 123.123, null, undefined, true, false, function () {\n }],\n TYPES_EXCEPT_BOOLEAN: ['string', 123, 123.123, null, undefined, {}, [], function () {\n }],\n TYPES_EXCEPT_FUNCTION: ['string', 123, 123.123, null, undefined, {}, [], true, false]\n}\n"],"names":["options","equal","$$adapter","afterCreate","$$User","name","stub","adapter","callsFake","mapper","props","opts","isDefined","op","debug","User","create","user","idAttribute","isTrue","calledOnce","firstCall","args","length","objectsEqual","isObject","restore","record","Promise","resolve","raw","result","created","data","afterUpdate","id","userId","update","updatedUser","updated","beforeCreate","beforeUpdate","count","user2","find","foundUser","createMany","age","user1","users","sort","a","b","filter","x","findAll","users3","destroy","beforeDestroy","afterDestroy","destroyedUser","isUndefined","beforeDestroyCalled","afterDestroyCalled","hasOwnProperty","deleted","destroyAll","foundUsers","destroyedUsers","constructor","extend","Adapter","SubAdapter","bar","err","subAdapter","foo","obj","setPrototypeOf","Profile","Post","Comment","Tag","$$Profile","$$Post","$$Comment","$$Tag","toClear","push","beforeFind","afterFind","beforeFindCalled","afterFindCalled","content","post","all","comments","postId","with","foundPost","equalObjects","found","email","profile","comment","status","post2","post3","post4","posts","hasFeature","value","tag","tag2","tagIds","tags","deepEqual","tagId","tag2Id","users2","result2","then","Error","message","comment2","profileId","profile1","post1","profile2","limit","offset","assert","query","sum","$$container","address","undefined","organization","store","_update","updateAll","userId1","userId2","users4","updateMany","m","JSON","parse","stringify","forEach","arg","i","log","prefix","hasMethod","method","methods","xmethods","indexOf","feature","features","xfeatures","adapterConfig","JSData","Container","containerConfig","$$store","DataStore","storeConfig","registerAdapter","userOptions","organizationOptions","postOptions","commentOptions","tagOptions","defineMapper","userConfig","utils","copy","$$Organization","organizationConfig","profileConfig","$$Address","addressConfig","postConfig","commentConfig","tagConfig","Test","Mapper","promise","msg"],"mappings":"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"} \ No newline at end of file diff --git a/dist/js-data-adapter.js b/dist/js-data-adapter.js new file mode 100644 index 0000000..54fa5c7 --- /dev/null +++ b/dist/js-data-adapter.js @@ -0,0 +1,1623 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('js-data')) : + typeof define === 'function' && define.amd ? define('js-data-adapter', ['exports', 'js-data'], factory) : + (factory((global.Adapter = global.Adapter || {}),global.JSData)); +}(this, (function (exports,jsData) { 'use strict'; + +var defineProperty = function (obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; +}; + + + + + + + + + + + + + + + + + + + + + +var slicedToArray = function () { + function sliceIterator(arr, i) { + var _arr = []; + var _n = true; + var _d = false; + var _e = undefined; + + try { + for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"]) _i["return"](); + } finally { + if (_d) throw _e; + } + } + + return _arr; + } + + return function (arr, i) { + if (Array.isArray(arr)) { + return arr; + } else if (Symbol.iterator in Object(arr)) { + return sliceIterator(arr, i); + } else { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); + } + }; +}(); + +var noop = function noop() { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + var opts = args[args.length - 1]; + this.dbg.apply(this, [opts.op].concat(args)); + return jsData.utils.resolve(); +}; + +var noop2 = function noop2() { + for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + var opts = args[args.length - 2]; + this.dbg.apply(this, [opts.op].concat(args)); + return jsData.utils.resolve(); +}; + +var unique = function unique(array) { + var seen = {}; + var final = []; + array.forEach(function (item) { + if (item in seen) { + return; + } + final.push(item); + seen[item] = 0; + }); + return final; +}; + +var withoutRelations = function withoutRelations(mapper, props, opts) { + opts || (opts = {}); + opts.with || (opts.with = []); + var relationFields = mapper.relationFields || []; + var toStrip = relationFields.filter(function (value) { + return opts.with.indexOf(value) === -1; + }); + return jsData.utils.omit(props, toStrip); +}; + +var reserved = ['orderBy', 'sort', 'limit', 'offset', 'skip', 'where']; + +/** + * Response object used when `raw` is `true`. May contain other fields in + * addition to `data`. + * + * @class Response + */ +function Response(data, meta, op) { + meta || (meta = {}); + + /** + * Response data. + * + * @name Response#data + * @type {*} + */ + this.data = data; + + jsData.utils.fillIn(this, meta); + + /** + * The operation for which the response was created. + * + * @name Response#op + * @type {string} + */ + this.op = op; +} + +var DEFAULTS = { + /** + * Whether to log debugging information. + * + * @name Adapter#debug + * @type {boolean} + * @default false + */ + debug: false, + + /** + * Whether to return a more detailed response object. + * + * @name Adapter#raw + * @type {boolean} + * @default false + */ + raw: false + + /** + * Abstract class meant to be extended by adapters. + * + * @class Adapter + * @abstract + * @extends Component + * @param {Object} [opts] Configuration opts. + * @param {boolean} [opts.debug=false] Whether to log debugging information. + * @param {boolean} [opts.raw=false] Whether to return a more detailed response + * object. + */ +};function Adapter(opts) { + jsData.utils.classCallCheck(this, Adapter); + jsData.Component.call(this, opts); + opts || (opts = {}); + jsData.utils.fillIn(opts, DEFAULTS); + jsData.utils.fillIn(this, opts); +} + +jsData.Component.extend({ + constructor: Adapter, + + /** + * Lifecycle method method called by count. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes count to wait for the Promise to resolve before continuing. + * + * If `opts.raw` is `true` then `response` will be a detailed response object, otherwise `response` will be the count. + * + * `response` may be modified. You can also re-assign `response` to another value by returning a different value or a Promise that resolves to a different value. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by count. + * + * @name Adapter#afterCount + * @method + * @param {Object} mapper The `mapper` argument passed to count. + * @param {Object} props The `props` argument passed to count. + * @param {Object} opts The `opts` argument passed to count. + * @property {string} opts.op `afterCount` + * @param {Object|Response} response Count or {@link Response}, depending on the value of `opts.raw`. + */ + afterCount: noop2, + + /** + * Lifecycle method method called by create. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes create to wait for the Promise to resolve before continuing. + * + * If `opts.raw` is `true` then `response` will be a detailed response object, otherwise `response` will be the created record. + * + * `response` may be modified. You can also re-assign `response` to another value by returning a different value or a Promise that resolves to a different value. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by create. + * + * @name Adapter#afterCreate + * @method + * @param {Object} mapper The `mapper` argument passed to create. + * @param {Object} props The `props` argument passed to create. + * @param {Object} opts The `opts` argument passed to create. + * @property {string} opts.op `afterCreate` + * @param {Object|Response} response Created record or {@link Response}, depending on the value of `opts.raw`. + */ + afterCreate: noop2, + + /** + * Lifecycle method method called by createMany. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes createMany to wait for the Promise to resolve before continuing. + * + * If `opts.raw` is `true` then `response` will be a detailed response object, otherwise `response` will be the created records. + * + * `response` may be modified. You can also re-assign `response` to another value by returning a different value or a Promise that resolves to a different value. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by createMany. + * + * @name Adapter#afterCreate + * @method + * @param {Object} mapper The `mapper` argument passed to createMany. + * @param {Object[]} props The `props` argument passed to createMany. + * @param {Object} opts The `opts` argument passed to createMany. + * @property {string} opts.op `afterCreateMany` + * @param {Object[]|Response} response Created records or {@link Response}, depending on the value of `opts.raw`. + */ + afterCreateMany: noop2, + + /** + * Lifecycle method method called by destroy. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes destroy to wait for the Promise to resolve before continuing. + * + * If `opts.raw` is `true` then `response` will be a detailed response object, otherwise `response` will be `undefined`. + * + * `response` may be modified. You can also re-assign `response` to another value by returning a different value or a Promise that resolves to a different value. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by destroy. + * + * @name Adapter#afterDestroy + * @method + * @param {Object} mapper The `mapper` argument passed to destroy. + * @param {(string|number)} id The `id` argument passed to destroy. + * @param {Object} opts The `opts` argument passed to destroy. + * @property {string} opts.op `afterDestroy` + * @param {undefined|Response} response `undefined` or {@link Response}, depending on the value of `opts.raw`. + */ + afterDestroy: noop2, + + /** + * Lifecycle method method called by destroyAll. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes destroyAll to wait for the Promise to resolve before continuing. + * + * If `opts.raw` is `true` then `response` will be a detailed response object, otherwise `response` will be `undefined`. + * + * `response` may be modified. You can also re-assign `response` to another value by returning a different value or a Promise that resolves to a different value. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by destroyAll. + * + * @name Adapter#afterDestroyAll + * @method + * @param {Object} mapper The `mapper` argument passed to destroyAll. + * @param {Object} query The `query` argument passed to destroyAll. + * @param {Object} opts The `opts` argument passed to destroyAll. + * @property {string} opts.op `afterDestroyAll` + * @param {undefined|Response} response `undefined` or {@link Response}, depending on the value of `opts.raw`. + */ + afterDestroyAll: noop2, + + /** + * Lifecycle method method called by find. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes find to wait for the Promise to resolve before continuing. + * + * If `opts.raw` is `true` then `response` will be a detailed response object, otherwise `response` will be the found record, if any. + * + * `response` may be modified. You can also re-assign `response` to another value by returning a different value or a Promise that resolves to a different value. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by find. + * + * @name Adapter#afterFind + * @method + * @param {Object} mapper The `mapper` argument passed to find. + * @param {(string|number)} id The `id` argument passed to find. + * @param {Object} opts The `opts` argument passed to find. + * @property {string} opts.op `afterFind` + * @param {Object|Response} response The found record or {@link Response}, depending on the value of `opts.raw`. + */ + afterFind: noop2, + + /** + * Lifecycle method method called by findAll. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes findAll to wait for the Promise to resolve before continuing. + * + * If `opts.raw` is `true` then `response` will be a detailed response object, otherwise `response` will be the found records, if any. + * + * `response` may be modified. You can also re-assign `response` to another value by returning a different value or a Promise that resolves to a different value. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by findAll. + * + * @name Adapter#afterFindAll + * @method + * @param {Object} mapper The `mapper` argument passed to findAll. + * @param {Object} query The `query` argument passed to findAll. + * @param {Object} opts The `opts` argument passed to findAll. + * @property {string} opts.op `afterFindAll` + * @param {Object[]|Response} response The found records or {@link Response}, depending on the value of `opts.raw`. + */ + afterFindAll: noop2, + + /** + * Lifecycle method method called by sum. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes sum to wait for the Promise to resolve before continuing. + * + * If `opts.raw` is `true` then `response` will be a detailed response object, otherwise `response` will be the sum. + * + * `response` may be modified. You can also re-assign `response` to another value by returning a different value or a Promise that resolves to a different value. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by sum. + * + * @name Adapter#afterSum + * @method + * @param {Object} mapper The `mapper` argument passed to sum. + * @param {string} field The `field` argument passed to sum. + * @param {Object} query The `query` argument passed to sum. + * @param {Object} opts The `opts` argument passed to sum. + * @property {string} opts.op `afterSum` + * @param {Object|Response} response Count or {@link Response}, depending on the value of `opts.raw`. + */ + afterSum: noop2, + + /** + * Lifecycle method method called by update. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes update to wait for the Promise to resolve before continuing. + * + * If `opts.raw` is `true` then `response` will be a detailed response object, otherwise `response` will be the updated record. + * + * `response` may be modified. You can also re-assign `response` to another value by returning a different value or a Promise that resolves to a different value. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by update. + * + * @name Adapter#afterUpdate + * @method + * @param {Object} mapper The `mapper` argument passed to update. + * @param {(string|number)} id The `id` argument passed to update. + * @param {Object} props The `props` argument passed to update. + * @param {Object} opts The `opts` argument passed to update. + * @property {string} opts.op `afterUpdate` + * @param {Object|Response} response The updated record or {@link Response}, depending on the value of `opts.raw`. + */ + afterUpdate: noop2, + + /** + * Lifecycle method method called by updateAll. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes updateAll to wait for the Promise to resolve before continuing. + * + * If `opts.raw` is `true` then `response` will be a detailed response object, otherwise `response` will be the updated records, if any. + * + * `response` may be modified. You can also re-assign `response` to another value by returning a different value or a Promise that resolves to a different value. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by updateAll. + * + * @name Adapter#afterUpdateAll + * @method + * @param {Object} mapper The `mapper` argument passed to updateAll. + * @param {Object} props The `props` argument passed to updateAll. + * @param {Object} query The `query` argument passed to updateAll. + * @param {Object} opts The `opts` argument passed to updateAll. + * @property {string} opts.op `afterUpdateAll` + * @param {Object[]|Response} response The updated records or {@link Response}, depending on the value of `opts.raw`. + */ + afterUpdateAll: noop2, + + /** + * Lifecycle method method called by updateMany. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes updateMany to wait for the Promise to resolve before continuing. + * + * If `opts.raw` is `true` then `response` will be a detailed response object, otherwise `response` will be the updated records, if any. + * + * `response` may be modified. You can also re-assign `response` to another value by returning a different value or a Promise that resolves to a different value. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by updateMany. + * + * @name Adapter#afterUpdateMany + * @method + * @param {Object} mapper The `mapper` argument passed to updateMany. + * @param {Object[]} records The `records` argument passed to updateMany. + * @param {Object} opts The `opts` argument passed to updateMany. + * @property {string} opts.op `afterUpdateMany` + * @param {Object[]|Response} response The updated records or {@link Response}, depending on the value of `opts.raw`. + */ + afterUpdateMany: noop2, + + /** + * Lifecycle method method called by count. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes count to wait for the Promise to resolve before continuing. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by count. + * + * @name Adapter#beforeCount + * @method + * @param {Object} mapper The `mapper` argument passed to count. + * @param {Object} query The `query` argument passed to count. + * @param {Object} opts The `opts` argument passed to count. + * @property {string} opts.op `beforeCount` + */ + beforeCount: noop, + + /** + * Lifecycle method method called by create. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes create to wait for the Promise to resolve before continuing. + * + * `props` may be modified. You can also re-assign `props` to another value by returning a different value or a Promise that resolves to a different value. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by create. + * + * @name Adapter#beforeCreate + * @method + * @param {Object} mapper The `mapper` argument passed to create. + * @param {Object} props The `props` argument passed to create. + * @param {Object} opts The `opts` argument passed to create. + * @property {string} opts.op `beforeCreate` + */ + beforeCreate: noop, + + /** + * Lifecycle method method called by createMany. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes createMany to wait for the Promise to resolve before continuing. + * + * `props` may be modified. You can also re-assign `props` to another value by returning a different value or a Promise that resolves to a different value. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by createMany. + * + * @name Adapter#beforeCreateMany + * @method + * @param {Object} mapper The `mapper` argument passed to createMany. + * @param {Object[]} props The `props` argument passed to createMany. + * @param {Object} opts The `opts` argument passed to createMany. + * @property {string} opts.op `beforeCreateMany` + */ + beforeCreateMany: noop, + + /** + * Lifecycle method method called by destroy. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes destroy to wait for the Promise to resolve before continuing. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by destroy. + * + * @name Adapter#beforeDestroy + * @method + * @param {Object} mapper The `mapper` argument passed to destroy. + * @param {(string|number)} id The `id` argument passed to destroy. + * @param {Object} opts The `opts` argument passed to destroy. + * @property {string} opts.op `beforeDestroy` + */ + beforeDestroy: noop, + + /** + * Lifecycle method method called by destroyAll. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes destroyAll to wait for the Promise to resolve before continuing. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by destroyAll. + * + * @name Adapter#beforeDestroyAll + * @method + * @param {Object} mapper The `mapper` argument passed to destroyAll. + * @param {Object} query The `query` argument passed to destroyAll. + * @param {Object} opts The `opts` argument passed to destroyAll. + * @property {string} opts.op `beforeDestroyAll` + */ + beforeDestroyAll: noop, + + /** + * Lifecycle method method called by find. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes find to wait for the Promise to resolve before continuing. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by find. + * + * @name Adapter#beforeFind + * @method + * @param {Object} mapper The `mapper` argument passed to find. + * @param {(string|number)} id The `id` argument passed to find. + * @param {Object} opts The `opts` argument passed to find. + * @property {string} opts.op `beforeFind` + */ + beforeFind: noop, + + /** + * Lifecycle method method called by findAll. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes findAll to wait for the Promise to resolve before continuing. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by findAll. + * + * @name Adapter#beforeFindAll + * @method + * @param {Object} mapper The `mapper` argument passed to findAll. + * @param {Object} query The `query` argument passed to findAll. + * @param {Object} opts The `opts` argument passed to findAll. + * @property {string} opts.op `beforeFindAll` + */ + beforeFindAll: noop, + + /** + * Lifecycle method method called by sum. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes sum to wait for the Promise to resolve before continuing. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by sum. + * + * @name Adapter#beforeSum + * @method + * @param {Object} mapper The `mapper` argument passed to sum. + * @param {Object} query The `query` argument passed to sum. + * @param {Object} opts The `opts` argument passed to sum. + * @property {string} opts.op `beforeSum` + */ + beforeSum: noop, + + /** + * Lifecycle method method called by update. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes update to wait for the Promise to resolve before continuing. + * + * `props` may be modified. You can also re-assign `props` to another value by returning a different value or a Promise that resolves to a different value. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by update. + * + * @name Adapter#beforeUpdate + * @method + * @param {Object} mapper The `mapper` argument passed to update. + * @param {(string|number)} id The `id` argument passed to update. + * @param {Object} props The `props` argument passed to update. + * @param {Object} opts The `opts` argument passed to update. + * @property {string} opts.op `beforeUpdate` + */ + beforeUpdate: noop, + + /** + * Lifecycle method method called by updateAll. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes updateAll to wait for the Promise to resolve before continuing. + * + * `props` may be modified. You can also re-assign `props` to another value by returning a different value or a Promise that resolves to a different value. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by updateAll. + * + * @name Adapter#beforeUpdateAll + * @method + * @param {Object} mapper The `mapper` argument passed to updateAll. + * @param {Object} props The `props` argument passed to updateAll. + * @param {Object} query The `query` argument passed to updateAll. + * @param {Object} opts The `opts` argument passed to updateAll. + * @property {string} opts.op `beforeUpdateAll` + */ + beforeUpdateAll: noop, + + /** + * Lifecycle method method called by updateMany. + * + * Override this method to add custom behavior for this lifecycle hook. + * + * Returning a Promise causes updateMany to wait for the Promise to resolve before continuing. + * + * `props` may be modified. You can also re-assign `props` to another value by returning a different value or a Promise that resolves to a different value. + * + * A thrown error or rejected Promise will bubble up and reject the Promise returned by updateMany. + * + * @name Adapter#beforeUpdateMany + * @method + * @param {Object} mapper The `mapper` argument passed to updateMany. + * @param {Object[]} props The `props` argument passed to updateMany. + * @param {Object} opts The `opts` argument passed to updateMany. + * @property {string} opts.op `beforeUpdateMany` + */ + beforeUpdateMany: noop, + + /** + * Retrieve the number of records that match the selection query. Called by + * `Mapper#count`. + * + * @name Adapter#count + * @method + * @param {Object} mapper The mapper. + * @param {Object} [query] Selection query. + * @param {Object} [query.where] Filtering criteria. + * @param {string|Array} [query.orderBy] Sorting criteria. + * @param {string|Array} [query.sort] Same as `query.sort`. + * @param {number} [query.limit] Limit results. + * @param {number} [query.skip] Offset results. + * @param {number} [query.offset] Same as `query.skip`. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @return {Promise} + */ + count: function count(mapper, query, opts) { + var _this = this; + + var op = void 0; + query || (query = {}); + opts || (opts = {}); + + // beforeCount lifecycle hook + op = opts.op = 'beforeCount'; + return jsData.utils.resolve(this[op](mapper, query, opts)).then(function () { + // Allow for re-assignment from lifecycle hook + op = opts.op = 'count'; + _this.dbg(op, mapper, query, opts); + return jsData.utils.resolve(_this._count(mapper, query, opts)); + }).then(function (results) { + var _results = slicedToArray(results, 2), + data = _results[0], + result = _results[1]; + + result || (result = {}); + var response = new Response(data, result, op); + response = _this.respond(response, opts); + + // afterCount lifecycle hook + op = opts.op = 'afterCount'; + return jsData.utils.resolve(_this[op](mapper, query, opts, response)).then(function (_response) { + return _response === undefined ? response : _response; + }); + }); + }, + + + /** + * Create a new record. Called by `Mapper#create`. + * + * @name Adapter#create + * @method + * @param {Object} mapper The mapper. + * @param {Object} props The record to be created. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @return {Promise} + */ + create: function create(mapper, props, opts) { + var _this2 = this; + + var op = void 0; + props || (props = {}); + opts || (opts = {}); + + // beforeCreate lifecycle hook + op = opts.op = 'beforeCreate'; + return jsData.utils.resolve(this[op](mapper, props, opts)).then(function (_props) { + // Allow for re-assignment from lifecycle hook + props = _props === undefined ? props : _props; + props = withoutRelations(mapper, props, opts); + op = opts.op = 'create'; + _this2.dbg(op, mapper, props, opts); + return jsData.utils.resolve(_this2._create(mapper, props, opts)); + }).then(function (results) { + var _results2 = slicedToArray(results, 2), + data = _results2[0], + result = _results2[1]; + + result || (result = {}); + var response = new Response(data, result, 'create'); + response.created = data ? 1 : 0; + response = _this2.respond(response, opts); + + // afterCreate lifecycle hook + op = opts.op = 'afterCreate'; + return jsData.utils.resolve(_this2[op](mapper, props, opts, response)).then(function (_response) { + return _response === undefined ? response : _response; + }); + }); + }, + + + /** + * Create multiple records in a single batch. Called by `Mapper#createMany`. + * + * @name Adapter#createMany + * @method + * @param {Object} mapper The mapper. + * @param {Object} props The records to be created. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @return {Promise} + */ + createMany: function createMany(mapper, props, opts) { + var _this3 = this; + + var op = void 0; + props || (props = {}); + opts || (opts = {}); + + // beforeCreateMany lifecycle hook + op = opts.op = 'beforeCreateMany'; + return jsData.utils.resolve(this[op](mapper, props, opts)).then(function (_props) { + // Allow for re-assignment from lifecycle hook + props = _props === undefined ? props : _props; + props = props.map(function (record) { + return withoutRelations(mapper, record, opts); + }); + op = opts.op = 'createMany'; + _this3.dbg(op, mapper, props, opts); + return jsData.utils.resolve(_this3._createMany(mapper, props, opts)); + }).then(function (results) { + var _results3 = slicedToArray(results, 2), + data = _results3[0], + result = _results3[1]; + + data || (data = []); + result || (result = {}); + var response = new Response(data, result, 'createMany'); + response.created = data.length; + response = _this3.respond(response, opts); + + // afterCreateMany lifecycle hook + op = opts.op = 'afterCreateMany'; + return jsData.utils.resolve(_this3[op](mapper, props, opts, response)).then(function (_response) { + return _response === undefined ? response : _response; + }); + }); + }, + + + /** + * Destroy the record with the given primary key. Called by + * `Mapper#destroy`. + * + * @name Adapter#destroy + * @method + * @param {Object} mapper The mapper. + * @param {(string|number)} id Primary key of the record to destroy. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @return {Promise} + */ + destroy: function destroy(mapper, id, opts) { + var _this4 = this; + + var op = void 0; + opts || (opts = {}); + + // beforeDestroy lifecycle hook + op = opts.op = 'beforeDestroy'; + return jsData.utils.resolve(this[op](mapper, id, opts)).then(function () { + op = opts.op = 'destroy'; + _this4.dbg(op, mapper, id, opts); + return jsData.utils.resolve(_this4._destroy(mapper, id, opts)); + }).then(function (results) { + var _results4 = slicedToArray(results, 2), + data = _results4[0], + result = _results4[1]; + + result || (result = {}); + var response = new Response(data, result, 'destroy'); + response = _this4.respond(response, opts); + + // afterDestroy lifecycle hook + op = opts.op = 'afterDestroy'; + return jsData.utils.resolve(_this4[op](mapper, id, opts, response)).then(function (_response) { + return _response === undefined ? response : _response; + }); + }); + }, + + + /** + * Destroy the records that match the selection query. Called by + * `Mapper#destroyAll`. + * + * @name Adapter#destroyAll + * @method + * @param {Object} mapper the mapper. + * @param {Object} [query] Selection query. + * @param {Object} [query.where] Filtering criteria. + * @param {string|Array} [query.orderBy] Sorting criteria. + * @param {string|Array} [query.sort] Same as `query.sort`. + * @param {number} [query.limit] Limit results. + * @param {number} [query.skip] Offset results. + * @param {number} [query.offset] Same as `query.skip`. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @return {Promise} + */ + destroyAll: function destroyAll(mapper, query, opts) { + var _this5 = this; + + var op = void 0; + query || (query = {}); + opts || (opts = {}); + + // beforeDestroyAll lifecycle hook + op = opts.op = 'beforeDestroyAll'; + return jsData.utils.resolve(this[op](mapper, query, opts)).then(function () { + op = opts.op = 'destroyAll'; + _this5.dbg(op, mapper, query, opts); + return jsData.utils.resolve(_this5._destroyAll(mapper, query, opts)); + }).then(function (results) { + var _results5 = slicedToArray(results, 2), + data = _results5[0], + result = _results5[1]; + + result || (result = {}); + var response = new Response(data, result, 'destroyAll'); + response = _this5.respond(response, opts); + + // afterDestroyAll lifecycle hook + op = opts.op = 'afterDestroyAll'; + return jsData.utils.resolve(_this5[op](mapper, query, opts, response)).then(function (_response) { + return _response === undefined ? response : _response; + }); + }); + }, + + + /** + * Load a belongsTo relationship. + * + * Override with care. + * + * @name Adapter#loadBelongsTo + * @method + * @return {Promise} + */ + loadBelongsTo: function loadBelongsTo(mapper, def, records, __opts) { + var _this6 = this; + + var relationDef = def.getRelation(); + + if (jsData.utils.isObject(records) && !jsData.utils.isArray(records)) { + var record = records; + return this.find(relationDef, this.makeBelongsToForeignKey(mapper, def, record), __opts).then(function (relatedItem) { + def.setLocalField(record, relatedItem); + }); + } else { + var keys = records.map(function (record) { + return _this6.makeBelongsToForeignKey(mapper, def, record); + }).filter(function (key) { + return key; + }); + return this.findAll(relationDef, { + where: defineProperty({}, relationDef.idAttribute, { + 'in': keys + }) + }, __opts).then(function (relatedItems) { + records.forEach(function (record) { + relatedItems.forEach(function (relatedItem) { + if (relatedItem[relationDef.idAttribute] === record[def.foreignKey]) { + def.setLocalField(record, relatedItem); + } + }); + }); + }); + } + }, + + + /** + * Retrieve the record with the given primary key. Called by `Mapper#find`. + * + * @name Adapter#find + * @method + * @param {Object} mapper The mapper. + * @param {(string|number)} id Primary key of the record to retrieve. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @param {string[]} [opts.with=[]] Relations to eager load. + * @return {Promise} + */ + find: function find(mapper, id, opts) { + var _this7 = this; + + var op = void 0; + opts || (opts = {}); + opts.with || (opts.with = []); + + // beforeFind lifecycle hook + op = opts.op = 'beforeFind'; + return jsData.utils.resolve(this[op](mapper, id, opts)).then(function () { + op = opts.op = 'find'; + _this7.dbg(op, mapper, id, opts); + return jsData.utils.resolve(_this7._find(mapper, id, opts)); + }).then(function (results) { + return _this7.loadRelationsFor(mapper, results, opts); + }).then(function (_ref) { + var _ref2 = slicedToArray(_ref, 2), + record = _ref2[0], + meta = _ref2[1]; + + var response = new Response(record, meta, 'find'); + response.found = record ? 1 : 0; + response = _this7.respond(response, opts); + + // afterFind lifecycle hook + op = opts.op = 'afterFind'; + return jsData.utils.resolve(_this7[op](mapper, id, opts, response)).then(function (_response) { + return _response === undefined ? response : _response; + }); + }); + }, + + + /** + * Retrieve the records that match the selection query. + * + * @name Adapter#findAll + * @method + * @param {Object} mapper The mapper. + * @param {Object} [query] Selection query. + * @param {Object} [query.where] Filtering criteria. + * @param {string|Array} [query.orderBy] Sorting criteria. + * @param {string|Array} [query.sort] Same as `query.sort`. + * @param {number} [query.limit] Limit results. + * @param {number} [query.skip] Offset results. + * @param {number} [query.offset] Same as `query.skip`. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @param {string[]} [opts.with=[]] Relations to eager load. + * @return {Promise} + */ + findAll: function findAll(mapper, query, opts) { + var _this8 = this; + + var op = void 0; + opts || (opts = {}); + opts.with || (opts.with = []); + + var activeWith = opts._activeWith; + + if (jsData.utils.isObject(activeWith)) { + var activeQuery = activeWith.query || {}; + if (activeWith.replace) { + query = activeQuery; + } else { + jsData.utils.deepFillIn(query, activeQuery); + } + } + + // beforeFindAll lifecycle hook + op = opts.op = 'beforeFindAll'; + return jsData.utils.resolve(this[op](mapper, query, opts)).then(function () { + op = opts.op = 'findAll'; + _this8.dbg(op, mapper, query, opts); + return jsData.utils.resolve(_this8._findAll(mapper, query, opts)); + }).then(function (results) { + return _this8.loadRelationsFor(mapper, results, opts); + }).then(function (_ref3) { + var _ref4 = slicedToArray(_ref3, 2), + records = _ref4[0], + meta = _ref4[1]; + + var response = new Response(records, meta, 'findAll'); + response.found = records.length; + response = _this8.respond(response, opts); + + // afterFindAll lifecycle hook + op = opts.op = 'afterFindAll'; + return jsData.utils.resolve(_this8[op](mapper, query, opts, response)).then(function (_response) { + return _response === undefined ? response : _response; + }); + }); + }, + loadRelationsFor: function loadRelationsFor(mapper, results, opts) { + var _this9 = this; + + var _results6 = slicedToArray(results, 1), + records = _results6[0]; + + var tasks = []; + + if (records) { + jsData.utils.forEachRelation(mapper, opts, function (def, __opts) { + var task = void 0; + if (def.foreignKey && (def.type === 'hasOne' || def.type === 'hasMany')) { + if (def.type === 'hasOne') { + task = _this9.loadHasOne(mapper, def, records, __opts); + } else { + task = _this9.loadHasMany(mapper, def, records, __opts); + } + } else if (def.type === 'hasMany' && def.localKeys) { + task = _this9.loadHasManyLocalKeys(mapper, def, records, __opts); + } else if (def.type === 'hasMany' && def.foreignKeys) { + task = _this9.loadHasManyForeignKeys(mapper, def, records, __opts); + } else if (def.type === 'belongsTo') { + task = _this9.loadBelongsTo(mapper, def, records, __opts); + } + if (task) { + tasks.push(task); + } + }); + } + + return jsData.utils.Promise.all(tasks).then(function () { + return results; + }); + }, + + + /** + * Resolve the value of the specified option based on the given options and + * this adapter's settings. Override with care. + * + * @name Adapter#getOpt + * @method + * @param {string} opt The name of the option. + * @param {Object} [opts] Configuration options. + * @return {*} The value of the specified option. + */ + getOpt: function getOpt(opt, opts) { + opts || (opts = {}); + return opts[opt] === undefined ? jsData.utils.plainCopy(this[opt]) : jsData.utils.plainCopy(opts[opt]); + }, + + + /** + * Load a hasMany relationship. + * + * Override with care. + * + * @name Adapter#loadHasMany + * @method + * @return {Promise} + */ + loadHasMany: function loadHasMany(mapper, def, records, __opts) { + var _this10 = this; + + var singular = false; + + if (jsData.utils.isObject(records) && !jsData.utils.isArray(records)) { + singular = true; + records = [records]; + } + var IDs = records.map(function (record) { + return _this10.makeHasManyForeignKey(mapper, def, record); + }); + var query = { + where: {} + }; + var criteria = query.where[def.foreignKey] = {}; + if (singular) { + // more efficient query when we only have one record + criteria['=='] = IDs[0]; + } else { + criteria['in'] = IDs.filter(function (id) { + return id; + }); + } + return this.findAll(def.getRelation(), query, __opts).then(function (relatedItems) { + records.forEach(function (record) { + var attached = []; + // avoid unneccesary iteration when we only have one record + if (singular) { + attached = relatedItems; + } else { + relatedItems.forEach(function (relatedItem) { + if (jsData.utils.get(relatedItem, def.foreignKey) === record[mapper.idAttribute]) { + attached.push(relatedItem); + } + }); + } + def.setLocalField(record, attached); + }); + }); + }, + loadHasManyLocalKeys: function loadHasManyLocalKeys(mapper, def, records, __opts) { + var _this11 = this; + + var record = void 0; + var relatedMapper = def.getRelation(); + + if (jsData.utils.isObject(records) && !jsData.utils.isArray(records)) { + record = records; + } + + if (record) { + return this.findAll(relatedMapper, { + where: defineProperty({}, relatedMapper.idAttribute, { + 'in': this.makeHasManyLocalKeys(mapper, def, record) + }) + }, __opts).then(function (relatedItems) { + def.setLocalField(record, relatedItems); + }); + } else { + var localKeys = []; + records.forEach(function (record) { + localKeys = localKeys.concat(_this11.makeHasManyLocalKeys(mapper, def, record)); + }); + return this.findAll(relatedMapper, { + where: defineProperty({}, relatedMapper.idAttribute, { + 'in': unique(localKeys).filter(function (x) { + return x; + }) + }) + }, __opts).then(function (relatedItems) { + records.forEach(function (item) { + var attached = []; + var itemKeys = jsData.utils.get(item, def.localKeys) || []; + itemKeys = jsData.utils.isArray(itemKeys) ? itemKeys : Object.keys(itemKeys); + relatedItems.forEach(function (relatedItem) { + if (itemKeys && itemKeys.indexOf(relatedItem[relatedMapper.idAttribute]) !== -1) { + attached.push(relatedItem); + } + }); + def.setLocalField(item, attached); + }); + return relatedItems; + }); + } + }, + loadHasManyForeignKeys: function loadHasManyForeignKeys(mapper, def, records, __opts) { + var _this12 = this; + + var relatedMapper = def.getRelation(); + var idAttribute = mapper.idAttribute; + var record = void 0; + + if (jsData.utils.isObject(records) && !jsData.utils.isArray(records)) { + record = records; + } + + if (record) { + return this.findAll(def.getRelation(), { + where: defineProperty({}, def.foreignKeys, { + 'contains': this.makeHasManyForeignKeys(mapper, def, record) + }) + }, __opts).then(function (relatedItems) { + def.setLocalField(record, relatedItems); + }); + } else { + return this.findAll(relatedMapper, { + where: defineProperty({}, def.foreignKeys, { + 'isectNotEmpty': records.map(function (record) { + return _this12.makeHasManyForeignKeys(mapper, def, record); + }) + }) + }, __opts).then(function (relatedItems) { + var foreignKeysField = def.foreignKeys; + records.forEach(function (record) { + var _relatedItems = []; + var id = jsData.utils.get(record, idAttribute); + relatedItems.forEach(function (relatedItem) { + var foreignKeys = jsData.utils.get(relatedItems, foreignKeysField) || []; + if (foreignKeys.indexOf(id) !== -1) { + _relatedItems.push(relatedItem); + } + }); + def.setLocalField(record, _relatedItems); + }); + }); + } + }, + + + /** + * Load a hasOne relationship. + * + * Override with care. + * + * @name Adapter#loadHasOne + * @method + * @return {Promise} + */ + loadHasOne: function loadHasOne(mapper, def, records, __opts) { + if (jsData.utils.isObject(records) && !jsData.utils.isArray(records)) { + records = [records]; + } + return this.loadHasMany(mapper, def, records, __opts).then(function () { + records.forEach(function (record) { + var relatedData = def.getLocalField(record); + if (jsData.utils.isArray(relatedData) && relatedData.length) { + def.setLocalField(record, relatedData[0]); + } + }); + }); + }, + + + /** + * Return the foreignKey from the given record for the provided relationship. + * + * There may be reasons why you may want to override this method, like when + * the id of the parent doesn't exactly match up to the key on the child. + * + * Override with care. + * + * @name Adapter#makeHasManyForeignKey + * @method + * @return {*} + */ + makeHasManyForeignKey: function makeHasManyForeignKey(mapper, def, record) { + return def.getForeignKey(record); + }, + + + /** + * Return the localKeys from the given record for the provided relationship. + * + * Override with care. + * + * @name Adapter#makeHasManyLocalKeys + * @method + * @return {*} + */ + makeHasManyLocalKeys: function makeHasManyLocalKeys(mapper, def, record) { + var localKeys = []; + var itemKeys = jsData.utils.get(record, def.localKeys) || []; + itemKeys = jsData.utils.isArray(itemKeys) ? itemKeys : Object.keys(itemKeys); + localKeys = localKeys.concat(itemKeys); + return unique(localKeys).filter(function (x) { + return x; + }); + }, + + + /** + * Return the foreignKeys from the given record for the provided relationship. + * + * Override with care. + * + * @name Adapter#makeHasManyForeignKeys + * @method + * @return {*} + */ + makeHasManyForeignKeys: function makeHasManyForeignKeys(mapper, def, record) { + return jsData.utils.get(record, mapper.idAttribute); + }, + + + /** + * Return the foreignKey from the given record for the provided relationship. + * + * Override with care. + * + * @name Adapter#makeBelongsToForeignKey + * @method + * @return {*} + */ + makeBelongsToForeignKey: function makeBelongsToForeignKey(mapper, def, record) { + return def.getForeignKey(record); + }, + + + /** + * Retrieve sum of the specified field of the records that match the selection + * query. Called by `Mapper#sum`. + * + * @name Adapter#sum + * @method + * @param {Object} mapper The mapper. + * @param {string} field By to sum. + * @param {Object} [query] Selection query. + * @param {Object} [query.where] Filtering criteria. + * @param {string|Array} [query.orderBy] Sorting criteria. + * @param {string|Array} [query.sort] Same as `query.sort`. + * @param {number} [query.limit] Limit results. + * @param {number} [query.skip] Offset results. + * @param {number} [query.offset] Same as `query.skip`. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @return {Promise} + */ + sum: function sum(mapper, field, query, opts) { + var _this13 = this; + + var op = void 0; + if (!jsData.utils.isString(field)) { + throw new Error('field must be a string!'); + } + query || (query = {}); + opts || (opts = {}); + + // beforeSum lifecycle hook + op = opts.op = 'beforeSum'; + return jsData.utils.resolve(this[op](mapper, field, query, opts)).then(function () { + // Allow for re-assignment from lifecycle hook + op = opts.op = 'sum'; + _this13.dbg(op, mapper, field, query, opts); + return jsData.utils.resolve(_this13._sum(mapper, field, query, opts)); + }).then(function (results) { + var _results7 = slicedToArray(results, 2), + data = _results7[0], + result = _results7[1]; + + result || (result = {}); + var response = new Response(data, result, op); + response = _this13.respond(response, opts); + + // afterSum lifecycle hook + op = opts.op = 'afterSum'; + return jsData.utils.resolve(_this13[op](mapper, field, query, opts, response)).then(function (_response) { + return _response === undefined ? response : _response; + }); + }); + }, + + + /** + * @name Adapter#respond + * @method + * @param {Object} response Response object. + * @param {Object} opts Configuration options. + * return {Object} If `opts.raw == true` then return `response`, else return + * `response.data`. + */ + respond: function respond(response, opts) { + return this.getOpt('raw', opts) ? response : response.data; + }, + + + /** + * Apply the given update to the record with the specified primary key. Called + * by `Mapper#update`. + * + * @name Adapter#update + * @method + * @param {Object} mapper The mapper. + * @param {(string|number)} id The primary key of the record to be updated. + * @param {Object} props The update to apply to the record. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @return {Promise} + */ + update: function update(mapper, id, props, opts) { + var _this14 = this; + + props || (props = {}); + opts || (opts = {}); + var op = void 0; + + // beforeUpdate lifecycle hook + op = opts.op = 'beforeUpdate'; + return jsData.utils.resolve(this[op](mapper, id, props, opts)).then(function (_props) { + // Allow for re-assignment from lifecycle hook + props = _props === undefined ? props : _props; + props = withoutRelations(mapper, props, opts); + op = opts.op = 'update'; + _this14.dbg(op, mapper, id, props, opts); + return jsData.utils.resolve(_this14._update(mapper, id, props, opts)); + }).then(function (results) { + var _results8 = slicedToArray(results, 2), + data = _results8[0], + result = _results8[1]; + + result || (result = {}); + var response = new Response(data, result, 'update'); + response.updated = data ? 1 : 0; + response = _this14.respond(response, opts); + + // afterUpdate lifecycle hook + op = opts.op = 'afterUpdate'; + return jsData.utils.resolve(_this14[op](mapper, id, props, opts, response)).then(function (_response) { + return _response === undefined ? response : _response; + }); + }); + }, + + + /** + * Apply the given update to all records that match the selection query. + * Called by `Mapper#updateAll`. + * + * @name Adapter#updateAll + * @method + * @param {Object} mapper The mapper. + * @param {Object} props The update to apply to the selected records. + * @param {Object} [query] Selection query. + * @param {Object} [query.where] Filtering criteria. + * @param {string|Array} [query.orderBy] Sorting criteria. + * @param {string|Array} [query.sort] Same as `query.sort`. + * @param {number} [query.limit] Limit results. + * @param {number} [query.skip] Offset results. + * @param {number} [query.offset] Same as `query.skip`. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @return {Promise} + */ + updateAll: function updateAll(mapper, props, query, opts) { + var _this15 = this; + + props || (props = {}); + query || (query = {}); + opts || (opts = {}); + var op = void 0; + + // beforeUpdateAll lifecycle hook + op = opts.op = 'beforeUpdateAll'; + return jsData.utils.resolve(this[op](mapper, props, query, opts)).then(function (_props) { + // Allow for re-assignment from lifecycle hook + props = _props === undefined ? props : _props; + props = withoutRelations(mapper, props, opts); + op = opts.op = 'updateAll'; + _this15.dbg(op, mapper, props, query, opts); + return jsData.utils.resolve(_this15._updateAll(mapper, props, query, opts)); + }).then(function (results) { + var _results9 = slicedToArray(results, 2), + data = _results9[0], + result = _results9[1]; + + data || (data = []); + result || (result = {}); + var response = new Response(data, result, 'updateAll'); + response.updated = data.length; + response = _this15.respond(response, opts); + + // afterUpdateAll lifecycle hook + op = opts.op = 'afterUpdateAll'; + return jsData.utils.resolve(_this15[op](mapper, props, query, opts, response)).then(function (_response) { + return _response === undefined ? response : _response; + }); + }); + }, + + + /** + * Update the given records in a single batch. Called by `Mapper#updateMany`. + * + * @name Adapter#updateMany + * @method + * @param {Object} mapper The mapper. + * @param {Object[]} records The records to update. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @return {Promise} + */ + updateMany: function updateMany(mapper, records, opts) { + var _this16 = this; + + records || (records = []); + opts || (opts = {}); + var op = void 0; + var idAttribute = mapper.idAttribute; + + records = records.filter(function (record) { + return jsData.utils.get(record, idAttribute); + }); + + // beforeUpdateMany lifecycle hook + op = opts.op = 'beforeUpdateMany'; + return jsData.utils.resolve(this[op](mapper, records, opts)).then(function (_records) { + // Allow for re-assignment from lifecycle hook + records = _records === undefined ? records : _records; + records = records.map(function (record) { + return withoutRelations(mapper, record, opts); + }); + op = opts.op = 'updateMany'; + _this16.dbg(op, mapper, records, opts); + return jsData.utils.resolve(_this16._updateMany(mapper, records, opts)); + }).then(function (results) { + var _results10 = slicedToArray(results, 2), + data = _results10[0], + result = _results10[1]; + + data || (data = []); + result || (result = {}); + var response = new Response(data, result, 'updateMany'); + response.updated = data.length; + response = _this16.respond(response, opts); + + // afterUpdateMany lifecycle hook + op = opts.op = 'afterUpdateMany'; + return jsData.utils.resolve(_this16[op](mapper, records, opts, response)).then(function (_response) { + return _response === undefined ? response : _response; + }); + }); + } +}); + +/** + * Create a subclass of this Adapter: + * + * @example