diff --git a/.babelrc b/.babelrc
deleted file mode 100644
index e7ad549..0000000
--- a/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["es2015", "stage-0"],
- "plugins": ["syntax-async-functions", "transform-regenerator"]
-}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 09afacd..c7cd3bc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,91 @@
+##### 2.0.0-alpha.21 - 03 May 2016
+
+- Fix peer dependencies
+
+##### 2.0.0-alpha.20 - 02 May 2016
+
+- Fix for SQL testing
+
+##### 2.0.0-alpha.19 - 02 May 2016
+
+- Fix for SQL testing
+
+##### 2.0.0-alpha.18 - 02 May 2016
+
+- Fix for SQL testing
+
+##### 2.0.0-alpha.17 - 30 April 2016
+
+- Fix for testing in IE9
+
+##### 2.0.0-alpha.16 - 17 March 2016
+
+- Added tests for "count" and "sum" methods
+
+##### 2.0.0-alpha.15 - 12 March 2016
+
+- Added tests for filtering in "with" sub queries
+
+##### 2.0.0-alpha.14 - 08 March 2016
+
+- Features and Methods are now opt-out rather than opt-in
+
+##### 2.0.0-alpha.13 - 03 March 2016
+
+- Added tests for subclassing adapters
+
+##### 2.0.0-alpha.12 - 01 March 2016
+
+- Some improved testing
+
+##### 2.0.0-alpha.11 - 29 February 2016
+
+- Some improved testing
+
+##### 2.0.0-alpha.10 - 26 February 2016
+
+- Some fixes
+
+##### 2.0.0-alpha.9 - 26 February 2016
+
+- Some fixes
+
+##### 2.0.0-alpha.8 - 26 February 2016
+
+- destroy and destroyAll no longer have return values
+
+##### 2.0.0-alpha.7 - 26 February 2016
+
+- Improved testing
+
+##### 2.0.0-alpha.6 - 23 February 2016
+
+- Improved testing of find, destroy, and update features
+
+##### 2.0.0-alpha.5 - 18 February 2016
+
+- rebased 1.5.0 changes
+
##### 1.5.0 - 18 February 2016
- Some improvements
+##### 2.0.0-alpha.4 - 16 February 2016
+
+- Better configurability
+
+##### 2.0.0-alpha.3 - 16 February 2016
+
+- Added source map
+
+##### 2.0.0-alpha.2 - 16 February 2016
+
+- Soem fixes
+
+##### 2.0.0-alpha.1 - 13 February 2016
+
+- Upgrades to work with 3.x js-data and adapters
+
##### 1.3.0 - 10 November 2015
- Fixed coMocha and some assertions
diff --git a/README.md b/README.md
index bbdb2d6..f175c9f 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,65 @@
-
+
-## js-data-adapter-tests [![Slack Status][sl_b]][sl_l] [![npm version][npm_b]][npm_l] [![Circle CI][circle_b]][circle_l] [![npm downloads][dn_b]][dn_l]
+# js-data-adapter-tests
+
+[![Slack Status][sl_b]][sl_l]
+[![npm version][npm_b]][npm_l]
+[![Circle CI][circle_b]][circle_l]
+[![npm downloads][dn_b]][dn_l]
Tests for [js-data](http://www.js-data.io/) adapters.
-See [js-data-sql](https://github.com/js-data/js-data-sql/blob/master/mocha.start.js) for usage.
+## Usage
+
+### Node.js
+
+```
+npm install --save-dev js-data-adapter-tests mocha sinon chai babel-polyfill
+```
+
+`mocha.start.js`:
+
+```js
+require('babel-polyfill')
+
+var JSData = require('js-data')
+var JSDataAdapterTests = require('js-data-adapter-tests')
+var MyAdapter = require('./')
+
+global.assert = JSDataAdapterTests.assert;
+global.sinon = JSDataAdapterTests.sinon;
+
+JSDataAdapterTests.init({
+ // minimum required config
+ JSData: JSData,
+ Adapter: MyAdapter
+})
+```
+
+### Karma
+
+```
+npm install --save-dev js-data-adapter-tests mocha sinon chai babel-polyfill karma karma-mocha karma-sinon karma-chai
+```
+
+`karma.start.js`:
+
+```js
+// babel-polyfill should be included by karma.conf.js
+
+window.assert = JSDataAdapterTests.assert
+// sinon should be loaded by karma.conf.js
+
+JSDataAdapterTests.init({
+ // minimum required config
+ JSData: JSData,
+ Adapter: MyAdapter
+})
+```
+
+See [js-data-rethinkdb](https://github.com/js-data/js-data-rethinkdb/blob/master/mocha.start.js) for a Node.js example.
+
+See [js-data-localstorage](https://github.com/js-data/js-data-localstorage/blob/master/karma.start.js) for a Karma example.
### Changelog
[CHANGELOG.md](https://github.com/js-data/js-data-adapter-tests/blob/master/CHANGELOG.md)
@@ -16,7 +71,7 @@ See [js-data-sql](https://github.com/js-data/js-data-sql/blob/master/mocha.start
The MIT License (MIT)
-Copyright (c) 2014-2015 Jason Dobry
+Copyright (c) 2014-2016 Jason Dobry
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/dist/js-data-adapter-tests.js b/dist/js-data-adapter-tests.js
index 4b7f770..5746a3f 100644
--- a/dist/js-data-adapter-tests.js
+++ b/dist/js-data-adapter-tests.js
@@ -1,1565 +1,4606 @@
-(function webpackUniversalModuleDefinition(root, factory) {
- if(typeof exports === 'object' && typeof module === 'object')
- module.exports = factory();
- else if(typeof define === 'function' && define.amd)
- define([], factory);
- else if(typeof exports === 'object')
- exports["TestRunner"] = factory();
- else
- root["TestRunner"] = factory();
-})(this, function() {
-return /******/ (function(modules) { // webpackBootstrap
-/******/ // The module cache
-/******/ var installedModules = {};
-/******/
-/******/ // The require function
-/******/ function __webpack_require__(moduleId) {
-/******/
-/******/ // Check if module is in cache
-/******/ if(installedModules[moduleId])
-/******/ return installedModules[moduleId].exports;
-/******/
-/******/ // Create a new module (and put it into the cache)
-/******/ var module = installedModules[moduleId] = {
-/******/ exports: {},
-/******/ id: moduleId,
-/******/ loaded: false
-/******/ };
-/******/
-/******/ // Execute the module function
-/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
-/******/
-/******/ // Flag the module as loaded
-/******/ module.loaded = true;
-/******/
-/******/ // Return the exports of the module
-/******/ return module.exports;
-/******/ }
-/******/
-/******/
-/******/ // expose the modules object (__webpack_modules__)
-/******/ __webpack_require__.m = modules;
-/******/
-/******/ // expose the module cache
-/******/ __webpack_require__.c = installedModules;
-/******/
-/******/ // __webpack_public_path__
-/******/ __webpack_require__.p = "";
-/******/
-/******/ // Load entry module and return exports
-/******/ return __webpack_require__(0);
-/******/ })
-/************************************************************************/
-/******/ ([
-/* 0 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
-
- function _asyncToGenerator(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) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
-
- assert.equalObjects = function (a, b, m) {
- assert.deepEqual(JSON.parse(JSON.stringify(a)), JSON.parse(JSON.stringify(b)), m || JSON.stringify(a) + ' should be equal to ' + JSON.stringify(b));
- };
-
- assert.objectsEqual = function (a, b, m) {
- 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;
-
- assert.debug = function () {
- if (debug) {
- var _console;
-
- (_console = console).log.apply(_console, arguments);
- }
- };
-
- var prefix = 'TestRunner.init(options): options';
-
- module.exports = {
- init: function init(options) {
- options = options || {};
- debug = !!options.debug;
- options.methods = options.methods || 'all';
- options.features = options.features || 'all';
- if (!options.DS || typeof options.DS !== 'function') {
- throw new Error(prefix + '.DS: Expected function, Actual: ' + _typeof(options.DS));
- }
- 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.$$store = new options.DS(options.storeConfig || {
- log: false,
- debug: false
- });
- this.$$User = this.$$store.defineResource(options.userConfig || {
- name: 'user',
- relations: {
- hasMany: {
- post: {
- localField: 'posts',
- foreignKey: 'userId'
- }
- },
- hasOne: {
- profile: {
- localField: 'profile',
- foreignKey: 'userId'
- },
- address: {
- localField: 'address',
- foreignKey: 'userId'
- }
- }
- }
- });
- this.$$Profile = this.$$store.defineResource(options.profileConfig || {
- name: 'profile',
- relations: {
- belongsTo: {
- user: {
- localField: 'user',
- localkey: 'userId'
- }
- }
- }
- });
- this.$$Address = this.$$store.defineResource(options.addressConfig || {
- name: 'address',
- relations: {
- belongsTo: {
- user: {
- localField: 'user',
- localkey: 'userId'
- }
- }
- }
- });
- this.$$Post = this.$$store.defineResource(options.postConfig || {
- name: 'post',
- relations: {
- belongsTo: {
- user: {
- localField: 'user',
- localKey: 'userId'
- }
- },
- hasMany: {
- comment: {
- localField: 'comments',
- foreignKey: 'postId'
- }
- }
- }
- });
- this.$$Comment = this.$$store.defineResource(options.commentConfig || {
- name: 'comment',
- relations: {
- belongsTo: {
- post: {
- localField: 'post',
- localKey: 'postId'
- },
- user: {
- localField: 'user',
- localKey: 'userId'
- }
- }
- }
- });
- });
-
- describe('js-data-adapter-tests', function () {
- if (options.methods === 'all' || options.methods.indexOf('create') !== -1) {
- __webpack_require__(1)(options);
- }
- if (options.methods === 'all' || options.methods.indexOf('find') !== -1) {
- __webpack_require__(2)(options);
- }
- if (options.methods === 'all' || options.methods.indexOf('findAll') !== -1) {
- __webpack_require__(3)(options);
- }
- if (options.methods === 'all' || options.methods.indexOf('destroy') !== -1) {
- __webpack_require__(4)(options);
- }
- if (options.methods === 'all' || options.methods.indexOf('destroyAll') !== -1) {
- __webpack_require__(5)(options);
- }
- if (options.methods === 'all' || options.methods.indexOf('update') !== -1) {
- __webpack_require__(6)(options);
- }
- if (options.methods === 'all' || options.methods.indexOf('updateAll') !== -1) {
- __webpack_require__(7)(options);
- }
- });
-
- afterEach(_asyncToGenerator(regeneratorRuntime.mark(function _callee() {
- return regeneratorRuntime.wrap(function _callee$(_context) {
- while (1) {
- switch (_context.prev = _context.next) {
- case 0:
- _context.next = 2;
- return this.$$adapter.destroyAll(this.$$Comment);
-
- case 2:
- _context.next = 4;
- return this.$$adapter.destroyAll(this.$$Post);
-
- case 4:
- _context.next = 6;
- return this.$$adapter.destroyAll(this.$$User);
-
- case 6:
- _context.next = 8;
- return this.$$adapter.destroyAll(this.$$Profile);
-
- case 8:
- _context.next = 10;
- return this.$$adapter.destroyAll(this.$$Address);
-
- case 10:
- case 'end':
- return _context.stop();
- }
- }
- }, _callee, this);
- })));
- },
- assert: assert,
- fail: function fail(msg) {
- 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]
- };
-
-/***/ },
-/* 1 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
-
- function _asyncToGenerator(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) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
-
- module.exports = 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, 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', props);
- _context.next = 6;
- return adapter.create(User, props);
-
- case 6:
- user = _context.sent;
-
- assert.debug('created', JSON.stringify(user, null, 2));
-
- 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[User.idAttribute]);
- _context.next = 13;
- return adapter.find(User, user[User.idAttribute]);
-
- case 13:
- foundUser = _context.sent;
-
- assert.debug('found', JSON.stringify(foundUser, null, 2));
-
- 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]);
-
- case 18:
- case 'end':
- return _context.stop();
- }
- }
- }, _callee, this);
- })));
- });
- };
-
-/***/ },
-/* 2 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
-
- function _asyncToGenerator(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) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
-
- module.exports = function (options) {
- describe('Adapter#find', 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.find), 'function', 'adapter should have a "find" method');
- });
-
- it('should find a user', _asyncToGenerator(regeneratorRuntime.mark(function _callee() {
- var props, user, userId, foundUser, post, postId, comments, findPost;
- return regeneratorRuntime.wrap(function _callee$(_context) {
- while (1) {
- switch (_context.prev = _context.next) {
- case 0:
- props = { name: 'John' };
-
- assert.debug('create', props);
- _context.next = 4;
- return adapter.create(User, props);
-
- case 4:
- user = _context.sent;
-
- assert.debug('created', JSON.stringify(user, null, 2));
- userId = user[User.idAttribute];
-
- assert.equal(user.name, 'John', 'name of created user should be "John"');
- assert.isDefined(user[User.idAttribute]);
-
- assert.debug('find', user[User.idAttribute]);
- _context.next = 12;
- return adapter.find(User, user[User.idAttribute]);
-
- case 12:
- foundUser = _context.sent;
-
- assert.debug('found', JSON.stringify(foundUser, null, 2));
- assert.equal(foundUser.name, 'John');
- assert.isDefined(foundUser[User.idAttribute]);
- assert.equal(foundUser[User.idAttribute], userId);
- assert.equal(foundUser.name, 'John');
-
- props = { content: 'test', userId: userId };
- assert.debug('create', props);
- _context.next = 22;
- return adapter.create(Post, props);
-
- case 22:
- post = _context.sent;
-
- assert.debug('created', JSON.stringify(post, null, 2));
- postId = post[Post.idAttribute];
-
- assert.equal(post.content, 'test');
- assert.isDefined(post[Post.idAttribute]);
- assert.equal(post.userId, userId);
-
- props = [{
- content: 'test2',
- postId: post[Post.idAttribute],
- userId: user[User.idAttribute]
- }, {
- content: 'test3',
- postId: post[Post.idAttribute],
- userId: user[User.idAttribute]
- }];
- assert.debug('create', props);
- _context.next = 32;
- return Promise.all([adapter.create(Comment, props[0]), adapter.create(Comment, props[1])]);
-
- case 32:
- comments = _context.sent;
-
- assert.debug('created', JSON.stringify(comments, null, 2));
-
- comments.sort(function (a, b) {
- return a.content > b.content;
- });
-
- _context.next = 37;
- return adapter.find(Post, postId, { with: ['user', 'comment'] });
-
- case 37:
- findPost = _context.sent;
-
- findPost.comments.sort(function (a, b) {
- return a.content > b.content;
- });
- assert.equalObjects(findPost.user, user);
- assert.equalObjects(findPost.comments, comments);
-
- case 41:
- case 'end':
- return _context.stop();
- }
- }
- }, _callee, this);
- })));
-
- it('should load belongsTo relations', _asyncToGenerator(regeneratorRuntime.mark(function _callee2() {
- var props, user, profile, post, comment;
- return regeneratorRuntime.wrap(function _callee2$(_context2) {
- while (1) {
- switch (_context2.prev = _context2.next) {
- case 0:
- props = { name: 'John' };
-
- assert.debug('create', props);
- _context2.next = 4;
- return adapter.create(User, props);
-
- case 4:
- user = _context2.sent;
-
- assert.debug('created', JSON.stringify(user, null, 2));
-
- props = { email: 'foo@test.com', userId: user[User.idAttribute] };
- assert.debug('create', props);
- _context2.next = 10;
- return adapter.create(Profile, props);
-
- case 10:
- profile = _context2.sent;
-
- assert.debug('created', JSON.stringify(profile, null, 2));
-
- props = { content: 'foo', userId: user[User.idAttribute] };
- assert.debug('create', props);
- _context2.next = 16;
- return adapter.create(Post, props);
-
- case 16:
- post = _context2.sent;
-
- assert.debug('created', JSON.stringify(post, null, 2));
-
- props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId };
- assert.debug('create', props);
- _context2.next = 22;
- return adapter.create(Comment, props);
-
- case 22:
- comment = _context2.sent;
-
- assert.debug('created', JSON.stringify(comment, null, 2));
-
- assert.debug('find', comment[Comment.idAttribute]);
- _context2.next = 27;
- return adapter.find(Comment, comment[Comment.idAttribute], { 'with': ['user', 'user.profile', 'post', 'post.user'] });
-
- case 27:
- comment = _context2.sent;
-
- assert.debug('found', JSON.stringify(comment, null, 2));
- assert.isDefined(comment);
- assert.isDefined(comment.post);
- assert.isDefined(comment.post.user);
- assert.isDefined(comment.user);
- assert.isDefined(comment.user.profile);
-
- case 34:
- case 'end':
- return _context2.stop();
- }
- }
- }, _callee2, this);
- })));
-
- it('should load hasMany and belongsTo relations', _asyncToGenerator(regeneratorRuntime.mark(function _callee3() {
- var props, user, profile, post, comment;
- return regeneratorRuntime.wrap(function _callee3$(_context3) {
- while (1) {
- switch (_context3.prev = _context3.next) {
- case 0:
- props = { name: 'John' };
-
- assert.debug('create', props);
- _context3.next = 4;
- return adapter.create(User, props);
-
- case 4:
- user = _context3.sent;
-
- assert.debug('created', JSON.stringify(user, null, 2));
-
- props = { email: 'foo@test.com', userId: user[User.idAttribute] };
- assert.debug('create', props);
- _context3.next = 10;
- return adapter.create(Profile, props);
-
- case 10:
- profile = _context3.sent;
-
- assert.debug('created', JSON.stringify(profile, null, 2));
-
- props = { content: 'foo', userId: user[User.idAttribute] };
- assert.debug('create', props);
- _context3.next = 16;
- return adapter.create(Post, props);
-
- case 16:
- post = _context3.sent;
-
- assert.debug('created', JSON.stringify(post, null, 2));
-
- props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId };
- assert.debug('create', props);
- _context3.next = 22;
- return adapter.create(Comment, props);
-
- case 22:
- comment = _context3.sent;
-
- assert.debug('created', JSON.stringify(comment, null, 2));
-
- assert.debug('find', props, comment[Comment.idAttribute]);
- _context3.next = 27;
- return adapter.find(Post, post[Post.idAttribute], { 'with': ['user', 'comment', 'comment.user', 'comment.user.profile'] });
-
- case 27:
- post = _context3.sent;
-
- assert.debug('found', JSON.stringify(post, null, 2));
-
- assert.isDefined(post.comments);
- assert.isDefined(post.comments[0].user);
- assert.isDefined(post.comments[0].user.profile);
- assert.isDefined(post.user);
-
- case 33:
- case 'end':
- return _context3.stop();
- }
- }
- }, _callee3, this);
- })));
- });
- };
-
-/***/ },
-/* 3 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
-
- function _asyncToGenerator(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) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
-
- module.exports = 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', { age: 30 });
- _context.next = 4;
- return adapter.findAll(User, { age: 30 });
-
- case 4:
- users = _context.sent;
-
- assert.debug('found', JSON.stringify(users, null, 2));
- assert.equal(users.length, 0);
-
- assert.debug('create', props);
- _context.next = 10;
- return adapter.create(User, props);
-
- case 10:
- user = _context.sent;
-
- assert.debug('created', JSON.stringify(user, null, 2));
- userId = user[User.idAttribute];
-
-
- assert.debug('findAll', { name: 'John' });
- _context.next = 16;
- return adapter.findAll(User, { name: 'John' });
-
- case 16:
- users2 = _context.sent;
-
- assert.debug('found', JSON.stringify(users2, null, 2));
- assert.equal(users2.length, 1);
- assert.equal(users2[0][User.idAttribute], userId);
- assert.equal(users2[0].name, 'John');
-
- case 21:
- case 'end':
- return _context.stop();
- }
- }
- }, _callee, this);
- })));
-
- if (options.features === 'all' || options.features.indexOf('inOp') !== -1) {
- it('should filter users using the "in" operator', _asyncToGenerator(regeneratorRuntime.mark(function _callee2() {
- var users, user, id, users2, destroyedUser;
- return regeneratorRuntime.wrap(function _callee2$(_context2) {
- while (1) {
- switch (_context2.prev = _context2.next) {
- case 0:
- _context2.next = 2;
- return adapter.findAll(User, {
- where: {
- age: {
- 'in': [30]
- }
- }
- });
-
- case 2:
- users = _context2.sent;
-
- assert.equal(users.length, 0);
-
- _context2.next = 6;
- return adapter.create(User, { name: 'John' });
-
- case 6:
- user = _context2.sent;
- id = user.id;
- _context2.next = 10;
- return adapter.findAll(User, { name: 'John' });
-
- case 10:
- users2 = _context2.sent;
-
- assert.equal(users2.length, 1);
- assert.equal(users2[0].id, id);
- assert.equal(users2[0].name, 'John');
-
- _context2.next = 16;
- return adapter.destroy(User, id);
-
- case 16:
- destroyedUser = _context2.sent;
-
- assert.isFalse(!!destroyedUser);
-
- case 18:
- case 'end':
- return _context2.stop();
- }
- }
- }, _callee2, this);
- })));
- }
-
- if (options.features === 'all' || options.features.indexOf('likeOp') !== -1) {
- it('should filter users using the "like" operator', _asyncToGenerator(regeneratorRuntime.mark(function _callee3() {
- var users, user, id, users2, destroyedUser;
- return regeneratorRuntime.wrap(function _callee3$(_context3) {
- while (1) {
- switch (_context3.prev = _context3.next) {
- case 0:
- _context3.next = 2;
- return adapter.findAll(User, {
- where: {
- name: {
- 'like': '%J%'
- }
- }
- });
-
- case 2:
- users = _context3.sent;
-
- assert.equal(users.length, 0);
-
- _context3.next = 6;
- return adapter.create(User, { name: 'John' });
-
- case 6:
- user = _context3.sent;
- id = user.id;
- _context3.next = 10;
- return adapter.findAll(User, {
- where: {
- name: {
- 'like': '%J%'
- }
- }
- });
-
- case 10:
- users2 = _context3.sent;
-
- assert.equal(users2.length, 1);
- assert.equal(users2[0].id, id);
- assert.equal(users2[0].name, 'John');
-
- _context3.next = 16;
- return adapter.destroy(User, id);
-
- case 16:
- destroyedUser = _context3.sent;
-
- assert.isFalse(!!destroyedUser);
-
- case 18:
- case 'end':
- return _context3.stop();
- }
- }
- }, _callee3, this);
- })));
- }
-
- if (options.features === 'all' || options.features.indexOf('filterOpNotFound') !== -1) {
- it('should throw "Operator not found" error', _asyncToGenerator(regeneratorRuntime.mark(function _callee4() {
- return regeneratorRuntime.wrap(function _callee4$(_context4) {
- while (1) {
- switch (_context4.prev = _context4.next) {
- case 0:
- assert.throw(function () {
- return adapter.findAll(User, {
- where: {
- name: {
- op: 'John'
- }
- }
- });
- }, Error, 'Operator not found');
-
- case 1:
- case 'end':
- return _context4.stop();
- }
- }
- }, _callee4, this);
- })));
- }
-
- 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:
- props = { name: 'John' };
-
- assert.debug('create', props);
- _context5.next = 4;
- return adapter.create(User, props);
-
- case 4:
- user = _context5.sent;
-
- assert.debug('created', JSON.stringify(user, null, 2));
-
- props = { email: 'foo@test.com', userId: user[User.idAttribute] };
- assert.debug('create', props);
- _context5.next = 10;
- return adapter.create(Profile, props);
-
- case 10:
- profile = _context5.sent;
-
- assert.debug('created', JSON.stringify(profile, null, 2));
-
- props = { content: 'foo', userId: user[User.idAttribute] };
- assert.debug('create', props);
- _context5.next = 16;
- return adapter.create(Post, props);
-
- case 16:
- post = _context5.sent;
-
- assert.debug('created', JSON.stringify(post, null, 2));
-
- props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId };
- assert.debug('create', props);
- _context5.next = 22;
- return adapter.create(Comment, props);
-
- case 22:
- comment = _context5.sent;
-
- assert.debug('created', JSON.stringify(comment, null, 2));
-
- props = { name: 'Sally' };
- assert.debug('create', props);
- _context5.next = 28;
- return adapter.create(User, props);
-
- case 28:
- user2 = _context5.sent;
-
- assert.debug('created', JSON.stringify(user2, null, 2));
-
- props = { content: 'bar', userId: user2[User.idAttribute] };
- assert.debug('create', props);
- _context5.next = 34;
- return adapter.create(Post, props);
-
- case 34:
- post2 = _context5.sent;
-
- assert.debug('created', JSON.stringify(post2, null, 2));
-
- props = { content: 'test67', postId: post2[Post.idAttribute], userId: post2.userId };
- assert.debug('create', props);
- _context5.next = 40;
- return adapter.create(Comment, props);
-
- case 40:
- comment2 = _context5.sent;
-
- assert.debug('created', JSON.stringify(comment2, null, 2));
-
- assert.debug('findAll');
- _context5.next = 45;
- return adapter.findAll(Comment, {}, { 'with': ['user', 'user.profile', 'post', 'post.user'] });
-
- case 45:
- comments = _context5.sent;
-
- assert.debug('found', JSON.stringify(comments, null, 2));
- assert.isDefined(comments[0].post);
- assert.isDefined(comments[0].post.user);
- assert.isDefined(comments[0].user);
- assert.isDefined(comments[0].user.profile || comments[1].user.profile);
- assert.isDefined(comments[1].post);
- assert.isDefined(comments[1].post.user);
- assert.isDefined(comments[1].user);
-
- case 54:
- case 'end':
- return _context5.stop();
- }
- }
- }, _callee5, this);
- })));
-
- it('should load hasMany and belongsTo relations', _asyncToGenerator(regeneratorRuntime.mark(function _callee6() {
- var props, user, profile, post, comment, user2, post2, comment2, posts;
- return regeneratorRuntime.wrap(function _callee6$(_context6) {
- while (1) {
- switch (_context6.prev = _context6.next) {
- case 0:
- props = { name: 'John' };
-
- assert.debug('create', props);
- _context6.next = 4;
- return adapter.create(User, props);
-
- case 4:
- user = _context6.sent;
-
- assert.debug('created', JSON.stringify(user, null, 2));
-
- props = { email: 'foo@test.com', userId: user[User.idAttribute] };
- assert.debug('create', props);
- _context6.next = 10;
- return adapter.create(Profile, props);
-
- case 10:
- profile = _context6.sent;
-
- assert.debug('created', JSON.stringify(profile, null, 2));
-
- props = { content: 'foo', userId: user[User.idAttribute] };
- assert.debug('create', props);
- _context6.next = 16;
- return adapter.create(Post, props);
-
- case 16:
- post = _context6.sent;
-
- assert.debug('created', JSON.stringify(post, null, 2));
-
- props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId };
- assert.debug('create', props);
- _context6.next = 22;
- return adapter.create(Comment, props);
-
- case 22:
- comment = _context6.sent;
-
- assert.debug('created', JSON.stringify(comment, null, 2));
-
- props = { name: 'Sally' };
- assert.debug('create', props);
- _context6.next = 28;
- return adapter.create(User, props);
-
- case 28:
- user2 = _context6.sent;
-
- assert.debug('created', JSON.stringify(user2, null, 2));
-
- props = { content: 'bar', userId: user2[User.idAttribute] };
- assert.debug('create', props);
- _context6.next = 34;
- return adapter.create(Post, props);
-
- case 34:
- post2 = _context6.sent;
-
- assert.debug('created', JSON.stringify(post2, null, 2));
-
- props = { content: 'test67', postId: post2[Post.idAttribute], userId: post2.userId };
- assert.debug('create', props);
- _context6.next = 40;
- return adapter.create(Comment, props);
-
- case 40:
- comment2 = _context6.sent;
-
- assert.debug('created', JSON.stringify(comment2, null, 2));
-
- assert.debug('find');
- _context6.next = 45;
- return adapter.findAll(Post, {}, { 'with': ['user', 'comment', 'comment.user', 'comment.user.profile'] });
-
- case 45:
- posts = _context6.sent;
-
- assert.debug('found', JSON.stringify(posts, null, 2));
- assert.isDefined(posts[0].comments);
- assert.isDefined(posts[0].comments[0].user);
- assert.isDefined(posts[0].comments[0].user.profile || posts[1].comments[0].user.profile);
- assert.isDefined(posts[0].user);
- assert.isDefined(posts[1].comments);
- assert.isDefined(posts[1].comments[0].user);
- assert.isDefined(posts[1].user);
-
- case 54:
- case 'end':
- return _context6.stop();
- }
- }
- }, _callee6, this);
- })));
-
- if (options.features === 'all' || options.features.indexOf('filterOnRelations') !== -1) {
- it('should filter using belongsTo relation', _asyncToGenerator(regeneratorRuntime.mark(function _callee7() {
- var profile1, user1, post1, user2, post2, users;
- return regeneratorRuntime.wrap(function _callee7$(_context7) {
- while (1) {
- switch (_context7.prev = _context7.next) {
- case 0:
- _context7.next = 2;
- return adapter.create(Profile, { email: 'foo@test.com' });
-
- case 2:
- profile1 = _context7.sent;
- _context7.next = 5;
- return adapter.create(User, { name: 'John', profileId: profile1.id });
-
- case 5:
- user1 = _context7.sent;
- _context7.next = 8;
- return adapter.create(Post, { content: 'foo', userId: user1.id });
-
- case 8:
- post1 = _context7.sent;
- _context7.next = 11;
- return adapter.create(Comment, { content: 'test1', postId: post1.id, userId: post1.userId });
-
- case 11:
- _context7.next = 13;
- return adapter.create(User, { name: 'Sally' });
-
- case 13:
- user2 = _context7.sent;
- _context7.next = 16;
- return adapter.create(Post, { content: 'bar', userId: user2.id });
-
- case 16:
- post2 = _context7.sent;
- _context7.next = 19;
- return adapter.create(Comment, { content: 'test2', postId: post2.id, userId: post2.userId });
-
- case 19:
- _context7.next = 21;
- return adapter.findAll(User, { 'profile.email': 'foo@test.com' });
-
- case 21:
- users = _context7.sent;
-
- assert.equal(users.length, 1);
- assert.equal(users[0].profileId, profile1.id);
- assert.equal(users[0].name, 'John');
-
- case 25:
- case 'end':
- return _context7.stop();
- }
- }
- }, _callee7, this);
- })));
-
- it('should filter through multiple hasOne/belongsTo relations', _asyncToGenerator(regeneratorRuntime.mark(function _callee8() {
- var profile1, user1, post1, profile2, user2, post2, comments;
- return regeneratorRuntime.wrap(function _callee8$(_context8) {
- while (1) {
- switch (_context8.prev = _context8.next) {
- case 0:
- _context8.next = 2;
- return adapter.create(Profile, { email: 'foo@test.com' });
-
- case 2:
- profile1 = _context8.sent;
- _context8.next = 5;
- return adapter.create(User, { name: 'John', profileId: profile1.id });
-
- case 5:
- user1 = _context8.sent;
- _context8.next = 8;
- return adapter.create(Post, { content: 'foo', userId: user1.id });
-
- case 8:
- post1 = _context8.sent;
- _context8.next = 11;
- return adapter.create(Comment, { content: 'test1', postId: post1.id, userId: post1.userId });
-
- case 11:
- _context8.next = 13;
- return adapter.create(Profile, { email: 'bar@test.com' });
-
- case 13:
- profile2 = _context8.sent;
- _context8.next = 16;
- return adapter.create(User, { name: 'Sally', profileId: profile2.id });
-
- case 16:
- user2 = _context8.sent;
- _context8.next = 19;
- return adapter.create(Post, { content: 'bar', userId: user2.id });
-
- case 19:
- post2 = _context8.sent;
- _context8.next = 22;
- return adapter.create(Comment, { content: 'test2', postId: post2.id, userId: post2.userId });
-
- case 22:
- _context8.next = 24;
- return adapter.findAll(Comment, { 'user.profile.email': 'foo@test.com' });
-
- case 24:
- comments = _context8.sent;
-
- assert.equal(comments.length, 1);
- assert.equal(comments[0].userId, user1.id);
- assert.equal(comments[0].content, 'test1');
-
- case 28:
- case 'end':
- return _context8.stop();
- }
- }
- }, _callee8, this);
- })));
-
- it('should filter using multiple hasOne/belongsTo relations', _asyncToGenerator(regeneratorRuntime.mark(function _callee9() {
- var profile1, user1, post1, profile2, user2, post2, comments;
- return regeneratorRuntime.wrap(function _callee9$(_context9) {
- while (1) {
- switch (_context9.prev = _context9.next) {
- case 0:
- _context9.next = 2;
- return adapter.create(Profile, { email: 'foo@test.com' });
-
- case 2:
- profile1 = _context9.sent;
- _context9.next = 5;
- return adapter.create(User, { name: 'John', profileId: profile1.id });
-
- case 5:
- user1 = _context9.sent;
- _context9.next = 8;
- return adapter.create(Post, { content: 'foo', userId: user1.id });
-
- case 8:
- post1 = _context9.sent;
- _context9.next = 11;
- return adapter.create(Comment, { content: 'test1', postId: post1.id, userId: post1.userId });
-
- case 11:
- _context9.next = 13;
- return adapter.create(Profile, { email: 'bar@test.com' });
-
- case 13:
- profile2 = _context9.sent;
- _context9.next = 16;
- return adapter.create(User, { name: 'Sally', profileId: profile2.id });
-
- case 16:
- user2 = _context9.sent;
- _context9.next = 19;
- return adapter.create(Post, { content: 'bar', userId: user2.id });
-
- case 19:
- post2 = _context9.sent;
- _context9.next = 22;
- return adapter.create(Comment, { content: 'test2', postId: post2.id, userId: post2.userId });
-
- case 22:
- _context9.next = 24;
- return adapter.findAll(Comment, { 'user.name': 'John', 'user.profile.email': 'foo@test.com' });
-
- case 24:
- comments = _context9.sent;
-
- assert.equal(comments.length, 1);
- assert.equal(comments[0].userId, user1.id);
- assert.equal(comments[0].content, 'test1');
-
- case 28:
- case 'end':
- return _context9.stop();
- }
- }
- }, _callee9, this);
- })));
- }
-
- it('should allow passing limit and offset as strings', _asyncToGenerator(regeneratorRuntime.mark(function _callee10() {
- return regeneratorRuntime.wrap(function _callee10$(_context10) {
- while (1) {
- switch (_context10.prev = _context10.next) {
- case 0:
- _context10.next = 2;
- return adapter.findAll(User, { limit: '10', offset: '20' });
-
- case 2:
- case 'end':
- return _context10.stop();
- }
- }
- }, _callee10, this);
- })));
- });
- };
-
-/***/ },
-/* 4 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
-
- function _asyncToGenerator(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) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
-
- module.exports = 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, 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', props);
- _context.next = 6;
- return adapter.create(User, props);
-
- case 6:
- user = _context.sent;
-
- assert.debug('created', JSON.stringify(user, null, 2));
-
- assert.debug('destroy', user[User.idAttribute]);
- _context.next = 11;
- return adapter.destroy(User, user[User.idAttribute]);
-
- case 11:
- destroyedUser = _context.sent;
-
- assert.debug('destroyed', JSON.stringify(destroyedUser, null, 2));
- assert.isFalse(!!destroyedUser);
-
- _context.prev = 14;
- _context.next = 17;
- return adapter.find(User, user[User.idAttribute]);
-
- case 17:
- throw new Error('Should not have reached here!');
-
- case 20:
- _context.prev = 20;
- _context.t0 = _context['catch'](14);
-
- assert.equal(_context.t0.message, 'Not Found!');
-
- case 23:
- case 'end':
- return _context.stop();
- }
- }
- }, _callee, this, [[14, 20]]);
- })));
- });
- };
-
-/***/ },
-/* 5 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
-
- function _asyncToGenerator(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) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
-
- module.exports = 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, 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', props);
- _context.next = 6;
- return adapter.create(User, props);
-
- case 6:
- user = _context.sent;
-
- assert.debug('created', JSON.stringify(user, null, 2));
-
- assert.debug('findAll', props);
- _context.next = 11;
- return adapter.findAll(User, props);
-
- case 11:
- foundUsers = _context.sent;
-
- assert.debug('found', JSON.stringify(foundUsers, null, 2));
- assert.equal(foundUsers.length, 1);
- assert.equal(foundUsers[0][User.idAttribute], user[User.idAttribute]);
- assert.equal(foundUsers[0].name, 'John');
-
- assert.debug('destroyAll', props);
- _context.next = 19;
- return adapter.destroyAll(User, props);
-
- case 19:
- destroyedUsers = _context.sent;
-
- assert.debug('destroyed', JSON.stringify(destroyedUsers, null, 2));
-
- assert.debug('findAll', props);
- _context.next = 24;
- return adapter.findAll(User, props);
-
- case 24:
- foundUsers = _context.sent;
-
- assert.debug('found', JSON.stringify(foundUsers, null, 2));
- assert.equal(foundUsers.length, 0);
-
- case 27:
- case 'end':
- return _context.stop();
- }
- }
- }, _callee, this);
- })));
- });
- };
-
-/***/ },
-/* 6 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
-
- function _asyncToGenerator(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) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
-
- module.exports = 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', props);
- _context.next = 6;
- return adapter.create(User, props);
-
- case 6:
- user = _context.sent;
-
- assert.debug('created', JSON.stringify(user, null, 2));
-
- 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[User.idAttribute]);
- _context.next = 13;
- return adapter.find(User, user[User.idAttribute]);
-
- case 13:
- foundUser = _context.sent;
-
- assert.debug('found', JSON.stringify(foundUser, null, 2));
-
- 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[User.idAttribute], { name: 'Johnny' });
- _context.next = 21;
- return adapter.update(User, user[User.idAttribute], { name: 'Johnny' });
-
- case 21:
- updatedUser = _context.sent;
-
- assert.debug('found', JSON.stringify(updatedUser, null, 2));
- assert.equal(updatedUser.name, 'Johnny');
- assert.equal(updatedUser[User.idAttribute], user[User.idAttribute]);
-
- assert.debug('find', user[User.idAttribute]);
- _context.next = 28;
- return adapter.find(User, user[User.idAttribute]);
-
- case 28:
- foundUser = _context.sent;
-
- assert.debug('found', JSON.stringify(foundUser, null, 2));
- assert.equal(foundUser.name, 'Johnny');
- assert.equal(foundUser[User.idAttribute], user[User.idAttribute]);
-
- case 32:
- case 'end':
- return _context.stop();
- }
- }
- }, _callee, this);
- })));
- });
- };
-
-/***/ },
-/* 7 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
-
- function _asyncToGenerator(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) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
-
- module.exports = 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', props);
- _context.next = 6;
- return adapter.create(User, props);
-
- case 6:
- user1 = _context.sent;
-
- assert.debug('created', JSON.stringify(user1, null, 2));
- userId1 = user1[User.idAttribute];
-
-
- props = { name: 'John', age: 30 };
-
- assert.debug('create', props);
- _context.next = 13;
- return adapter.create(User, props);
-
- case 13:
- user2 = _context.sent;
-
- assert.debug('created', JSON.stringify(user2, null, 2));
- userId2 = user2[User.idAttribute];
-
-
- assert.debug('findAll', { name: 'John' });
- _context.next = 19;
- return adapter.findAll(User, { name: 'John' });
-
- case 19:
- users = _context.sent;
-
- assert.debug('found', JSON.stringify(users, null, 2));
- 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', { name: 'Johnny' }, { name: 'John' });
- _context.next = 31;
- return adapter.updateAll(User, { name: 'Johnny' }, { name: 'John' });
-
- case 31:
- users2 = _context.sent;
-
- assert.debug('updated', JSON.stringify(users2, null, 2));
- 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', { name: 'John' });
- _context.next = 43;
- return adapter.findAll(User, { name: 'John' });
-
- case 43:
- users3 = _context.sent;
-
- assert.debug('found', JSON.stringify(users3, null, 2));
- assert.equalObjects(users3, []);
- assert.equal(users3.length, 0);
-
- assert.debug('findAll', { name: 'Johnny' });
- _context.next = 50;
- return adapter.findAll(User, { name: 'Johnny' });
-
- case 50:
- users4 = _context.sent;
-
- assert.debug('found', JSON.stringify(users4, null, 2));
- 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);
- })));
- });
- };
-
-/***/ }
-/******/ ])
-});
-;
+(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 = 'default' in sinon$1 ? sinon$1['default'] : sinon$1;
+
+ var babelHelpers = {};
+ babelHelpers.typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
+ return typeof obj;
+ } : function (obj) {
+ return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj;
+ };
+
+ babelHelpers.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) {
+ return step("next", value);
+ }, function (err) {
+ return step("throw", err);
+ });
+ }
+ }
+
+ return step("next");
+ });
+ };
+ };
+
+ babelHelpers.classCallCheck = function (instance, Constructor) {
+ if (!(instance instanceof Constructor)) {
+ throw new TypeError("Cannot call a class as a function");
+ }
+ };
+
+ babelHelpers.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;
+ };
+ }();
+
+ babelHelpers.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;
+ };
+
+ babelHelpers.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;
+ };
+
+ babelHelpers.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;
+ };
+
+ babelHelpers;
+
+ /* global assert:true */
+ function afterCreateTest (options) {
+ describe('Adapter#afterCreate', function () {
+ it('should exist', function () {
+ assert.equal(babelHelpers.typeof(this.$$adapter.afterCreate), 'function', 'adapter should have a "afterCreate" method');
+ });
+ it('should call afterCreate', babelHelpers.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', 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');
+
+ case 18:
+ case 'end':
+ return _context.stop();
+ }
+ }
+ }, _callee, this);
+ })));
+ it('should allow re-assignment', babelHelpers.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', 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');
+
+ case 17:
+ case 'end':
+ return _context2.stop();
+ }
+ }
+ }, _callee2, this);
+ })));
+ it('should allow returning a promise', babelHelpers.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', 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');
+
+ case 18:
+ case 'end':
+ return _context3.stop();
+ }
+ }
+ }, _callee3, this);
+ })));
+ it('should allow returning a promise and re-assignment', babelHelpers.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', 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');
+
+ case 17:
+ case 'end':
+ return _context4.stop();
+ }
+ }
+ }, _callee4, this);
+ })));
+ it('should receive raw', babelHelpers.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', 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');
+
+ case 21:
+ case 'end':
+ return _context5.stop();
+ }
+ }
+ }, _callee5, this);
+ })));
+ });
+ }
+
+ /* global assert:true */
+ function afterUpdateTest (options) {
+ describe('Adapter#afterUpdate', function () {
+ it('should exist', function () {
+ assert.equal(babelHelpers.typeof(this.$$adapter.afterUpdate), 'function', 'adapter should have a "afterUpdate" method');
+ });
+ it('should call afterUpdate', babelHelpers.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', 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');
+
+ case 30:
+ case 'end':
+ return _context.stop();
+ }
+ }
+ }, _callee, this);
+ })));
+ it('should receive raw', babelHelpers.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', 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');
+
+ case 33:
+ case 'end':
+ return _context2.stop();
+ }
+ }
+ }, _callee2, this);
+ })));
+ it('should allow re-assignment', babelHelpers.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', 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');
+
+ case 29:
+ case 'end':
+ return _context3.stop();
+ }
+ }
+ }, _callee3, this);
+ })));
+ it('should allow returning a promise', babelHelpers.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', 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');
+
+ case 30:
+ case 'end':
+ return _context4.stop();
+ }
+ }
+ }, _callee4, this);
+ })));
+ it('should allow returning a promise and re-assignment', babelHelpers.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', 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');
+
+ case 29:
+ case 'end':
+ return _context5.stop();
+ }
+ }
+ }, _callee5, this);
+ })));
+ });
+ }
+
+ /* global assert:true */
+ function beforeCreateTest (options) {
+ describe('Adapter#beforeCreate', function () {
+ it('should exist', function () {
+ assert.equal(babelHelpers.typeof(this.$$adapter.beforeCreate), 'function', 'adapter should have a "beforeCreate" method');
+ });
+ it('should call beforeCreate', babelHelpers.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', 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');
+
+ case 17:
+ case 'end':
+ return _context.stop();
+ }
+ }
+ }, _callee, this);
+ })));
+ it('should allow re-assignment', babelHelpers.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', 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');
+
+ case 17:
+ case 'end':
+ return _context2.stop();
+ }
+ }
+ }, _callee2, this);
+ })));
+ it('should allow returning a promise', babelHelpers.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', 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');
+
+ case 17:
+ case 'end':
+ return _context3.stop();
+ }
+ }
+ }, _callee3, this);
+ })));
+ it('should allow returning a promise and re-assignment', babelHelpers.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', 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');
+
+ case 17:
+ case 'end':
+ return _context4.stop();
+ }
+ }
+ }, _callee4, this);
+ })));
+ });
+ }
+
+ /* global assert:true */
+ function beforeUpdateTest (options) {
+ describe('Adapter#beforeUpdate', function () {
+ it('should exist', function () {
+ assert.equal(babelHelpers.typeof(this.$$adapter.beforeUpdate), 'function', 'adapter should have a "beforeUpdate" method');
+ });
+ it('should call beforeUpdate', babelHelpers.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', 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], 'beforeCreate should have received options');
+
+ case 26:
+ case 'end':
+ return _context.stop();
+ }
+ }
+ }, _callee, this);
+ })));
+ it('should allow re-assignment', babelHelpers.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', 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], 'beforeCreate should have received options');
+
+ case 26:
+ case 'end':
+ return _context2.stop();
+ }
+ }
+ }, _callee2, this);
+ })));
+ it('should allow returning a promise', babelHelpers.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', 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], 'beforeCreate should have received options');
+
+ case 26:
+ case 'end':
+ return _context3.stop();
+ }
+ }
+ }, _callee3, this);
+ })));
+ it('should allow returning a promise and re-assignment', babelHelpers.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', 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], 'beforeCreate should have received options');
+
+ case 26:
+ case 'end':
+ return _context4.stop();
+ }
+ }
+ }, _callee4, this);
+ })));
+ });
+ }
+
+ /* global assert:true */
+ function countTest (options) {
+ describe('Adapter#count', function () {
+ it('should exist', function () {
+ assert.equal(babelHelpers.typeof(this.$$adapter.count), 'function', 'adapter should have a "count" method');
+ });
+ it('should count users', babelHelpers.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', babelHelpers.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 */
+ function createTest (options) {
+ describe('Adapter#create', function () {
+ it('should exist', function () {
+ assert.equal(babelHelpers.typeof(this.$$adapter.create), 'function', 'adapter should have a "create" method');
+ });
+ it('should create a user', babelHelpers.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 */
+ function createManyTest (options) {
+ describe('Adapter#createMany', function () {
+ it('should exist', function () {
+ assert.equal(babelHelpers.typeof(this.$$adapter.createMany), 'function', 'adapter should have a "createMany" method');
+ });
+ it('should create multiple users', babelHelpers.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 */
+ function destroyTest (options) {
+ describe('Adapter#destroy', function () {
+ it('should exist', function () {
+ assert.equal(babelHelpers.typeof(this.$$adapter.destroy), 'function', 'adapter should have a "destroy" method');
+ });
+ it('should destroy a user', babelHelpers.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', babelHelpers.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', babelHelpers.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', babelHelpers.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', babelHelpers.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 */
+ function destroyAllTest (options) {
+ describe('Adapter#destroyAll', function () {
+ it('should exist', function () {
+ assert.equal(babelHelpers.typeof(this.$$adapter.destroyAll), 'function', 'adapter should have a "destroyAll" method');
+ });
+ it('should destroy all users', babelHelpers.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', babelHelpers.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', babelHelpers.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', babelHelpers.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 */
+ function extendTest (options) {
+ describe('Adapter.extend', function () {
+ it('should exist', function () {
+ assert.equal(babelHelpers.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(babelHelpers.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) {
+ babelHelpers.inherits(SubAdapter, _Adapter);
+
+ function SubAdapter() {
+ babelHelpers.classCallCheck(this, SubAdapter);
+ return babelHelpers.possibleConstructorReturn(this, Object.getPrototypeOf(SubAdapter).apply(this, arguments));
+ }
+
+ babelHelpers.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(babelHelpers.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 */
+ function findTest (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(babelHelpers.typeof(adapter.find), 'function', 'adapter should have a "find" method');
+ });
+
+ it('should find a user', babelHelpers.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(babelHelpers.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', babelHelpers.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', babelHelpers.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', babelHelpers.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', babelHelpers.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', babelHelpers.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)', babelHelpers.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', babelHelpers.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)', babelHelpers.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')) {
+ var _tagIds;
+
+ it('should load hasMany localKeys (array) relations', babelHelpers.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', babelHelpers.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', babelHelpers.asyncToGenerator(regeneratorRuntime.mark(function _callee12() {
+ 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 = {}, babelHelpers.defineProperty(_tagIds, tag[Tag.idAttribute], true), babelHelpers.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', babelHelpers.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 */
+ function findAllTest (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(babelHelpers.typeof(adapter.findAll), 'function', 'adapter should have a "findAll" method');
+ });
+
+ it('should filter users', babelHelpers.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);
+ })));
+
+ if (options.hasFeature('findAllInOp')) {
+ it('should filter users using the "in" operator', babelHelpers.asyncToGenerator(regeneratorRuntime.mark(function _callee2() {
+ var users, user, id, users2;
+ return regeneratorRuntime.wrap(function _callee2$(_context2) {
+ while (1) {
+ switch (_context2.prev = _context2.next) {
+ case 0:
+ _context2.next = 2;
+ return adapter.findAll(User, {
+ where: {
+ age: {
+ 'in': [30]
+ }
+ }
+ });
+
+ case 2:
+ users = _context2.sent;
+
+ assert.equal(users.length, 0, 'users.length');
+
+ _context2.next = 6;
+ return adapter.create(User, { name: 'John' });
+
+ case 6:
+ user = _context2.sent;
+ id = user[User.idAttribute];
+ _context2.next = 10;
+ return adapter.findAll(User, { name: 'John' });
+
+ case 10:
+ users2 = _context2.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 _context2.stop();
+ }
+ }
+ }, _callee2, this);
+ })));
+ }
+
+ if (options.hasFeature('findAllLikeOp')) {
+ it('should filter users using the "like" operator', babelHelpers.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: {
+ name: {
+ 'like': '%J%'
+ }
+ }
+ });
+
+ case 2:
+ users = _context3.sent;
+
+ assert.equal(users.length, 0);
+
+ _context3.next = 6;
+ return adapter.create(User, { name: 'John' });
+
+ case 6:
+ user = _context3.sent;
+ id = user.id;
+ _context3.next = 10;
+ return adapter.findAll(User, {
+ where: {
+ name: {
+ 'like': '%J%'
+ }
+ }
+ });
+
+ case 10:
+ users2 = _context3.sent;
+
+ assert.equal(users2.length, 1);
+ assert.equal(users2[0].id, id);
+ assert.equal(users2[0].name, 'John');
+
+ case 14:
+ case 'end':
+ return _context3.stop();
+ }
+ }
+ }, _callee3, 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', babelHelpers.asyncToGenerator(regeneratorRuntime.mark(function _callee4() {
+ var props, user, profile, post, comment, user2, post2, comment2, comments;
+ return regeneratorRuntime.wrap(function _callee4$(_context4) {
+ while (1) {
+ switch (_context4.prev = _context4.next) {
+ case 0:
+ this.toClear.push('Post');
+ this.toClear.push('Profile');
+ this.toClear.push('Comment');
+ props = { name: 'John' };
+
+ 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);
+
+ props = { email: 'foo@test.com', userId: user[User.idAttribute] };
+ assert.debug('create', Profile.name, props);
+ _context4.next = 13;
+ return adapter.create(Profile, props);
+
+ case 13:
+ profile = _context4.sent;
+
+ assert.debug('created', Profile.name, profile);
+
+ props = { content: 'foo', userId: user[User.idAttribute] };
+ assert.debug('create', Post.name, props);
+ _context4.next = 19;
+ return adapter.create(Post, props);
+
+ case 19:
+ post = _context4.sent;
+
+ assert.debug('created', Post.name, post);
+
+ props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId };
+ assert.debug('create', Comment.name, props);
+ _context4.next = 25;
+ return adapter.create(Comment, props);
+
+ case 25:
+ comment = _context4.sent;
+
+ assert.debug('created', Comment.name, comment);
+
+ props = { name: 'Sally' };
+ assert.debug('create', User.name, props);
+ _context4.next = 31;
+ return adapter.create(User, props);
+
+ case 31:
+ user2 = _context4.sent;
+
+ assert.debug('created', User.name, user2);
+
+ props = { content: 'bar', userId: user2[User.idAttribute] };
+ assert.debug('create', Post.name, props);
+ _context4.next = 37;
+ return adapter.create(Post, props);
+
+ case 37:
+ post2 = _context4.sent;
+
+ assert.debug('created', Post.name, post2);
+
+ props = { content: 'test67', postId: post2[Post.idAttribute], userId: post2.userId };
+ assert.debug('create', Comment.name, props);
+ _context4.next = 43;
+ return adapter.create(Comment, props);
+
+ case 43:
+ comment2 = _context4.sent;
+
+ assert.debug('created', Comment.name, comment2);
+
+ assert.debug('findAll', Comment.name, {});
+ _context4.next = 48;
+ return adapter.findAll(Comment, {}, { 'with': ['user', 'post'] });
+
+ case 48:
+ comments = _context4.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 _context4.stop();
+ }
+ }
+ }, _callee4, this);
+ })));
+
+ it('should load belongsTo relations and filter sub queries', babelHelpers.asyncToGenerator(regeneratorRuntime.mark(function _callee5() {
+ var props, user, user2, post, post2, post3, post4, users;
+ return regeneratorRuntime.wrap(function _callee5$(_context5) {
+ while (1) {
+ switch (_context5.prev = _context5.next) {
+ case 0:
+ this.toClear.push('Post');
+ this.toClear.push('Comment');
+ props = { name: 'John' };
+
+ assert.debug('create', User.name, props);
+ _context5.next = 6;
+ return adapter.create(User, props);
+
+ case 6:
+ user = _context5.sent;
+
+ assert.debug('created', User.name, user);
+
+ props = { name: 'Sally' };
+ assert.debug('create', User.name, props);
+ _context5.next = 12;
+ return adapter.create(User, props);
+
+ case 12:
+ user2 = _context5.sent;
+
+ assert.debug('created', User.name, user);
+
+ props = { status: 'draft', userId: user[User.idAttribute] };
+ assert.debug('create', Post.name, props);
+ _context5.next = 18;
+ return adapter.create(Post, props);
+
+ case 18:
+ post = _context5.sent;
+
+ assert.debug('created', Post.name, post);
+
+ props = { status: 'published', userId: user[User.idAttribute] };
+ assert.debug('create', Post.name, props);
+ _context5.next = 24;
+ return adapter.create(Post, props);
+
+ case 24:
+ post2 = _context5.sent;
+
+ assert.debug('created', Post.name, post2);
+
+ props = { status: 'draft', userId: user2[User.idAttribute] };
+ assert.debug('create', Post.name, props);
+ _context5.next = 30;
+ return adapter.create(Post, props);
+
+ case 30:
+ post3 = _context5.sent;
+
+ assert.debug('created', Post.name, post3);
+
+ props = { status: 'published', userId: user2[User.idAttribute] };
+ assert.debug('create', Post.name, props);
+ _context5.next = 36;
+ return adapter.create(Post, props);
+
+ case 36:
+ post4 = _context5.sent;
+
+ assert.debug('created', Post.name, post4);
+
+ assert.debug('findAll', User.name, babelHelpers.defineProperty({}, User.idAttribute, user[User.idAttribute]));
+ _context5.next = 41;
+ return adapter.findAll(User, babelHelpers.defineProperty({}, User.idAttribute, user[User.idAttribute]), { 'with': ['post'] });
+
+ case 41:
+ users = _context5.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, babelHelpers.defineProperty({}, User.idAttribute, user[User.idAttribute]));
+ _context5.next = 49;
+ return adapter.findAll(User, babelHelpers.defineProperty({}, User.idAttribute, user[User.idAttribute]), { 'with': [{
+ relation: 'post',
+ query: {
+ status: 'published'
+ }
+ }] });
+
+ case 49:
+ users = _context5.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, babelHelpers.defineProperty({}, User.idAttribute, user[User.idAttribute]));
+ _context5.next = 57;
+ return adapter.findAll(User, babelHelpers.defineProperty({}, User.idAttribute, user[User.idAttribute]), { 'with': [{
+ relation: 'post',
+ replace: true,
+ query: {
+ status: 'published'
+ }
+ }] });
+
+ case 57:
+ users = _context5.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 _context5.stop();
+ }
+ }
+ }, _callee5, this);
+ })));
+ }
+
+ if (options.hasFeature('findAllBelongsToNested')) {
+ it('should load belongsTo relations (nested)', babelHelpers.asyncToGenerator(regeneratorRuntime.mark(function _callee6() {
+ var props, user, profile, post, comment, user2, post2, comment2, comments;
+ return regeneratorRuntime.wrap(function _callee6$(_context6) {
+ while (1) {
+ switch (_context6.prev = _context6.next) {
+ case 0:
+ this.toClear.push('Post');
+ this.toClear.push('Profile');
+ this.toClear.push('Comment');
+ props = { name: 'John' };
+
+ assert.debug('create', User.name, props);
+ _context6.next = 7;
+ return adapter.create(User, props);
+
+ case 7:
+ user = _context6.sent;
+
+ assert.debug('created', User.name, user);
+
+ props = { email: 'foo@test.com', userId: user[User.idAttribute] };
+ assert.debug('create', Profile.name, props);
+ _context6.next = 13;
+ return adapter.create(Profile, props);
+
+ case 13:
+ profile = _context6.sent;
+
+ assert.debug('created', Profile.name, profile);
+
+ props = { content: 'foo', userId: user[User.idAttribute] };
+ assert.debug('create', Post.name, props);
+ _context6.next = 19;
+ return adapter.create(Post, props);
+
+ case 19:
+ post = _context6.sent;
+
+ assert.debug('created', Post.name, post);
+
+ props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId };
+ assert.debug('create', Comment.name, props);
+ _context6.next = 25;
+ return adapter.create(Comment, props);
+
+ case 25:
+ comment = _context6.sent;
+
+ assert.debug('created', Comment.name, comment);
+
+ props = { name: 'Sally' };
+ assert.debug('create', User.name, props);
+ _context6.next = 31;
+ return adapter.create(User, props);
+
+ case 31:
+ user2 = _context6.sent;
+
+ assert.debug('created', User.name, user2);
+
+ props = { content: 'bar', userId: user2[User.idAttribute] };
+ assert.debug('create', Post.name, props);
+ _context6.next = 37;
+ return adapter.create(Post, props);
+
+ case 37:
+ post2 = _context6.sent;
+
+ assert.debug('created', Post.name, post2);
+
+ props = { content: 'test67', postId: post2[Post.idAttribute], userId: post2.userId };
+ assert.debug('create', Comment.name, props);
+ _context6.next = 43;
+ return adapter.create(Comment, props);
+
+ case 43:
+ comment2 = _context6.sent;
+
+ assert.debug('created', Comment.name, comment2);
+
+ assert.debug('findAll', Comment.name, {});
+ _context6.next = 48;
+ return adapter.findAll(Comment, {}, { 'with': ['user', 'user.profile', 'post', 'post.user'] });
+
+ case 48:
+ comments = _context6.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 _context6.stop();
+ }
+ }
+ }, _callee6, this);
+ })));
+ }
+
+ if (options.hasFeature('findAllBelongsToHasMany')) {
+ it('should load hasMany and belongsTo relations', babelHelpers.asyncToGenerator(regeneratorRuntime.mark(function _callee7() {
+ var props, user, profile, post, comment, user2, post2, comment2, posts;
+ 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('find', Post.name, {});
+ _context7.next = 48;
+ return adapter.findAll(Post, {}, { 'with': ['user', 'comment'] });
+
+ case 48:
+ posts = _context7.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 _context7.stop();
+ }
+ }
+ }, _callee7, this);
+ })));
+ }
+
+ if (options.hasFeature('findAllBelongsToHasManyNested')) {
+ it('should load hasMany and belongsTo relations', babelHelpers.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', 'comment.user', 'comment.user.profile'] });
+
+ case 48:
+ posts = _context8.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 _context8.stop();
+ }
+ }
+ }, _callee8, this);
+ })));
+ }
+
+ if (options.hasFeature('filterOnRelations')) {
+ it('should filter using belongsTo relation', babelHelpers.asyncToGenerator(regeneratorRuntime.mark(function _callee9() {
+ var profile1, user1, post1, user2, post2, users;
+ 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');
+ _context9.next = 5;
+ return adapter.create(Profile, { email: 'foo@test.com' });
+
+ case 5:
+ profile1 = _context9.sent;
+ _context9.next = 8;
+ return adapter.create(User, { name: 'John', profileId: profile1.id });
+
+ case 8:
+ user1 = _context9.sent;
+ _context9.next = 11;
+ return adapter.create(Post, { content: 'foo', userId: user1.id });
+
+ case 11:
+ post1 = _context9.sent;
+ _context9.next = 14;
+ return adapter.create(Comment, { content: 'test1', postId: post1.id, userId: post1.userId });
+
+ case 14:
+ _context9.next = 16;
+ return adapter.create(User, { name: 'Sally' });
+
+ case 16:
+ user2 = _context9.sent;
+ _context9.next = 19;
+ return adapter.create(Post, { content: 'bar', userId: user2.id });
+
+ case 19:
+ post2 = _context9.sent;
+ _context9.next = 22;
+ return adapter.create(Comment, { content: 'test2', postId: post2.id, userId: post2.userId });
+
+ case 22:
+ _context9.next = 24;
+ return adapter.findAll(User, { 'profile.email': 'foo@test.com' });
+
+ case 24:
+ users = _context9.sent;
+
+ assert.equal(users.length, 1);
+ assert.equal(users[0].profileId, profile1.id);
+ assert.equal(users[0].name, 'John');
+
+ case 28:
+ case 'end':
+ return _context9.stop();
+ }
+ }
+ }, _callee9, this);
+ })));
+
+ it('should filter through multiple hasOne/belongsTo relations', babelHelpers.asyncToGenerator(regeneratorRuntime.mark(function _callee10() {
+ var profile1, user1, post1, profile2, user2, post2, comments;
+ 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(Profile, { email: 'bar@test.com' });
+
+ case 16:
+ profile2 = _context10.sent;
+ _context10.next = 19;
+ return adapter.create(User, { name: 'Sally', profileId: profile2.id });
+
+ case 19:
+ user2 = _context10.sent;
+ _context10.next = 22;
+ return adapter.create(Post, { content: 'bar', userId: user2.id });
+
+ case 22:
+ post2 = _context10.sent;
+ _context10.next = 25;
+ return adapter.create(Comment, { content: 'test2', postId: post2.id, userId: post2.userId });
+
+ case 25:
+ _context10.next = 27;
+ return adapter.findAll(Comment, { 'user.profile.email': 'foo@test.com' });
+
+ case 27:
+ comments = _context10.sent;
+
+ assert.equal(comments.length, 1);
+ assert.equal(comments[0].userId, user1.id);
+ assert.equal(comments[0].content, 'test1');
+
+ case 31:
+ case 'end':
+ return _context10.stop();
+ }
+ }
+ }, _callee10, this);
+ })));
+
+ it('should filter using multiple hasOne/belongsTo relations', babelHelpers.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.name': 'John', '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 allow passing limit and offset as strings', babelHelpers.asyncToGenerator(regeneratorRuntime.mark(function _callee12() {
+ return regeneratorRuntime.wrap(function _callee12$(_context12) {
+ while (1) {
+ switch (_context12.prev = _context12.next) {
+ case 0:
+ _context12.next = 2;
+ return adapter.findAll(User, { limit: '10', offset: '20' });
+
+ case 2:
+ case 'end':
+ return _context12.stop();
+ }
+ }
+ }, _callee12, this);
+ })));
+ });
+ }
+
+ /* global assert:true */
+ function sumTest (options) {
+ describe('Adapter#sum', function () {
+ it('should exist', function () {
+ assert.equal(babelHelpers.typeof(this.$$adapter.sum), 'function', 'adapter should have a "sum" method');
+ });
+ it('should sum users\' age', babelHelpers.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', babelHelpers.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 */
+ function updateTest (options) {
+ describe('Adapter#update', function () {
+ it('should exist', function () {
+ assert.equal(babelHelpers.typeof(this.$$adapter.update), 'function', 'adapter should have a "update" method');
+ });
+ it('should update a user', babelHelpers.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', babelHelpers.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', babelHelpers.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]]);
+ })));
+ });
+ }
+
+ /* global assert:true */
+ function updateAllTest (options) {
+ describe('Adapter#updateAll', function () {
+ it('should exist', function () {
+ assert.equal(babelHelpers.typeof(this.$$adapter.updateAll), 'function', 'adapter should have a "updateAll" method');
+ });
+ it('should update multiple users', babelHelpers.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 */
+ function updateManyTest (options) {
+ describe('Adapter#updateMany', function () {
+ it('should exist', function () {
+ assert.equal(babelHelpers.typeof(this.$$adapter.updateMany), 'function', 'adapter should have a "updateMany" method');
+ });
+ it('should update multiple users', babelHelpers.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: ' + babelHelpers.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(babelHelpers.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
\ No newline at end of file
diff --git a/dist/js-data-adapter-tests.js.map b/dist/js-data-adapter-tests.js.map
index 4aa96ff..c43525e 100644
--- a/dist/js-data-adapter-tests.js.map
+++ b/dist/js-data-adapter-tests.js.map
@@ -1 +1 @@
-{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap 6e27cf557d53a70f58c7","webpack:///./src/index.js","webpack:///./src/create.test.js","webpack:///./src/find.test.js","webpack:///./src/findAll.test.js","webpack:///./src/destroy.test.js","webpack:///./src/destroyAll.test.js","webpack:///./src/update.test.js","webpack:///./src/updateAll.test.js"],"names":[],"mappings":"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","file":"./dist/js-data-adapter-tests.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"TestRunner\"] = factory();\n\telse\n\t\troot[\"TestRunner\"] = factory();\n})(this, function() {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 6e27cf557d53a70f58c7\n **/","assert.equalObjects = function (a, b, m) {\r\n assert.deepEqual(JSON.parse(JSON.stringify(a)), JSON.parse(JSON.stringify(b)), m || (JSON.stringify(a) + ' should be equal to ' + JSON.stringify(b)))\r\n}\r\n\r\nassert.objectsEqual = function (a, b, m) {\r\n assert.deepEqual(JSON.parse(JSON.stringify(a)), JSON.parse(JSON.stringify(b)), m || (JSON.stringify(a) + ' should be equal to ' + JSON.stringify(b)))\r\n}\r\n\r\nlet debug = false\r\n\r\nassert.debug = function (...args) {\r\n if (debug) {\r\n console.log(...args)\r\n }\r\n}\r\n\r\nvar prefix = 'TestRunner.init(options): options'\r\n\r\nmodule.exports = {\r\n init: function (options) {\r\n options = options || {}\r\n debug = !!options.debug\r\n options.methods = options.methods || 'all'\r\n options.features = options.features || 'all'\r\n if (!options.DS || typeof options.DS !== 'function') {\r\n throw new Error(prefix + '.DS: Expected function, Actual: ' + typeof options.DS)\r\n }\r\n if (!options.Adapter || typeof options.Adapter !== 'function') {\r\n throw new Error(prefix + '.Adapter: Expected function, Actual: ' + typeof options.Adapter)\r\n }\r\n beforeEach(function () {\r\n this.$$adapter = new options.Adapter(options.adapterConfig)\r\n this.$$store = new options.DS(options.storeConfig || {\r\n log: false,\r\n debug: false\r\n })\r\n this.$$User = this.$$store.defineResource(options.userConfig || {\r\n name: 'user',\r\n relations: {\r\n hasMany: {\r\n post: {\r\n localField: 'posts',\r\n foreignKey: 'userId'\r\n }\r\n },\r\n hasOne: {\r\n profile: {\r\n localField: 'profile',\r\n foreignKey: 'userId'\r\n },\r\n address: {\r\n localField: 'address',\r\n foreignKey: 'userId'\r\n }\r\n }\r\n }\r\n })\r\n this.$$Profile = this.$$store.defineResource(options.profileConfig || {\r\n name: 'profile',\r\n relations: {\r\n belongsTo: {\r\n user: {\r\n localField: 'user',\r\n localkey: 'userId'\r\n }\r\n }\r\n }\r\n })\r\n this.$$Address = this.$$store.defineResource(options.addressConfig || {\r\n name: 'address',\r\n relations: {\r\n belongsTo: {\r\n user: {\r\n localField: 'user',\r\n localkey: 'userId'\r\n }\r\n }\r\n }\r\n })\r\n this.$$Post = this.$$store.defineResource(options.postConfig || {\r\n name: 'post',\r\n relations: {\r\n belongsTo: {\r\n user: {\r\n localField: 'user',\r\n localKey: 'userId'\r\n }\r\n },\r\n hasMany: {\r\n comment: {\r\n localField: 'comments',\r\n foreignKey: 'postId'\r\n }\r\n }\r\n }\r\n })\r\n this.$$Comment = this.$$store.defineResource(options.commentConfig || {\r\n name: 'comment',\r\n relations: {\r\n belongsTo: {\r\n post: {\r\n localField: 'post',\r\n localKey: 'postId'\r\n },\r\n user: {\r\n localField: 'user',\r\n localKey: 'userId'\r\n }\r\n }\r\n }\r\n })\r\n })\r\n\r\n describe('js-data-adapter-tests', function () {\r\n if (options.methods === 'all' || options.methods.indexOf('create') !== -1) {\r\n require('./create.test')(options)\r\n }\r\n if (options.methods === 'all' || options.methods.indexOf('find') !== -1) {\r\n require('./find.test')(options)\r\n }\r\n if (options.methods === 'all' || options.methods.indexOf('findAll') !== -1) {\r\n require('./findAll.test')(options)\r\n }\r\n if (options.methods === 'all' || options.methods.indexOf('destroy') !== -1) {\r\n require('./destroy.test')(options)\r\n }\r\n if (options.methods === 'all' || options.methods.indexOf('destroyAll') !== -1) {\r\n require('./destroyAll.test')(options)\r\n }\r\n if (options.methods === 'all' || options.methods.indexOf('update') !== -1) {\r\n require('./update.test')(options)\r\n }\r\n if (options.methods === 'all' || options.methods.indexOf('updateAll') !== -1) {\r\n require('./updateAll.test')(options)\r\n }\r\n })\r\n\r\n afterEach(async function () {\r\n await this.$$adapter.destroyAll(this.$$Comment)\r\n await this.$$adapter.destroyAll(this.$$Post)\r\n await this.$$adapter.destroyAll(this.$$User)\r\n await this.$$adapter.destroyAll(this.$$Profile)\r\n await this.$$adapter.destroyAll(this.$$Address)\r\n })\r\n },\r\n assert: assert,\r\n fail: function (msg) {\r\n assert.equal('should not reach this!: ' + msg, 'failure')\r\n },\r\n TYPES_EXCEPT_STRING: [123, 123.123, null, undefined, {}, [], true, false, function () {\r\n }],\r\n TYPES_EXCEPT_STRING_OR_ARRAY: [123, 123.123, null, undefined, {}, true, false, function () {\r\n }],\r\n TYPES_EXCEPT_STRING_OR_NUMBER: [null, undefined, {}, [], true, false, function () {\r\n }],\r\n TYPES_EXCEPT_STRING_OR_OBJECT: [123, 123.123, null, undefined, [], true, false, function () {\r\n }],\r\n TYPES_EXCEPT_STRING_OR_NUMBER_OBJECT: [null, undefined, [], true, false, function () {\r\n }],\r\n TYPES_EXCEPT_STRING_OR_ARRAY_OR_NUMBER: [null, undefined, {}, true, false, function () {\r\n }],\r\n TYPES_EXCEPT_NUMBER: ['string', null, undefined, {}, [], true, false, function () {\r\n }],\r\n TYPES_EXCEPT_OBJECT: ['string', 123, 123.123, null, undefined, true, false, function () {\r\n }],\r\n TYPES_EXCEPT_BOOLEAN: ['string', 123, 123.123, null, undefined, {}, [], function () {\r\n }],\r\n TYPES_EXCEPT_FUNCTION: ['string', 123, 123.123, null, undefined, {}, [], true, false]\r\n}\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/index.js\n **/","module.exports = function (options) {\r\n describe('Adapter#create', function () {\r\n it('should exist', function () {\r\n assert.equal(typeof this.$$adapter.create, 'function', 'adapter should have a \"create\" method')\r\n })\r\n it('should create a user', async function () {\r\n const adapter = this.$$adapter\r\n const User = this.$$User\r\n const props = { name: 'John' }\r\n\r\n assert.debug('create', props)\r\n const user = await adapter.create(User, props)\r\n assert.debug('created', JSON.stringify(user, null, 2))\r\n\r\n assert.equal(user.name, props.name, `name of user should be \"${props.name}\"`)\r\n assert.isDefined(user[User.idAttribute], 'new user should have an id')\r\n\r\n assert.debug('find', user[User.idAttribute])\r\n const foundUser = await adapter.find(User, user[User.idAttribute])\r\n assert.debug('found', JSON.stringify(foundUser, null, 2))\r\n\r\n assert.equal(foundUser.name, props.name, `name of user should be \"${props.name}\"`)\r\n assert.isDefined(foundUser[User.idAttribute], 'new user should have an id')\r\n assert.equal(foundUser[User.idAttribute], user[User.idAttribute])\r\n })\r\n })\r\n}\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/create.test.js\n **/","module.exports = function (options) {\r\n describe('Adapter#find', function () {\r\n var adapter, User, Profile, Post, Comment\r\n\r\n beforeEach(function () {\r\n adapter = this.$$adapter\r\n User = this.$$User\r\n Profile = this.$$Profile\r\n Post = this.$$Post\r\n Comment = this.$$Comment\r\n })\r\n\r\n it('should exist', function () {\r\n assert.equal(typeof adapter.find, 'function', 'adapter should have a \"find\" method')\r\n })\r\n\r\n it('should find a user', async function () {\r\n let props = { name: 'John' }\r\n assert.debug('create', props)\r\n const user = await adapter.create(User, props)\r\n assert.debug('created', JSON.stringify(user, null, 2))\r\n const userId = user[User.idAttribute]\r\n assert.equal(user.name, 'John', 'name of created user should be \"John\"')\r\n assert.isDefined(user[User.idAttribute])\r\n\r\n assert.debug('find', user[User.idAttribute])\r\n const foundUser = await adapter.find(User, user[User.idAttribute])\r\n assert.debug('found', JSON.stringify(foundUser, null, 2))\r\n assert.equal(foundUser.name, 'John')\r\n assert.isDefined(foundUser[User.idAttribute])\r\n assert.equal(foundUser[User.idAttribute], userId)\r\n assert.equal(foundUser.name, 'John')\r\n\r\n props = { content: 'test', userId: userId }\r\n assert.debug('create', props)\r\n const post = await adapter.create(Post, props)\r\n assert.debug('created', JSON.stringify(post, null, 2))\r\n const postId = post[Post.idAttribute]\r\n assert.equal(post.content, 'test')\r\n assert.isDefined(post[Post.idAttribute])\r\n assert.equal(post.userId, userId)\r\n\r\n props = [\r\n {\r\n content: 'test2',\r\n postId: post[Post.idAttribute],\r\n userId: user[User.idAttribute]\r\n },\r\n {\r\n content: 'test3',\r\n postId: post[Post.idAttribute],\r\n userId: user[User.idAttribute]\r\n }\r\n ]\r\n assert.debug('create', props)\r\n const comments = await Promise.all([\r\n adapter.create(Comment, props[0]),\r\n adapter.create(Comment, props[1])\r\n ])\r\n assert.debug('created', JSON.stringify(comments, null, 2))\r\n\r\n comments.sort(function (a, b) {\r\n return a.content > b.content\r\n })\r\n\r\n const findPost = await adapter.find(Post, postId, {with: ['user', 'comment']})\r\n findPost.comments.sort(function (a, b) {\r\n return a.content > b.content\r\n })\r\n assert.equalObjects(findPost.user, user)\r\n assert.equalObjects(findPost.comments, comments)\r\n })\r\n\r\n it('should load belongsTo relations', async function () {\r\n let props = { name: 'John' }\r\n assert.debug('create', props)\r\n const user = await adapter.create(User, props)\r\n assert.debug('created', JSON.stringify(user, null, 2))\r\n\r\n props = { email: 'foo@test.com', userId: user[User.idAttribute] }\r\n assert.debug('create', props)\r\n const profile = await adapter.create(Profile, props)\r\n assert.debug('created', JSON.stringify(profile, null, 2))\r\n\r\n props = { content: 'foo', userId: user[User.idAttribute] }\r\n assert.debug('create', props)\r\n const post = await adapter.create(Post, props)\r\n assert.debug('created', JSON.stringify(post, null, 2))\r\n\r\n props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }\r\n assert.debug('create', props)\r\n let comment = await adapter.create(Comment, props)\r\n assert.debug('created', JSON.stringify(comment, null, 2))\r\n\r\n assert.debug('find', comment[Comment.idAttribute])\r\n comment = await adapter.find(Comment, comment[Comment.idAttribute], {'with': ['user', 'user.profile', 'post', 'post.user']})\r\n assert.debug('found', JSON.stringify(comment, null, 2))\r\n assert.isDefined(comment)\r\n assert.isDefined(comment.post)\r\n assert.isDefined(comment.post.user)\r\n assert.isDefined(comment.user)\r\n assert.isDefined(comment.user.profile)\r\n })\r\n\r\n it('should load hasMany and belongsTo relations', async function () {\r\n let props = { name: 'John' }\r\n assert.debug('create', props)\r\n const user = await adapter.create(User, props)\r\n assert.debug('created', JSON.stringify(user, null, 2))\r\n\r\n props = { email: 'foo@test.com', userId: user[User.idAttribute] }\r\n assert.debug('create', props)\r\n const profile = await adapter.create(Profile, props)\r\n assert.debug('created', JSON.stringify(profile, null, 2))\r\n\r\n props = { content: 'foo', userId: user[User.idAttribute] }\r\n assert.debug('create', props)\r\n let post = await adapter.create(Post, props)\r\n assert.debug('created', JSON.stringify(post, null, 2))\r\n\r\n props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }\r\n assert.debug('create', props)\r\n const comment = await adapter.create(Comment, props)\r\n assert.debug('created', JSON.stringify(comment, null, 2))\r\n\r\n assert.debug('find', props, comment[Comment.idAttribute])\r\n post = await adapter.find(Post, post[Post.idAttribute], {'with': ['user', 'comment', 'comment.user', 'comment.user.profile']})\r\n assert.debug('found', JSON.stringify(post, null, 2))\r\n\r\n assert.isDefined(post.comments)\r\n assert.isDefined(post.comments[0].user)\r\n assert.isDefined(post.comments[0].user.profile)\r\n assert.isDefined(post.user)\r\n })\r\n })\r\n}\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/find.test.js\n **/","module.exports = function (options) {\r\n describe('Adapter#findAll', function () {\r\n var adapter, User, Profile, Post, Comment\r\n\r\n beforeEach(function () {\r\n adapter = this.$$adapter\r\n User = this.$$User\r\n Profile = this.$$Profile\r\n Post = this.$$Post\r\n Comment = this.$$Comment\r\n })\r\n\r\n it('should exist', function () {\r\n assert.equal(typeof adapter.findAll, 'function', 'adapter should have a \"findAll\" method')\r\n })\r\n\r\n it('should filter users', async function () {\r\n let props = { name: 'John' }\r\n assert.debug('findAll', { age: 30 })\r\n const users = await adapter.findAll(User, { age: 30 })\r\n assert.debug('found', JSON.stringify(users, null, 2))\r\n assert.equal(users.length, 0)\r\n\r\n assert.debug('create', props)\r\n const user = await adapter.create(User, props)\r\n assert.debug('created', JSON.stringify(user, null, 2))\r\n const userId = user[User.idAttribute]\r\n\r\n assert.debug('findAll', { name: 'John' })\r\n const users2 = await adapter.findAll(User, { name: 'John' })\r\n assert.debug('found', JSON.stringify(users2, null, 2))\r\n assert.equal(users2.length, 1)\r\n assert.equal(users2[0][User.idAttribute], userId)\r\n assert.equal(users2[0].name, 'John')\r\n })\r\n\r\n if (options.features === 'all' || options.features.indexOf('inOp') !== -1) {\r\n it('should filter users using the \"in\" operator', async function () {\r\n var users = await adapter.findAll(User, {\r\n where: {\r\n age: {\r\n 'in': [30]\r\n }\r\n }\r\n })\r\n assert.equal(users.length, 0)\r\n\r\n var user = await adapter.create(User, {name: 'John'})\r\n var id = user.id\r\n\r\n var users2 = await adapter.findAll(User, { name: 'John' })\r\n assert.equal(users2.length, 1)\r\n assert.equal(users2[0].id, id)\r\n assert.equal(users2[0].name, 'John')\r\n\r\n var destroyedUser = await adapter.destroy(User, id)\r\n assert.isFalse(!!destroyedUser)\r\n })\r\n }\r\n\r\n if (options.features === 'all' || options.features.indexOf('likeOp') !== -1) {\r\n it('should filter users using the \"like\" operator', async function () {\r\n var users = await adapter.findAll(User, {\r\n where: {\r\n name: {\r\n 'like': '%J%'\r\n }\r\n }\r\n })\r\n assert.equal(users.length, 0)\r\n\r\n var user = await adapter.create(User, {name: 'John'})\r\n var id = user.id\r\n\r\n var users2 = await adapter.findAll(User, {\r\n where: {\r\n name: {\r\n 'like': '%J%'\r\n }\r\n }\r\n })\r\n assert.equal(users2.length, 1)\r\n assert.equal(users2[0].id, id)\r\n assert.equal(users2[0].name, 'John')\r\n\r\n var destroyedUser = await adapter.destroy(User, id)\r\n assert.isFalse(!!destroyedUser)\r\n })\r\n }\r\n\r\n if (options.features === 'all' || options.features.indexOf('filterOpNotFound') !== -1) {\r\n it('should throw \"Operator not found\" error', async function () {\r\n assert.throw(function () {\r\n return adapter.findAll(User, {\r\n where: {\r\n name: {\r\n op: 'John'\r\n }\r\n }\r\n })\r\n }, Error, 'Operator not found')\r\n })\r\n }\r\n\r\n it('should load belongsTo relations', async function () {\r\n let props = { name: 'John' }\r\n assert.debug('create', props)\r\n const user = await adapter.create(User, props)\r\n assert.debug('created', JSON.stringify(user, null, 2))\r\n\r\n props = { email: 'foo@test.com', userId: user[User.idAttribute] }\r\n assert.debug('create', props)\r\n const profile = await adapter.create(Profile, props)\r\n assert.debug('created', JSON.stringify(profile, null, 2))\r\n\r\n props = { content: 'foo', userId: user[User.idAttribute] }\r\n assert.debug('create', props)\r\n const post = await adapter.create(Post, props)\r\n assert.debug('created', JSON.stringify(post, null, 2))\r\n\r\n props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }\r\n assert.debug('create', props)\r\n let comment = await adapter.create(Comment, props)\r\n assert.debug('created', JSON.stringify(comment, null, 2))\r\n\r\n props = { name: 'Sally' }\r\n assert.debug('create', props)\r\n const user2 = await adapter.create(User, props)\r\n assert.debug('created', JSON.stringify(user2, null, 2))\r\n\r\n props = { content: 'bar', userId: user2[User.idAttribute] }\r\n assert.debug('create', props)\r\n const post2 = await adapter.create(Post, props)\r\n assert.debug('created', JSON.stringify(post2, null, 2))\r\n\r\n props = { content: 'test67', postId: post2[Post.idAttribute], userId: post2.userId }\r\n assert.debug('create', props)\r\n let comment2 = await adapter.create(Comment, props)\r\n assert.debug('created', JSON.stringify(comment2, null, 2))\r\n\r\n assert.debug('findAll')\r\n const comments = await adapter.findAll(Comment, {}, {'with': ['user', 'user.profile', 'post', 'post.user']})\r\n assert.debug('found', JSON.stringify(comments, null, 2))\r\n assert.isDefined(comments[0].post)\r\n assert.isDefined(comments[0].post.user)\r\n assert.isDefined(comments[0].user)\r\n assert.isDefined(comments[0].user.profile || comments[1].user.profile)\r\n assert.isDefined(comments[1].post)\r\n assert.isDefined(comments[1].post.user)\r\n assert.isDefined(comments[1].user)\r\n })\r\n\r\n it('should load hasMany and belongsTo relations', async function () {\r\n let props = { name: 'John' }\r\n assert.debug('create', props)\r\n const user = await adapter.create(User, props)\r\n assert.debug('created', JSON.stringify(user, null, 2))\r\n\r\n props = { email: 'foo@test.com', userId: user[User.idAttribute] }\r\n assert.debug('create', props)\r\n const profile = await adapter.create(Profile, props)\r\n assert.debug('created', JSON.stringify(profile, null, 2))\r\n\r\n props = { content: 'foo', userId: user[User.idAttribute] }\r\n assert.debug('create', props)\r\n const post = await adapter.create(Post, props)\r\n assert.debug('created', JSON.stringify(post, null, 2))\r\n\r\n props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }\r\n assert.debug('create', props)\r\n let comment = await adapter.create(Comment, props)\r\n assert.debug('created', JSON.stringify(comment, null, 2))\r\n\r\n props = { name: 'Sally' }\r\n assert.debug('create', props)\r\n const user2 = await adapter.create(User, props)\r\n assert.debug('created', JSON.stringify(user2, null, 2))\r\n\r\n props = { content: 'bar', userId: user2[User.idAttribute] }\r\n assert.debug('create', props)\r\n const post2 = await adapter.create(Post, props)\r\n assert.debug('created', JSON.stringify(post2, null, 2))\r\n\r\n props = { content: 'test67', postId: post2[Post.idAttribute], userId: post2.userId }\r\n assert.debug('create', props)\r\n let comment2 = await adapter.create(Comment, props)\r\n assert.debug('created', JSON.stringify(comment2, null, 2))\r\n\r\n assert.debug('find')\r\n const posts = await adapter.findAll(Post, {}, {'with': ['user', 'comment', 'comment.user', 'comment.user.profile']})\r\n assert.debug('found', JSON.stringify(posts, null, 2))\r\n assert.isDefined(posts[0].comments)\r\n assert.isDefined(posts[0].comments[0].user)\r\n assert.isDefined(posts[0].comments[0].user.profile || posts[1].comments[0].user.profile)\r\n assert.isDefined(posts[0].user)\r\n assert.isDefined(posts[1].comments)\r\n assert.isDefined(posts[1].comments[0].user)\r\n assert.isDefined(posts[1].user)\r\n })\r\n\r\n if (options.features === 'all' || options.features.indexOf('filterOnRelations') !== -1) {\r\n it('should filter using belongsTo relation', async function () {\r\n var profile1 = await adapter.create(Profile, { email: 'foo@test.com' })\r\n var user1 = await adapter.create(User, {name: 'John', profileId: profile1.id})\r\n var post1 = await adapter.create(Post, {content: 'foo', userId: user1.id})\r\n await adapter.create(Comment, {content: 'test1', postId: post1.id, userId: post1.userId})\r\n\r\n var user2 = await adapter.create(User, {name: 'Sally'})\r\n var post2 = await adapter.create(Post, {content: 'bar', userId: user2.id})\r\n await adapter.create(Comment, {content: 'test2', postId: post2.id, userId: post2.userId})\r\n\r\n var users = await adapter.findAll(User, {'profile.email': 'foo@test.com'})\r\n assert.equal(users.length, 1)\r\n assert.equal(users[0].profileId, profile1.id)\r\n assert.equal(users[0].name, 'John')\r\n })\r\n\r\n it('should filter through multiple hasOne/belongsTo relations', async function () {\r\n var profile1 = await adapter.create(Profile, { email: 'foo@test.com' })\r\n var user1 = await adapter.create(User, {name: 'John', profileId: profile1.id})\r\n var post1 = await adapter.create(Post, {content: 'foo', userId: user1.id})\r\n await adapter.create(Comment, {content: 'test1', postId: post1.id, userId: post1.userId})\r\n\r\n var profile2 = await adapter.create(Profile, { email: 'bar@test.com' })\r\n var user2 = await adapter.create(User, {name: 'Sally', profileId: profile2.id})\r\n var post2 = await adapter.create(Post, {content: 'bar', userId: user2.id})\r\n await adapter.create(Comment, {content: 'test2', postId: post2.id, userId: post2.userId})\r\n\r\n var comments = await adapter.findAll(Comment, { 'user.profile.email': 'foo@test.com' })\r\n assert.equal(comments.length, 1)\r\n assert.equal(comments[0].userId, user1.id)\r\n assert.equal(comments[0].content, 'test1')\r\n })\r\n\r\n it('should filter using multiple hasOne/belongsTo relations', async function () {\r\n var profile1 = await adapter.create(Profile, { email: 'foo@test.com' })\r\n var user1 = await adapter.create(User, {name: 'John', profileId: profile1.id})\r\n var post1 = await adapter.create(Post, {content: 'foo', userId: user1.id})\r\n await adapter.create(Comment, {content: 'test1', postId: post1.id, userId: post1.userId})\r\n\r\n var profile2 = await adapter.create(Profile, { email: 'bar@test.com' })\r\n var user2 = await adapter.create(User, {name: 'Sally', profileId: profile2.id})\r\n var post2 = await adapter.create(Post, {content: 'bar', userId: user2.id})\r\n await adapter.create(Comment, {content: 'test2', postId: post2.id, userId: post2.userId})\r\n\r\n var comments = await adapter.findAll(Comment, { 'user.name': 'John', 'user.profile.email': 'foo@test.com' })\r\n assert.equal(comments.length, 1)\r\n assert.equal(comments[0].userId, user1.id)\r\n assert.equal(comments[0].content, 'test1')\r\n })\r\n }\r\n\r\n it('should allow passing limit and offset as strings', async function () {\r\n await adapter.findAll(User, { limit: '10', offset: '20' })\r\n })\r\n })\r\n}\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/findAll.test.js\n **/","module.exports = function (options) {\r\n describe('Adapter#destroy', function () {\r\n it('should exist', function () {\r\n assert.equal(typeof this.$$adapter.destroy, 'function', 'adapter should have a \"destroy\" method')\r\n })\r\n it('should destroy a user', async function () {\r\n const adapter = this.$$adapter\r\n const User = this.$$User\r\n const props = { name: 'John' }\r\n\r\n assert.debug('create', props)\r\n const user = await adapter.create(User, props)\r\n assert.debug('created', JSON.stringify(user, null, 2))\r\n\r\n assert.debug('destroy', user[User.idAttribute])\r\n const destroyedUser = await adapter.destroy(User, user[User.idAttribute])\r\n assert.debug('destroyed', JSON.stringify(destroyedUser, null, 2))\r\n assert.isFalse(!!destroyedUser)\r\n\r\n try {\r\n await adapter.find(User, user[User.idAttribute])\r\n throw new Error('Should not have reached here!')\r\n } catch (err) {\r\n assert.equal(err.message, 'Not Found!')\r\n }\r\n })\r\n })\r\n}\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/destroy.test.js\n **/","module.exports = function (options) {\r\n describe('Adapter#destroyAll', function () {\r\n it('should exist', function () {\r\n assert.equal(typeof this.$$adapter.destroyAll, 'function', 'adapter should have a \"destroyAll\" method')\r\n })\r\n it('should destroy all users', async function () {\r\n const adapter = this.$$adapter\r\n const User = this.$$User\r\n const props = { name: 'John' }\r\n\r\n assert.debug('create', props)\r\n const user = await adapter.create(User, props)\r\n assert.debug('created', JSON.stringify(user, null, 2))\r\n\r\n assert.debug('findAll', props)\r\n let foundUsers = await adapter.findAll(User, props)\r\n assert.debug('found', JSON.stringify(foundUsers, null, 2))\r\n assert.equal(foundUsers.length, 1)\r\n assert.equal(foundUsers[0][User.idAttribute], user[User.idAttribute])\r\n assert.equal(foundUsers[0].name, 'John')\r\n\r\n assert.debug('destroyAll', props)\r\n const destroyedUsers = await adapter.destroyAll(User, props)\r\n assert.debug('destroyed', JSON.stringify(destroyedUsers, null, 2))\r\n\r\n assert.debug('findAll', props)\r\n foundUsers = await adapter.findAll(User, props)\r\n assert.debug('found', JSON.stringify(foundUsers, null, 2))\r\n assert.equal(foundUsers.length, 0)\r\n })\r\n })\r\n}\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/destroyAll.test.js\n **/","module.exports = function (options) {\r\n describe('Adapter#update', function () {\r\n it('should exist', function () {\r\n assert.equal(typeof this.$$adapter.update, 'function', 'adapter should have a \"update\" method')\r\n })\r\n it('should update a user', async function () {\r\n const adapter = this.$$adapter\r\n const User = this.$$User\r\n const props = { name: 'John' }\r\n\r\n assert.debug('create', props)\r\n const user = await adapter.create(User, props)\r\n assert.debug('created', JSON.stringify(user, null, 2))\r\n\r\n assert.equal(user.name, props.name, `name of user should be \"${props.name}\"`)\r\n assert.isDefined(user[User.idAttribute], 'new user should have an id')\r\n\r\n assert.debug('find', user[User.idAttribute])\r\n let foundUser = await adapter.find(User, user[User.idAttribute])\r\n assert.debug('found', JSON.stringify(foundUser, null, 2))\r\n\r\n assert.equal(foundUser.name, props.name, `name of user should be \"${props.name}\"`)\r\n assert.isDefined(foundUser[User.idAttribute], 'new user should have an id')\r\n assert.equal(foundUser[User.idAttribute], user[User.idAttribute])\r\n\r\n assert.debug('update', user[User.idAttribute], { name: 'Johnny' })\r\n const updatedUser = await adapter.update(User, user[User.idAttribute], { name: 'Johnny' })\r\n assert.debug('found', JSON.stringify(updatedUser, null, 2))\r\n assert.equal(updatedUser.name, 'Johnny')\r\n assert.equal(updatedUser[User.idAttribute], user[User.idAttribute])\r\n\r\n assert.debug('find', user[User.idAttribute])\r\n foundUser = await adapter.find(User, user[User.idAttribute])\r\n assert.debug('found', JSON.stringify(foundUser, null, 2))\r\n assert.equal(foundUser.name, 'Johnny')\r\n assert.equal(foundUser[User.idAttribute], user[User.idAttribute])\r\n })\r\n })\r\n}\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/update.test.js\n **/","module.exports = function (options) {\r\n describe('Adapter#updateAll', function () {\r\n it('should exist', function () {\r\n assert.equal(typeof this.$$adapter.updateAll, 'function', 'adapter should have a \"updateAll\" method')\r\n })\r\n it('should update multiple users', async function () {\r\n const adapter = this.$$adapter\r\n const User = this.$$User\r\n let props = { name: 'John', age: 20 }\r\n\r\n assert.debug('create', props)\r\n const user1 = await adapter.create(User, props)\r\n assert.debug('created', JSON.stringify(user1, null, 2))\r\n const userId1 = user1[User.idAttribute]\r\n\r\n props = { name: 'John', age: 30 }\r\n\r\n assert.debug('create', props)\r\n const user2 = await adapter.create(User, props)\r\n assert.debug('created', JSON.stringify(user2, null, 2))\r\n const userId2 = user2[User.idAttribute]\r\n\r\n assert.debug('findAll', { name: 'John' })\r\n const users = await adapter.findAll(User, { name: 'John' })\r\n assert.debug('found', JSON.stringify(users, null, 2))\r\n users.sort(function (a, b) {\r\n return a.age - b.age\r\n })\r\n assert.equal(users[0].name, 'John')\r\n assert.equal(users[0].name, 'John')\r\n assert.equal(users.filter(function (x) { return x[User.idAttribute] === userId1 }).length, 1)\r\n assert.equal(users.filter(function (x) { return x[User.idAttribute] === userId2 }).length, 1)\r\n assert.equal(users.filter(function (x) { return x.age === 20 }).length, 1)\r\n assert.equal(users.filter(function (x) { return x.age === 30 }).length, 1)\r\n\r\n assert.debug('updateAll', { name: 'Johnny' }, { name: 'John' })\r\n const users2 = await adapter.updateAll(User, { name: 'Johnny' }, { name: 'John' })\r\n assert.debug('updated', JSON.stringify(users2, null, 2))\r\n users2.sort(function (a, b) {\r\n return a.age - b.age\r\n })\r\n assert.equal(users2[0].name, 'Johnny')\r\n assert.equal(users2[0].name, 'Johnny')\r\n assert.equal(users2.filter(function (x) { return x[User.idAttribute] === userId1 }).length, 1)\r\n assert.equal(users2.filter(function (x) { return x[User.idAttribute] === userId2 }).length, 1)\r\n assert.equal(users2.filter(function (x) { return x.age === 20 }).length, 1)\r\n assert.equal(users2.filter(function (x) { return x.age === 30 }).length, 1)\r\n\r\n assert.debug('findAll', { name: 'John' })\r\n const users3 = await adapter.findAll(User, { name: 'John' })\r\n assert.debug('found', JSON.stringify(users3, null, 2))\r\n assert.equalObjects(users3, [])\r\n assert.equal(users3.length, 0)\r\n\r\n assert.debug('findAll', { name: 'Johnny' })\r\n const users4 = await adapter.findAll(User, { name: 'Johnny' })\r\n assert.debug('found', JSON.stringify(users4, null, 2))\r\n users4.sort(function (a, b) {\r\n return a.age - b.age\r\n })\r\n assert.equal(users4[0].name, 'Johnny')\r\n assert.equal(users4[0].name, 'Johnny')\r\n assert.equal(users4.filter(function (x) { return x[User.idAttribute] === userId1 }).length, 1)\r\n assert.equal(users4.filter(function (x) { return x[User.idAttribute] === userId2 }).length, 1)\r\n assert.equal(users4.filter(function (x) { return x.age === 20 }).length, 1)\r\n assert.equal(users4.filter(function (x) { return x.age === 30 }).length, 1)\r\n })\r\n })\r\n}\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/updateAll.test.js\n **/"],"sourceRoot":""}
\ No newline at end of file
+{"version":3,"file":"js-data-adapter-tests.js","sources":["../src/afterCreate.test.js","../src/afterUpdate.test.js","../src/beforeCreate.test.js","../src/beforeUpdate.test.js","../src/count.test.js","../src/create.test.js","../src/createMany.test.js","../src/destroy.test.js","../src/destroyAll.test.js","../src/extend.test.js","../src/find.test.js","../src/findAll.test.js","../src/sum.test.js","../src/update.test.js","../src/updateAll.test.js","../src/updateMany.test.js","../src/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', 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 })\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', 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 })\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', 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 })\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', 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 })\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', 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 })\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', 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 })\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', 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 })\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', 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 })\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', 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 })\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', 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 })\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', 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 })\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', 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 })\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', 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 })\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', 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 })\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', 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], 'beforeCreate should have received options')\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', 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], 'beforeCreate should have received options')\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', 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], 'beforeCreate should have received options')\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', 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], 'beforeCreate should have received options')\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 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}\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 })\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":["assert"],"mappings":"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"}
\ No newline at end of file
diff --git a/package.json b/package.json
index e02dc1e..ffa66d7 100644
--- a/package.json
+++ b/package.json
@@ -1,8 +1,8 @@
{
"name": "js-data-adapter-tests",
"description": "Tests for js-data adapters.",
- "version": "1.5.0",
"homepage": "https://github.com/js-data/js-data-adapter-tests",
+ "version": "2.0.0-alpha.21",
"repository": {
"type": "git",
"url": "https://github.com/js-data/js-data-adapter-tests.git"
@@ -16,33 +16,47 @@
"test"
],
"scripts": {
- "lint": "standard src/**/*.js",
- "bundle": "webpack --config webpack.config.js",
- "test": "npm run lint && npm run bundle"
+ "lint": "repo-tools lint \"**/*.js\"",
+ "bundle": "rollup -c rollup.config.js -f umd -o dist/js-data-adapter-tests.js -m dist/js-data-adapter-tests.js.map src/index.js",
+ "watch": "watch \"npm run bundle\" src/",
+ "test": "npm run lint && npm run bundle",
+ "release": "npm test && repo-tools updates && repo-tools changelog"
},
"standard": {
"parser": "babel-eslint",
"globals": [
"Mocha",
"describe",
+ "sinon",
"it",
"before",
"after",
"beforeEach",
"afterEach",
"assert"
+ ],
+ "ignore": [
+ "dist/"
]
},
+ "babel": {
+ "presets": ["es2015-rollup", "stage-0"],
+ "plugins": ["syntax-async-functions", "transform-regenerator"]
+ },
+ "peerDependencies": {
+ "chai": "^3.5.0",
+ "mocha": "^2.4.5",
+ "sinon": "^1.17.3"
+ },
"devDependencies": {
- "babel-core": "6.5.2",
- "babel-eslint": "5.0.0",
- "babel-loader": "6.2.3",
- "babel-plugin-syntax-async-functions": "6.5.0",
- "babel-plugin-transform-regenerator": "6.5.2",
- "babel-polyfill": "6.5.0",
- "babel-preset-es2015": "6.5.0",
+ "babel-plugin-syntax-async-functions": "6.8.0",
+ "babel-plugin-transform-regenerator": "6.8.0",
+ "babel-polyfill": "6.8.0",
+ "babel-preset-es2015-rollup": "1.1.1",
"babel-preset-stage-0": "6.5.0",
- "standard": "6.0.5",
- "webpack": "1.12.13"
+ "js-data-repo-tools": "0.5.0",
+ "rollup": "0.26.2",
+ "rollup-plugin-babel": "2.4.0",
+ "watch": "0.18.0"
}
}
diff --git a/rollup.config.js b/rollup.config.js
new file mode 100644
index 0000000..55f65f4
--- /dev/null
+++ b/rollup.config.js
@@ -0,0 +1,19 @@
+var babel = require('rollup-plugin-babel')
+
+module.exports = {
+ moduleName: 'JSDataAdapterTests',
+ moduleId: 'js-data-adapter-tests',
+ external: [
+ 'chai',
+ 'sinon'
+ ],
+ globals: {
+ chai: 'chai',
+ sinon: 'sinon'
+ },
+ plugins: [
+ babel({
+ exclude: 'node_modules/**'
+ })
+ ]
+}
diff --git a/src/afterCreate.test.js b/src/afterCreate.test.js
new file mode 100644
index 0000000..cd55cf2
--- /dev/null
+++ b/src/afterCreate.test.js
@@ -0,0 +1,142 @@
+/* global assert:true */
+export default 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', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ sinon.stub(adapter, 'afterCreate', 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)
+ const user = await adapter.create(User, props)
+ 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')
+
+ const 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')
+ })
+ it('should allow re-assignment', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ sinon.stub(adapter, 'afterCreate', 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)
+ const user = await adapter.create(User, props)
+ 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')
+
+ const 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')
+ })
+ it('should allow returning a promise', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ sinon.stub(adapter, 'afterCreate', 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)
+ const user = await adapter.create(User, props)
+ 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')
+
+ const 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')
+ })
+ it('should allow returning a promise and re-assignment', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ sinon.stub(adapter, 'afterCreate', 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)
+ const user = await adapter.create(User, props)
+ 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')
+
+ const 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')
+ })
+ it('should receive raw', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ sinon.stub(adapter, 'afterCreate', 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)
+ const result = await adapter.create(User, props, { raw: true })
+ 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')
+
+ const 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')
+ })
+ })
+}
diff --git a/src/afterUpdate.test.js b/src/afterUpdate.test.js
new file mode 100644
index 0000000..7d8c6e6
--- /dev/null
+++ b/src/afterUpdate.test.js
@@ -0,0 +1,197 @@
+/* global assert:true */
+export default 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', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ sinon.stub(adapter, 'afterUpdate', 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)
+ const user = await adapter.create(User, props)
+ const 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' })
+ let updatedUser = await adapter.update(User, userId, { name: 'Johnny' })
+ 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')
+
+ const 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')
+ })
+ it('should receive raw', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ sinon.stub(adapter, 'afterUpdate', 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)
+ const user = await adapter.create(User, props)
+ const 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' })
+ let result = await adapter.update(User, userId, { name: 'Johnny' }, { raw: true })
+ 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')
+
+ const 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')
+ })
+ it('should allow re-assignment', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ sinon.stub(adapter, 'afterUpdate', 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)
+ const user = await adapter.create(User, props)
+ const 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' })
+ let updatedUser = await adapter.update(User, userId, { name: 'Johnny' })
+ 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')
+
+ const 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')
+ })
+ it('should allow returning a promise', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ sinon.stub(adapter, 'afterUpdate', 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)
+ const user = await adapter.create(User, props)
+ const 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' })
+ let updatedUser = await adapter.update(User, userId, { name: 'Johnny' })
+ 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')
+
+ const 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')
+ })
+ it('should allow returning a promise and re-assignment', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ sinon.stub(adapter, 'afterUpdate', 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)
+ const user = await adapter.create(User, props)
+ const 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' })
+ let updatedUser = await adapter.update(User, userId, { name: 'Johnny' })
+ 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')
+
+ const 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')
+ })
+ })
+}
diff --git a/src/beforeCreate.test.js b/src/beforeCreate.test.js
new file mode 100644
index 0000000..e9cf4aa
--- /dev/null
+++ b/src/beforeCreate.test.js
@@ -0,0 +1,111 @@
+/* global assert:true */
+export default 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', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ sinon.stub(adapter, 'beforeCreate', 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)
+ const user = await adapter.create(User, props)
+ 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')
+
+ const 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')
+ })
+ it('should allow re-assignment', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ sinon.stub(adapter, 'beforeCreate', 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)
+ const user = await adapter.create(User, props)
+ 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')
+
+ const 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')
+ })
+ it('should allow returning a promise', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ sinon.stub(adapter, 'beforeCreate', 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)
+ const user = await adapter.create(User, props)
+ 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')
+
+ const 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')
+ })
+ it('should allow returning a promise and re-assignment', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ sinon.stub(adapter, 'beforeCreate', 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)
+ const user = await adapter.create(User, props)
+ 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')
+
+ const 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')
+ })
+ })
+}
diff --git a/src/beforeUpdate.test.js b/src/beforeUpdate.test.js
new file mode 100644
index 0000000..d74eebe
--- /dev/null
+++ b/src/beforeUpdate.test.js
@@ -0,0 +1,143 @@
+/* global assert:true */
+export default 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', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ sinon.stub(adapter, 'beforeUpdate', 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)
+ const user = await adapter.create(User, props)
+ const 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' })
+ let updatedUser = await adapter.update(User, userId, { name: 'Johnny' })
+ 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')
+
+ const 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], 'beforeCreate should have received options')
+ })
+ it('should allow re-assignment', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ sinon.stub(adapter, 'beforeUpdate', 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)
+ const user = await adapter.create(User, props)
+ const 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' })
+ let updatedUser = await adapter.update(User, userId, { name: 'Johnny' })
+ 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')
+
+ const 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], 'beforeCreate should have received options')
+ })
+ it('should allow returning a promise', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ sinon.stub(adapter, 'beforeUpdate', 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)
+ const user = await adapter.create(User, props)
+ const 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' })
+ let updatedUser = await adapter.update(User, userId, { name: 'Johnny' })
+ 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')
+
+ const 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], 'beforeCreate should have received options')
+ })
+ it('should allow returning a promise and re-assignment', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ sinon.stub(adapter, 'beforeUpdate', 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)
+ const user = await adapter.create(User, props)
+ const 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' })
+ let updatedUser = await adapter.update(User, userId, { name: 'Johnny' })
+ 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')
+
+ const 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], 'beforeCreate should have received options')
+ })
+ })
+}
diff --git a/src/count.test.js b/src/count.test.js
new file mode 100644
index 0000000..992d7bd
--- /dev/null
+++ b/src/count.test.js
@@ -0,0 +1,80 @@
+/* global assert:true */
+export default 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', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ assert.debug('count', User.name, {})
+ let count = await adapter.count(User)
+ assert.debug('counted', User.name, count)
+ assert.equal(count, 0)
+
+ assert.debug('count', User.name, { name: 'John' })
+ count = await adapter.count(User, { name: 'John' })
+ assert.debug('counted', User.name, count)
+ assert.equal(count, 0)
+
+ assert.debug('count', User.name, { name: 'Sally' })
+ count = await adapter.count(User, { name: 'Sally' })
+ assert.debug('counted', User.name, count)
+ assert.equal(count, 0)
+
+ assert.debug('create', User.name, props)
+ const user = await adapter.create(User, props)
+ assert.debug('created', User.name, user)
+
+ assert.debug('count', User.name, {})
+ count = await adapter.count(User)
+ assert.debug('counted', User.name, count)
+ assert.equal(count, 1)
+
+ assert.debug('count', User.name, { name: 'John' })
+ count = await adapter.count(User, { name: 'John' })
+ assert.debug('counted', User.name, count)
+ assert.equal(count, 1)
+
+ assert.debug('count', User.name, { name: 'Sally' })
+ count = await adapter.count(User, { name: 'Sally' })
+ assert.debug('counted', User.name, count)
+ assert.equal(count, 0)
+
+ assert.debug('create', User.name, { name: 'Sally' })
+ const user2 = await adapter.create(User, { name: 'Sally' })
+ assert.debug('created', User.name, user2)
+
+ assert.debug('count', User.name, {})
+ count = await adapter.count(User)
+ assert.debug('counted', User.name, count)
+ assert.equal(count, 2)
+
+ assert.debug('count', User.name, { name: 'John' })
+ count = await adapter.count(User, { name: 'John' })
+ assert.debug('counted', User.name, count)
+ assert.equal(count, 1)
+
+ assert.debug('count', User.name, { name: 'Sally' })
+ count = await adapter.count(User, { name: 'Sally' })
+ assert.debug('counted', User.name, count)
+ assert.equal(count, 1)
+ })
+ it('should count users and return raw', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ assert.debug('create', User.name, props)
+ let user = await adapter.create(User, props)
+ assert.debug('created', User.name, user)
+
+ assert.debug('count', User.name, props)
+ const result = await adapter.count(User, props, { raw: true })
+ assert.debug('counted', User.name, result)
+ assert.equal(result.data, 1, 'result.data')
+ })
+ })
+}
diff --git a/src/create.test.js b/src/create.test.js
index 9cf6f7b..0e863a6 100644
--- a/src/create.test.js
+++ b/src/create.test.js
@@ -1,4 +1,5 @@
-module.exports = function (options) {
+/* global assert:true */
+export default function (options) {
describe('Adapter#create', function () {
it('should exist', function () {
assert.equal(typeof this.$$adapter.create, 'function', 'adapter should have a "create" method')
@@ -8,20 +9,21 @@ module.exports = function (options) {
const User = this.$$User
const props = { name: 'John' }
- assert.debug('create', props)
+ assert.debug('create', User.name, props)
const user = await adapter.create(User, props)
- assert.debug('created', JSON.stringify(user, null, 2))
+ const 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.equal(user.name, props.name, 'user.name')
+ assert.isDefined(user[User.idAttribute], 'user[User.idAttribute]')
- assert.debug('find', user[User.idAttribute])
- const foundUser = await adapter.find(User, user[User.idAttribute])
- assert.debug('found', JSON.stringify(foundUser, null, 2))
+ assert.debug('find', User.name, userId)
+ const foundUser = await adapter.find(User, userId)
+ 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.equal(foundUser.name, props.name, 'foundUser.name')
+ assert.isDefined(foundUser[User.idAttribute], 'foundUser[User.idAttribute]')
+ assert.equal(foundUser[User.idAttribute], userId, 'foundUser[User.idAttribute]')
})
})
}
diff --git a/src/createMany.test.js b/src/createMany.test.js
new file mode 100644
index 0000000..18c786e
--- /dev/null
+++ b/src/createMany.test.js
@@ -0,0 +1,31 @@
+/* global assert:true */
+export default 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', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ let user1 = { name: 'John', age: 20 }
+
+ let user2 = { name: 'John', age: 30 }
+
+ assert.debug('createMany', User.name, [user1, user2])
+ const users = await adapter.createMany(User, [user1, user2])
+ 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 })
+ const users3 = await adapter.findAll(User, { age: 20 })
+ assert.debug('found', User.name, users3)
+ assert.equal(users3.length, 1)
+ })
+ })
+}
diff --git a/src/destroy.test.js b/src/destroy.test.js
index f8d7ae0..8dbb80f 100644
--- a/src/destroy.test.js
+++ b/src/destroy.test.js
@@ -1,4 +1,5 @@
-module.exports = function (options) {
+/* global assert:true */
+export default function (options) {
describe('Adapter#destroy', function () {
it('should exist', function () {
assert.equal(typeof this.$$adapter.destroy, 'function', 'adapter should have a "destroy" method')
@@ -8,20 +9,116 @@ module.exports = function (options) {
const User = this.$$User
const props = { name: 'John' }
- assert.debug('create', props)
- const user = await adapter.create(User, props)
- assert.debug('created', JSON.stringify(user, null, 2))
+ assert.debug('create', User.name, props)
+ let user = await adapter.create(User, props)
+ let userId = user[User.idAttribute]
+ assert.debug('created', User.name, user)
- assert.debug('destroy', user[User.idAttribute])
- const destroyedUser = await adapter.destroy(User, user[User.idAttribute])
- assert.debug('destroyed', JSON.stringify(destroyedUser, null, 2))
- assert.isFalse(!!destroyedUser)
+ let beforeDestroyCalled = false
+ let afterDestroyCalled = false
- try {
- await adapter.find(User, user[User.idAttribute])
- throw new Error('Should not have reached here!')
- } catch (err) {
- assert.equal(err.message, 'Not Found!')
+ // 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)
+ const destroyedUser = await adapter.destroy(User, userId)
+ 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')
+ })
+ it('should destroy a user and allow afterDestroy re-assignment', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ assert.debug('create', User.name, props)
+ let user = await adapter.create(User, props)
+ let userId = user[User.idAttribute]
+ assert.debug('created', User.name, user)
+
+ let beforeDestroyCalled = false
+ let 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)
+ const destroyedUser = await adapter.destroy(User, userId, { raw: true })
+ 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')
+ })
+ it('should destroy a user and return raw', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ assert.debug('create', User.name, props)
+ let user = await adapter.create(User, props)
+ let userId = user[User.idAttribute]
+ assert.debug('created', User.name, user)
+
+ assert.debug('destroy', User.name, userId)
+ const result = await adapter.destroy(User, userId, { raw: true })
+ 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')
+ }
+ })
+ it('should destroy nothing', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+
+ assert.debug('destroy', User.name, 'non-existent-id')
+ const result = await adapter.destroy(User, 'non-existent-id')
+ assert.debug('destroyed', User.name, result)
+ assert.isUndefined(result, 'result')
+ })
+ it('should destroy nothing and return raw', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+
+ assert.debug('destroy', User.name, 'non-existent-id')
+ const result = await adapter.destroy(User, 'non-existent-id', { raw: true })
+ 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')
}
})
})
diff --git a/src/destroyAll.test.js b/src/destroyAll.test.js
index f4bc2a4..bdec910 100644
--- a/src/destroyAll.test.js
+++ b/src/destroyAll.test.js
@@ -1,4 +1,5 @@
-module.exports = function (options) {
+/* global assert:true */
+export default function (options) {
describe('Adapter#destroyAll', function () {
it('should exist', function () {
assert.equal(typeof this.$$adapter.destroyAll, 'function', 'adapter should have a "destroyAll" method')
@@ -8,25 +9,76 @@ module.exports = function (options) {
const User = this.$$User
const props = { name: 'John' }
- assert.debug('create', props)
+ assert.debug('create', User.name, props)
const user = await adapter.create(User, props)
- assert.debug('created', JSON.stringify(user, null, 2))
+ const userId = user[User.idAttribute]
+ assert.debug('created', User.name, user)
- assert.debug('findAll', props)
- let foundUsers = await adapter.findAll(User, props)
- assert.debug('found', JSON.stringify(foundUsers, null, 2))
- assert.equal(foundUsers.length, 1)
- assert.equal(foundUsers[0][User.idAttribute], user[User.idAttribute])
- assert.equal(foundUsers[0].name, 'John')
+ assert.debug('create', User.name, { name: 'Sally' })
+ const user2 = await adapter.create(User, { name: 'Sally' })
+ assert.debug('created', User.name, user2)
+
+ assert.debug('findAll', User.name, { name: 'John' })
+ let foundUsers = await adapter.findAll(User, { name: 'John' })
+ 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', props)
- const destroyedUsers = await adapter.destroyAll(User, props)
- assert.debug('destroyed', JSON.stringify(destroyedUsers, null, 2))
+ assert.debug('destroyAll', User.name, { name: 'John' })
+ const destroyedUsers = await adapter.destroyAll(User, { name: 'John' })
+ assert.debug('destroyed', User.name, destroyedUsers)
+ assert.isUndefined(destroyedUsers, 'destroyedUsers')
- assert.debug('findAll', props)
- foundUsers = await adapter.findAll(User, props)
- assert.debug('found', JSON.stringify(foundUsers, null, 2))
+ assert.debug('findAll', User.name, { name: 'John' })
+ foundUsers = await adapter.findAll(User, { name: 'John' })
+ assert.debug('found', User.name, foundUsers)
assert.equal(foundUsers.length, 0)
+
+ assert.debug('findAll', User.name, {})
+ foundUsers = await adapter.findAll(User, {})
+ assert.debug('found', User.name, foundUsers)
+ assert.equal(foundUsers.length, 1)
+ })
+ it('should destroy users and return raw', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ assert.debug('create', User.name, props)
+ let user = await adapter.create(User, props)
+ assert.debug('created', User.name, user)
+
+ assert.debug('destroyAll', User.name, props)
+ const result = await adapter.destroyAll(User, props, { raw: true })
+ 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')
+ }
+ })
+ it('should destroy nothing', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+
+ assert.debug('destroyAll', User.name, {})
+ const result = await adapter.destroyAll(User, {})
+ assert.debug('destroyed', User.name, result)
+ assert.isUndefined(result, 'result')
+ })
+ it('should destroy nothing and return raw', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+
+ assert.debug('destroyAll', User.name, {})
+ const result = await adapter.destroyAll(User, {}, { raw: true })
+ 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')
+ }
})
})
}
diff --git a/src/extend.test.js b/src/extend.test.js
new file mode 100644
index 0000000..2ce8619
--- /dev/null
+++ b/src/extend.test.js
@@ -0,0 +1,64 @@
+/* global assert:true */
+export default 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 () {
+ const Adapter = this.$$adapter.constructor
+
+ const SubAdapter = Adapter.extend({
+ foo () {
+ return 'foo'
+ }
+ }, {
+ 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')
+ }
+
+ const 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 () {
+ const Adapter = this.$$adapter.constructor
+
+ class SubAdapter extends Adapter {
+ foo () {
+ return 'foo'
+ }
+ static 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) {
+ try {
+ assert.equal(typeof SubAdapter.extend, 'function', 'should have same static methods')
+ } catch (err) {
+ var obj = {}
+ if (obj.setPrototypeOf) {
+ throw err
+ }
+ }
+ }
+
+ const subAdapter = new SubAdapter()
+
+ assert.equal(subAdapter.foo(), 'foo', 'subAdapter.foo() should return "foo"')
+ assert.isTrue(subAdapter.find === subAdapter.find, 'should have same instance methods')
+ })
+ })
+}
diff --git a/src/find.test.js b/src/find.test.js
index 345338b..e21c26d 100644
--- a/src/find.test.js
+++ b/src/find.test.js
@@ -1,6 +1,7 @@
-module.exports = function (options) {
+/* global assert:true */
+export default function (options) {
describe('Adapter#find', function () {
- var adapter, User, Profile, Post, Comment
+ var adapter, User, Profile, Post, Comment, Tag
beforeEach(function () {
adapter = this.$$adapter
@@ -8,6 +9,7 @@ module.exports = function (options) {
Profile = this.$$Profile
Post = this.$$Post
Comment = this.$$Comment
+ Tag = this.$$Tag
})
it('should exist', function () {
@@ -15,122 +17,477 @@ module.exports = function (options) {
})
it('should find a user', async function () {
+ this.toClear.push('Post')
+ this.toClear.push('Comment')
let props = { name: 'John' }
- assert.debug('create', props)
+ assert.debug('create', User.name, props)
const user = await adapter.create(User, props)
- assert.debug('created', JSON.stringify(user, null, 2))
+ assert.debug('created', User.name, user)
const userId = user[User.idAttribute]
- assert.equal(user.name, 'John', 'name of created user should be "John"')
- assert.isDefined(user[User.idAttribute])
+ assert.equal(user.name, 'John', 'user.name')
+ assert.isDefined(user[User.idAttribute], 'user[User.idAttribute]')
- assert.debug('find', user[User.idAttribute])
- const foundUser = await adapter.find(User, user[User.idAttribute])
- assert.debug('found', JSON.stringify(foundUser, null, 2))
- assert.equal(foundUser.name, 'John')
- assert.isDefined(foundUser[User.idAttribute])
- assert.equal(foundUser[User.idAttribute], userId)
- assert.equal(foundUser.name, 'John')
+ // Test beforeFind and afterFind
+ let beforeFindCalled = false
+ let 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)
+ let foundUser = await adapter.find(User, userId)
+ 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({ name: 'Sally', [User.idAttribute]: userId })
+ }
+
+ assert.debug('find', User.name, userId)
+ foundUser = await adapter.find(User, userId)
+ 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', props)
+ assert.debug('create', Post.name, props)
const post = await adapter.create(Post, props)
- assert.debug('created', JSON.stringify(post, null, 2))
+ assert.debug('created', Post.name, post)
const postId = post[Post.idAttribute]
- assert.equal(post.content, 'test')
- assert.isDefined(post[Post.idAttribute])
- assert.equal(post.userId, userId)
+
+ 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: post[Post.idAttribute],
- userId: user[User.idAttribute]
+ postId,
+ userId
},
{
content: 'test3',
- postId: post[Post.idAttribute],
- userId: user[User.idAttribute]
+ postId,
+ userId
}
]
- assert.debug('create', props)
+ assert.debug('create', Comment.name, props)
const comments = await Promise.all([
adapter.create(Comment, props[0]),
adapter.create(Comment, props[1])
])
- assert.debug('created', JSON.stringify(comments, null, 2))
+ assert.debug('created', Comment.name, comments)
comments.sort(function (a, b) {
return a.content > b.content
})
- const findPost = await adapter.find(Post, postId, {with: ['user', 'comment']})
- findPost.comments.sort(function (a, b) {
+ assert.debug('find', Post.name, postId)
+ const foundPost = await adapter.find(Post, postId, { with: ['user', 'comment'] })
+ assert.debug('found', Post.name, foundPost)
+ foundPost.comments.sort(function (a, b) {
return a.content > b.content
})
- assert.equalObjects(findPost.user, user)
- assert.equalObjects(findPost.comments, comments)
+ assert.equalObjects(foundPost.user, user, 'foundPost.user')
+ assert.equalObjects(foundPost.comments, comments, 'foundPost.comments')
+ })
+
+ it('should return raw', async function () {
+ let props = { name: 'John' }
+ assert.debug('create', User.name, props)
+ const user = await adapter.create(User, props)
+ assert.debug('created', User.name, user)
+ const 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)
+ const result = await adapter.find(User, userId, { raw: true })
+ 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')
+ })
+
+ it('should return nothing', async function () {
+ assert.debug('find', User.name, 'non-existent-id')
+ const result = await adapter.find(User, 'non-existent-id')
+ assert.debug('found', User.name, result)
+ assert.isUndefined(result, 'result')
+ })
+
+ it('should return raw and nothing', async function () {
+ assert.debug('find', User.name, 'non-existent-id')
+ const result = await adapter.find(User, 'non-existent-id', { raw: true })
+ 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')
})
it('should load belongsTo relations', async function () {
+ this.toClear.push('Post')
+ this.toClear.push('Comment')
+ this.toClear.push('Profile')
let props = { name: 'John' }
- assert.debug('create', props)
+ assert.debug('create', User.name, props)
const user = await adapter.create(User, props)
- assert.debug('created', JSON.stringify(user, null, 2))
+ assert.debug('created', User.name, user)
props = { email: 'foo@test.com', userId: user[User.idAttribute] }
- assert.debug('create', props)
+ assert.debug('create', Profile.name, props)
const profile = await adapter.create(Profile, props)
- assert.debug('created', JSON.stringify(profile, null, 2))
+ assert.debug('created', Profile.name, profile)
props = { content: 'foo', userId: user[User.idAttribute] }
- assert.debug('create', props)
+ assert.debug('create', Post.name, props)
const post = await adapter.create(Post, props)
- assert.debug('created', JSON.stringify(post, null, 2))
+ assert.debug('created', Post.name, post)
props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }
- assert.debug('create', props)
+ assert.debug('create', Comment.name, props)
let comment = await adapter.create(Comment, props)
- assert.debug('created', JSON.stringify(comment, null, 2))
-
- assert.debug('find', comment[Comment.idAttribute])
- comment = await adapter.find(Comment, comment[Comment.idAttribute], {'with': ['user', 'user.profile', 'post', 'post.user']})
- assert.debug('found', JSON.stringify(comment, null, 2))
- assert.isDefined(comment)
- assert.isDefined(comment.post)
- assert.isDefined(comment.post.user)
- assert.isDefined(comment.user)
- assert.isDefined(comment.user.profile)
+ assert.debug('created', Comment.name, comment)
+
+ assert.debug('find', Comment.name, comment[Comment.idAttribute])
+ comment = await adapter.find(Comment, comment[Comment.idAttribute], {'with': ['user', 'post']})
+ assert.debug('found', Comment.name, comment)
+
+ assert.isDefined(comment, 'comment')
+ assert.isDefined(comment.post, 'comment.post')
+ assert.isDefined(comment.user, 'comment.user')
+ })
+
+ it('should load belongsTo relations and filter sub queries', async function () {
+ this.toClear.push('Post')
+ this.toClear.push('Comment')
+ let props = { name: 'John' }
+ assert.debug('create', User.name, props)
+ let user = await adapter.create(User, props)
+ assert.debug('created', User.name, user)
+
+ props = { name: 'Sally' }
+ assert.debug('create', User.name, props)
+ let user2 = await adapter.create(User, props)
+ assert.debug('created', User.name, user)
+
+ props = { status: 'draft', userId: user[User.idAttribute] }
+ assert.debug('create', Post.name, props)
+ const post = await adapter.create(Post, props)
+ assert.debug('created', Post.name, post)
+
+ props = { status: 'published', userId: user[User.idAttribute] }
+ assert.debug('create', Post.name, props)
+ const post2 = await adapter.create(Post, props)
+ assert.debug('created', Post.name, post2)
+
+ props = { status: 'draft', userId: user2[User.idAttribute] }
+ assert.debug('create', Post.name, props)
+ const post3 = await adapter.create(Post, props)
+ assert.debug('created', Post.name, post3)
+
+ props = { status: 'published', userId: user2[User.idAttribute] }
+ assert.debug('create', Post.name, props)
+ const post4 = await adapter.create(Post, props)
+ assert.debug('created', Post.name, post4)
+
+ assert.debug('find', User.name, user[User.idAttribute])
+ user = await adapter.find(User, user[User.idAttribute], {'with': ['post']})
+ 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])
+ user = await adapter.find(User, user[User.idAttribute], {'with': [{
+ relation: 'post',
+ query: {
+ status: 'published'
+ }
+ }]})
+ 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])
+ user = await adapter.find(User, user[User.idAttribute], {'with': [{
+ relation: 'post',
+ replace: true,
+ query: {
+ status: 'published'
+ }
+ }]})
+ 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')
})
+ if (options.hasFeature('findBelongsToNested')) {
+ it('should load belongsTo relations (nested)', async function () {
+ this.toClear.push('Post')
+ this.toClear.push('Comment')
+ this.toClear.push('Profile')
+ let props = { name: 'John' }
+ assert.debug('create', User.name, props)
+ const user = await adapter.create(User, props)
+ assert.debug('created', User.name, user)
+
+ props = { email: 'foo@test.com', userId: user[User.idAttribute] }
+ assert.debug('create', Profile.name, props)
+ const profile = await adapter.create(Profile, props)
+ assert.debug('created', Profile.name, profile)
+
+ props = { content: 'foo', userId: user[User.idAttribute] }
+ assert.debug('create', Post.name, props)
+ const post = await adapter.create(Post, props)
+ assert.debug('created', Post.name, post)
+
+ props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }
+ assert.debug('create', Comment.name, props)
+ let comment = await adapter.create(Comment, props)
+ assert.debug('created', Comment.name, comment)
+
+ assert.debug('find', Comment.name, comment[Comment.idAttribute])
+ comment = await adapter.find(Comment, comment[Comment.idAttribute], {'with': ['user', 'user.profile', 'post', 'post.user']})
+ 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')
+ })
+ }
+
it('should load hasMany and belongsTo relations', async function () {
+ this.toClear.push('Post')
+ this.toClear.push('Comment')
+ this.toClear.push('Profile')
let props = { name: 'John' }
- assert.debug('create', props)
+ assert.debug('create', User.name, props)
const user = await adapter.create(User, props)
- assert.debug('created', JSON.stringify(user, null, 2))
+ assert.debug('created', User.name, user)
props = { email: 'foo@test.com', userId: user[User.idAttribute] }
- assert.debug('create', props)
+ assert.debug('create', Profile.name, props)
const profile = await adapter.create(Profile, props)
- assert.debug('created', JSON.stringify(profile, null, 2))
+ assert.debug('created', Profile.name, profile)
props = { content: 'foo', userId: user[User.idAttribute] }
- assert.debug('create', props)
+ assert.debug('create', Post.name, props)
let post = await adapter.create(Post, props)
- assert.debug('created', JSON.stringify(post, null, 2))
+ let postId = post[Post.idAttribute]
+ assert.debug('created', Post.name, post)
- props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }
- assert.debug('create', props)
+ props = { content: 'test2', postId, userId: post.userId }
+ assert.debug('create', Comment.name, props)
const comment = await adapter.create(Comment, props)
- assert.debug('created', JSON.stringify(comment, null, 2))
+ assert.debug('created', Comment.name, comment)
- assert.debug('find', props, comment[Comment.idAttribute])
- post = await adapter.find(Post, post[Post.idAttribute], {'with': ['user', 'comment', 'comment.user', 'comment.user.profile']})
- assert.debug('found', JSON.stringify(post, null, 2))
+ assert.debug('find', Post.name, postId)
+ post = await adapter.find(Post, postId, {'with': ['user', 'comment']})
+ assert.debug('found', Post.name, post)
- assert.isDefined(post.comments)
- assert.isDefined(post.comments[0].user)
- assert.isDefined(post.comments[0].user.profile)
- assert.isDefined(post.user)
+ assert.isDefined(post.comments, 'post.comments')
+ assert.isDefined(post.user, 'post.user')
})
+
+ if (options.hasFeature('findBelongsToHasManyNested')) {
+ it('should load hasMany and belongsTo relations (nested)', async function () {
+ this.toClear.push('Post')
+ this.toClear.push('Comment')
+ this.toClear.push('Profile')
+ let props = { name: 'John' }
+ assert.debug('create', User.name, props)
+ const user = await adapter.create(User, props)
+ assert.debug('created', User.name, user)
+
+ props = { email: 'foo@test.com', userId: user[User.idAttribute] }
+ assert.debug('create', Profile.name, props)
+ const profile = await adapter.create(Profile, props)
+ assert.debug('created', Profile.name, profile)
+
+ props = { content: 'foo', userId: user[User.idAttribute] }
+ assert.debug('create', Post.name, props)
+ let post = await adapter.create(Post, props)
+ let postId = post[Post.idAttribute]
+ assert.debug('created', Post.name, post)
+
+ props = { content: 'test2', postId, userId: post.userId }
+ assert.debug('create', Comment.name, props)
+ const comment = await adapter.create(Comment, props)
+ assert.debug('created', Comment.name, comment)
+
+ assert.debug('find', Post.name, postId)
+ post = await adapter.find(Post, postId, {'with': ['user', 'comment', 'comment.user', 'comment.user.profile']})
+ 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')
+ })
+ }
+
+ if (options.hasFeature('findHasManyLocalKeys')) {
+ it('should load hasMany localKeys (array) relations', async function () {
+ this.toClear.push('Post')
+ this.toClear.push('Tag')
+ let props = { value: 'big data' }
+ assert.debug('create', Tag.name, props)
+ const tag = await adapter.create(Tag, props)
+ assert.debug('created', Tag.name, tag)
+
+ props = { value: 'servers' }
+ assert.debug('create', Tag.name, props)
+ const tag2 = await adapter.create(Tag, props)
+ assert.debug('created', Tag.name, tag2)
+
+ props = { content: 'test', tagIds: [tag[Tag.idAttribute], tag2[Tag.idAttribute]] }
+ assert.debug('create', Post.name, props)
+ let post = await adapter.create(Post, props)
+ let postId = post[Post.idAttribute]
+ assert.debug('created', Post.name, post)
+
+ assert.debug('find', Post.name, postId)
+ post = await adapter.find(Post, postId, { 'with': ['tag'] })
+ 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]')
+ })
+ it('should load hasMany localKeys (empty array) relations', async function () {
+ this.toClear.push('Post')
+ let props = { content: 'test' }
+ assert.debug('create', Post.name, props)
+ let post = await adapter.create(Post, props)
+ let postId = post[Post.idAttribute]
+ assert.debug('created', Post.name, post)
+
+ assert.debug('find', Post.name, postId)
+ post = await adapter.find(Post, postId, { 'with': ['tag'] })
+ 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')
+ })
+ it('should load hasMany localKeys (object) relations', async function () {
+ this.toClear.push('Post')
+ this.toClear.push('Tag')
+ let props = { value: 'big data' }
+ assert.debug('create', Tag.name, props)
+ const tag = await adapter.create(Tag, props)
+ assert.debug('created', Tag.name, tag)
+
+ props = { value: 'servers' }
+ assert.debug('create', Tag.name, props)
+ const tag2 = await adapter.create(Tag, props)
+ assert.debug('created', Tag.name, tag2)
+
+ props = { content: 'test', tagIds: { [tag[Tag.idAttribute]]: true, [tag2[Tag.idAttribute]]: true } }
+ assert.debug('create', Post.name, props)
+ let post = await adapter.create(Post, props)
+ let postId = post[Post.idAttribute]
+ assert.debug('created', Post.name, post)
+
+ assert.debug('find', Post.name, postId)
+ post = await adapter.find(Post, postId, { 'with': ['tag'] })
+ 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]')
+ })
+ }
+
+ if (options.hasFeature('findHasManyForeignKeys')) {
+ it('should load hasMany foreignKeys (array) relations', async function () {
+ this.toClear.push('Post')
+ this.toClear.push('Tag')
+ let props = { value: 'big data' }
+ assert.debug('create', Tag.name, props)
+ let tag = await adapter.create(Tag, props)
+ let tagId = tag[Tag.idAttribute]
+ assert.debug('created', Tag.name, tag)
+
+ props = { value: 'servers' }
+ assert.debug('create', Tag.name, props)
+ let tag2 = await adapter.create(Tag, props)
+ let tag2Id = tag2[Tag.idAttribute]
+ assert.debug('created', Tag.name, tag2)
+
+ props = { content: 'test', tagIds: [tagId] }
+ assert.debug('create', Post.name, props)
+ let post = await adapter.create(Post, props)
+ assert.debug('created', Post.name, post)
+
+ props = { content: 'test2', tagIds: [tagId, tag2Id] }
+ assert.debug('create', Post.name, props)
+ let post2 = await adapter.create(Post, props)
+ assert.debug('created', Post.name, post2)
+
+ assert.debug('find', Tag.name, tagId)
+ tag = await adapter.find(Tag, tagId, { 'with': ['post'] })
+ 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)
+ tag2 = await adapter.find(Tag, tag2Id, { 'with': ['post'] })
+ 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')
+ })
+ }
})
}
diff --git a/src/findAll.test.js b/src/findAll.test.js
index 3295119..d66fab5 100644
--- a/src/findAll.test.js
+++ b/src/findAll.test.js
@@ -1,4 +1,5 @@
-module.exports = function (options) {
+/* global assert:true */
+export default function (options) {
describe('Adapter#findAll', function () {
var adapter, User, Profile, Post, Comment
@@ -16,25 +17,26 @@ module.exports = function (options) {
it('should filter users', async function () {
let props = { name: 'John' }
- assert.debug('findAll', { age: 30 })
+ assert.debug('findAll', User.name, { age: 30 })
const users = await adapter.findAll(User, { age: 30 })
- assert.debug('found', JSON.stringify(users, null, 2))
- assert.equal(users.length, 0)
+ assert.debug('found', User.name, users)
+ assert.equal(users.length, 0, 'users.length')
- assert.debug('create', props)
+ assert.debug('create', User.name, props)
const user = await adapter.create(User, props)
- assert.debug('created', JSON.stringify(user, null, 2))
+ assert.debug('created', User.name, user)
const userId = user[User.idAttribute]
- assert.debug('findAll', { name: 'John' })
+ assert.debug('findAll', User.name, { name: 'John' })
const users2 = await adapter.findAll(User, { name: 'John' })
- assert.debug('found', JSON.stringify(users2, null, 2))
- assert.equal(users2.length, 1)
- assert.equal(users2[0][User.idAttribute], userId)
- assert.equal(users2[0].name, 'John')
+ 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)
})
- if (options.features === 'all' || options.features.indexOf('inOp') !== -1) {
+ if (options.hasFeature('findAllInOp')) {
it('should filter users using the "in" operator', async function () {
var users = await adapter.findAll(User, {
where: {
@@ -43,22 +45,19 @@ module.exports = function (options) {
}
}
})
- assert.equal(users.length, 0)
+ assert.equal(users.length, 0, 'users.length')
var user = await adapter.create(User, {name: 'John'})
- var id = user.id
+ var id = user[User.idAttribute]
var users2 = await adapter.findAll(User, { name: 'John' })
- assert.equal(users2.length, 1)
- assert.equal(users2[0].id, id)
- assert.equal(users2[0].name, 'John')
-
- var destroyedUser = await adapter.destroy(User, id)
- assert.isFalse(!!destroyedUser)
+ 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')
})
}
- if (options.features === 'all' || options.features.indexOf('likeOp') !== -1) {
+ if (options.hasFeature('findAllLikeOp')) {
it('should filter users using the "like" operator', async function () {
var users = await adapter.findAll(User, {
where: {
@@ -82,126 +81,312 @@ module.exports = function (options) {
assert.equal(users2.length, 1)
assert.equal(users2[0].id, id)
assert.equal(users2[0].name, 'John')
-
- var destroyedUser = await adapter.destroy(User, id)
- assert.isFalse(!!destroyedUser)
})
}
- if (options.features === 'all' || options.features.indexOf('filterOpNotFound') !== -1) {
- it('should throw "Operator not found" error', async function () {
- assert.throw(function () {
- return adapter.findAll(User, {
- where: {
- name: {
- op: 'John'
- }
+ if (options.hasFeature('findAllOpNotFound')) {
+ it('should throw "Operator not found" error', function () {
+ return adapter.findAll(User, {
+ where: {
+ name: {
+ op: 'John'
}
- })
- }, Error, 'Operator not found')
+ }
+ }).then(function () {
+ throw new Error('should have failed!')
+ }, function (err) {
+ assert.equal(err.message, 'Operator op not supported!')
+ })
})
}
- it('should load belongsTo relations', async function () {
- let props = { name: 'John' }
- assert.debug('create', props)
- const user = await adapter.create(User, props)
- assert.debug('created', JSON.stringify(user, null, 2))
-
- props = { email: 'foo@test.com', userId: user[User.idAttribute] }
- assert.debug('create', props)
- const profile = await adapter.create(Profile, props)
- assert.debug('created', JSON.stringify(profile, null, 2))
-
- props = { content: 'foo', userId: user[User.idAttribute] }
- assert.debug('create', props)
- const post = await adapter.create(Post, props)
- assert.debug('created', JSON.stringify(post, null, 2))
-
- props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }
- assert.debug('create', props)
- let comment = await adapter.create(Comment, props)
- assert.debug('created', JSON.stringify(comment, null, 2))
-
- props = { name: 'Sally' }
- assert.debug('create', props)
- const user2 = await adapter.create(User, props)
- assert.debug('created', JSON.stringify(user2, null, 2))
-
- props = { content: 'bar', userId: user2[User.idAttribute] }
- assert.debug('create', props)
- const post2 = await adapter.create(Post, props)
- assert.debug('created', JSON.stringify(post2, null, 2))
-
- props = { content: 'test67', postId: post2[Post.idAttribute], userId: post2.userId }
- assert.debug('create', props)
- let comment2 = await adapter.create(Comment, props)
- assert.debug('created', JSON.stringify(comment2, null, 2))
-
- assert.debug('findAll')
- const comments = await adapter.findAll(Comment, {}, {'with': ['user', 'user.profile', 'post', 'post.user']})
- assert.debug('found', JSON.stringify(comments, null, 2))
- assert.isDefined(comments[0].post)
- assert.isDefined(comments[0].post.user)
- assert.isDefined(comments[0].user)
- assert.isDefined(comments[0].user.profile || comments[1].user.profile)
- assert.isDefined(comments[1].post)
- assert.isDefined(comments[1].post.user)
- assert.isDefined(comments[1].user)
- })
+ if (options.hasFeature('findAllBelongsTo')) {
+ it('should load belongsTo relations', async function () {
+ this.toClear.push('Post')
+ this.toClear.push('Profile')
+ this.toClear.push('Comment')
+ let props = { name: 'John' }
+ assert.debug('create', User.name, props)
+ const user = await adapter.create(User, props)
+ assert.debug('created', User.name, user)
+
+ props = { email: 'foo@test.com', userId: user[User.idAttribute] }
+ assert.debug('create', Profile.name, props)
+ const profile = await adapter.create(Profile, props)
+ assert.debug('created', Profile.name, profile)
+
+ props = { content: 'foo', userId: user[User.idAttribute] }
+ assert.debug('create', Post.name, props)
+ const post = await adapter.create(Post, props)
+ assert.debug('created', Post.name, post)
+
+ props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }
+ assert.debug('create', Comment.name, props)
+ let comment = await adapter.create(Comment, props)
+ assert.debug('created', Comment.name, comment)
+
+ props = { name: 'Sally' }
+ assert.debug('create', User.name, props)
+ const user2 = await adapter.create(User, props)
+ assert.debug('created', User.name, user2)
+
+ props = { content: 'bar', userId: user2[User.idAttribute] }
+ assert.debug('create', Post.name, props)
+ const post2 = await adapter.create(Post, props)
+ assert.debug('created', Post.name, post2)
+
+ props = { content: 'test67', postId: post2[Post.idAttribute], userId: post2.userId }
+ assert.debug('create', Comment.name, props)
+ let comment2 = await adapter.create(Comment, props)
+ assert.debug('created', Comment.name, comment2)
+
+ assert.debug('findAll', Comment.name, {})
+ const comments = await adapter.findAll(Comment, {}, {'with': ['user', 'post']})
+ 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')
+ })
- it('should load hasMany and belongsTo relations', async function () {
- let props = { name: 'John' }
- assert.debug('create', props)
- const user = await adapter.create(User, props)
- assert.debug('created', JSON.stringify(user, null, 2))
-
- props = { email: 'foo@test.com', userId: user[User.idAttribute] }
- assert.debug('create', props)
- const profile = await adapter.create(Profile, props)
- assert.debug('created', JSON.stringify(profile, null, 2))
-
- props = { content: 'foo', userId: user[User.idAttribute] }
- assert.debug('create', props)
- const post = await adapter.create(Post, props)
- assert.debug('created', JSON.stringify(post, null, 2))
-
- props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }
- assert.debug('create', props)
- let comment = await adapter.create(Comment, props)
- assert.debug('created', JSON.stringify(comment, null, 2))
-
- props = { name: 'Sally' }
- assert.debug('create', props)
- const user2 = await adapter.create(User, props)
- assert.debug('created', JSON.stringify(user2, null, 2))
-
- props = { content: 'bar', userId: user2[User.idAttribute] }
- assert.debug('create', props)
- const post2 = await adapter.create(Post, props)
- assert.debug('created', JSON.stringify(post2, null, 2))
-
- props = { content: 'test67', postId: post2[Post.idAttribute], userId: post2.userId }
- assert.debug('create', props)
- let comment2 = await adapter.create(Comment, props)
- assert.debug('created', JSON.stringify(comment2, null, 2))
-
- assert.debug('find')
- const posts = await adapter.findAll(Post, {}, {'with': ['user', 'comment', 'comment.user', 'comment.user.profile']})
- assert.debug('found', JSON.stringify(posts, null, 2))
- assert.isDefined(posts[0].comments)
- assert.isDefined(posts[0].comments[0].user)
- assert.isDefined(posts[0].comments[0].user.profile || posts[1].comments[0].user.profile)
- assert.isDefined(posts[0].user)
- assert.isDefined(posts[1].comments)
- assert.isDefined(posts[1].comments[0].user)
- assert.isDefined(posts[1].user)
- })
+ it('should load belongsTo relations and filter sub queries', async function () {
+ this.toClear.push('Post')
+ this.toClear.push('Comment')
+ let props = { name: 'John' }
+ assert.debug('create', User.name, props)
+ let user = await adapter.create(User, props)
+ assert.debug('created', User.name, user)
+
+ props = { name: 'Sally' }
+ assert.debug('create', User.name, props)
+ let user2 = await adapter.create(User, props)
+ assert.debug('created', User.name, user)
+
+ props = { status: 'draft', userId: user[User.idAttribute] }
+ assert.debug('create', Post.name, props)
+ const post = await adapter.create(Post, props)
+ assert.debug('created', Post.name, post)
+
+ props = { status: 'published', userId: user[User.idAttribute] }
+ assert.debug('create', Post.name, props)
+ const post2 = await adapter.create(Post, props)
+ assert.debug('created', Post.name, post2)
+
+ props = { status: 'draft', userId: user2[User.idAttribute] }
+ assert.debug('create', Post.name, props)
+ const post3 = await adapter.create(Post, props)
+ assert.debug('created', Post.name, post3)
+
+ props = { status: 'published', userId: user2[User.idAttribute] }
+ assert.debug('create', Post.name, props)
+ const post4 = await adapter.create(Post, props)
+ assert.debug('created', Post.name, post4)
+
+ assert.debug('findAll', User.name, { [User.idAttribute]: user[User.idAttribute] })
+ let users = await adapter.findAll(User, { [User.idAttribute]: user[User.idAttribute] }, {'with': ['post']})
+ 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, { [User.idAttribute]: user[User.idAttribute] })
+ users = await adapter.findAll(User, { [User.idAttribute]: user[User.idAttribute] }, {'with': [{
+ relation: 'post',
+ query: {
+ status: 'published'
+ }
+ }]})
+ 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, { [User.idAttribute]: user[User.idAttribute] })
+ users = await adapter.findAll(User, { [User.idAttribute]: user[User.idAttribute] }, {'with': [{
+ relation: 'post',
+ replace: true,
+ query: {
+ status: 'published'
+ }
+ }]})
+ 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')
+ })
+ }
+
+ if (options.hasFeature('findAllBelongsToNested')) {
+ it('should load belongsTo relations (nested)', async function () {
+ this.toClear.push('Post')
+ this.toClear.push('Profile')
+ this.toClear.push('Comment')
+ let props = { name: 'John' }
+ assert.debug('create', User.name, props)
+ const user = await adapter.create(User, props)
+ assert.debug('created', User.name, user)
+
+ props = { email: 'foo@test.com', userId: user[User.idAttribute] }
+ assert.debug('create', Profile.name, props)
+ const profile = await adapter.create(Profile, props)
+ assert.debug('created', Profile.name, profile)
+
+ props = { content: 'foo', userId: user[User.idAttribute] }
+ assert.debug('create', Post.name, props)
+ const post = await adapter.create(Post, props)
+ assert.debug('created', Post.name, post)
+
+ props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }
+ assert.debug('create', Comment.name, props)
+ let comment = await adapter.create(Comment, props)
+ assert.debug('created', Comment.name, comment)
+
+ props = { name: 'Sally' }
+ assert.debug('create', User.name, props)
+ const user2 = await adapter.create(User, props)
+ assert.debug('created', User.name, user2)
+
+ props = { content: 'bar', userId: user2[User.idAttribute] }
+ assert.debug('create', Post.name, props)
+ const post2 = await adapter.create(Post, props)
+ assert.debug('created', Post.name, post2)
+
+ props = { content: 'test67', postId: post2[Post.idAttribute], userId: post2.userId }
+ assert.debug('create', Comment.name, props)
+ let comment2 = await adapter.create(Comment, props)
+ assert.debug('created', Comment.name, comment2)
+
+ assert.debug('findAll', Comment.name, {})
+ const comments = await adapter.findAll(Comment, {}, {'with': ['user', 'user.profile', 'post', 'post.user']})
+ 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')
+ })
+ }
- if (options.features === 'all' || options.features.indexOf('filterOnRelations') !== -1) {
+ if (options.hasFeature('findAllBelongsToHasMany')) {
+ it('should load hasMany and belongsTo relations', async function () {
+ this.toClear.push('Post')
+ this.toClear.push('Profile')
+ this.toClear.push('Comment')
+ let props = { name: 'John' }
+ assert.debug('create', User.name, props)
+ const user = await adapter.create(User, props)
+ assert.debug('created', User.name, user)
+
+ props = { email: 'foo@test.com', userId: user[User.idAttribute] }
+ assert.debug('create', Profile.name, props)
+ const profile = await adapter.create(Profile, props)
+ assert.debug('created', Profile.name, profile)
+
+ props = { content: 'foo', userId: user[User.idAttribute] }
+ assert.debug('create', Post.name, props)
+ const post = await adapter.create(Post, props)
+ assert.debug('created', Post.name, post)
+
+ props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }
+ assert.debug('create', Comment.name, props)
+ let comment = await adapter.create(Comment, props)
+ assert.debug('created', Comment.name, comment)
+
+ props = { name: 'Sally' }
+ assert.debug('create', User.name, props)
+ const user2 = await adapter.create(User, props)
+ assert.debug('created', User.name, user2)
+
+ props = { content: 'bar', userId: user2[User.idAttribute] }
+ assert.debug('create', Post.name, props)
+ const post2 = await adapter.create(Post, props)
+ assert.debug('created', Post.name, post2)
+
+ props = { content: 'test67', postId: post2[Post.idAttribute], userId: post2.userId }
+ assert.debug('create', Comment.name, props)
+ let comment2 = await adapter.create(Comment, props)
+ assert.debug('created', Comment.name, comment2)
+
+ assert.debug('find', Post.name, {})
+ const posts = await adapter.findAll(Post, {}, {'with': ['user', 'comment']})
+ 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')
+ })
+ }
+
+ if (options.hasFeature('findAllBelongsToHasManyNested')) {
+ it('should load hasMany and belongsTo relations', async function () {
+ this.toClear.push('Post')
+ this.toClear.push('Profile')
+ this.toClear.push('Comment')
+ let props = { name: 'John' }
+ assert.debug('create', User.name, props)
+ const user = await adapter.create(User, props)
+ assert.debug('created', User.name, user)
+
+ props = { email: 'foo@test.com', userId: user[User.idAttribute] }
+ assert.debug('create', Profile.name, props)
+ const profile = await adapter.create(Profile, props)
+ assert.debug('created', Profile.name, profile)
+
+ props = { content: 'foo', userId: user[User.idAttribute] }
+ assert.debug('create', Post.name, props)
+ const post = await adapter.create(Post, props)
+ assert.debug('created', Post.name, post)
+
+ props = { content: 'test2', postId: post[Post.idAttribute], userId: post.userId }
+ assert.debug('create', Comment.name, props)
+ let comment = await adapter.create(Comment, props)
+ assert.debug('created', Comment.name, comment)
+
+ props = { name: 'Sally' }
+ assert.debug('create', User.name, props)
+ const user2 = await adapter.create(User, props)
+ assert.debug('created', User.name, user2)
+
+ props = { content: 'bar', userId: user2[User.idAttribute] }
+ assert.debug('create', Post.name, props)
+ const post2 = await adapter.create(Post, props)
+ assert.debug('created', Post.name, post2)
+
+ props = { content: 'test67', postId: post2[Post.idAttribute], userId: post2.userId }
+ assert.debug('create', Comment.name, props)
+ let comment2 = await adapter.create(Comment, props)
+ assert.debug('created', Comment.name, comment2)
+
+ assert.debug('find', Post.name, {})
+ const posts = await adapter.findAll(Post, {}, {'with': ['user', 'comment', 'comment.user', 'comment.user.profile']})
+ 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')
+ })
+ }
+
+ if (options.hasFeature('filterOnRelations')) {
it('should filter using belongsTo relation', async function () {
+ this.toClear.push('Post')
+ this.toClear.push('Profile')
+ this.toClear.push('Comment')
var profile1 = await adapter.create(Profile, { email: 'foo@test.com' })
var user1 = await adapter.create(User, {name: 'John', profileId: profile1.id})
+
var post1 = await adapter.create(Post, {content: 'foo', userId: user1.id})
await adapter.create(Comment, {content: 'test1', postId: post1.id, userId: post1.userId})
@@ -216,8 +401,12 @@ module.exports = function (options) {
})
it('should filter through multiple hasOne/belongsTo relations', async function () {
+ this.toClear.push('Post')
+ this.toClear.push('Profile')
+ this.toClear.push('Comment')
var profile1 = await adapter.create(Profile, { email: 'foo@test.com' })
var user1 = await adapter.create(User, {name: 'John', profileId: profile1.id})
+
var post1 = await adapter.create(Post, {content: 'foo', userId: user1.id})
await adapter.create(Comment, {content: 'test1', postId: post1.id, userId: post1.userId})
@@ -233,8 +422,12 @@ module.exports = function (options) {
})
it('should filter using multiple hasOne/belongsTo relations', async function () {
+ this.toClear.push('Post')
+ this.toClear.push('Profile')
+ this.toClear.push('Comment')
var profile1 = await adapter.create(Profile, { email: 'foo@test.com' })
var user1 = await adapter.create(User, {name: 'John', profileId: profile1.id})
+
var post1 = await adapter.create(Post, {content: 'foo', userId: user1.id})
await adapter.create(Comment, {content: 'test1', postId: post1.id, userId: post1.userId})
diff --git a/src/index.js b/src/index.js
index 1712ca3..fa6dc0d 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,3 +1,23 @@
+import afterCreateTest from './afterCreate.test'
+import afterUpdateTest from './afterUpdate.test'
+import beforeCreateTest from './beforeCreate.test'
+import beforeUpdateTest from './beforeUpdate.test'
+import countTest from './count.test'
+import createTest from './create.test'
+import createManyTest from './createMany.test'
+import destroyTest from './destroy.test'
+import destroyAllTest from './destroyAll.test'
+import extendTest from './extend.test'
+import findTest from './find.test'
+import findAllTest from './findAll.test'
+import sumTest from './sum.test'
+import updateTest from './update.test'
+import updateAllTest from './updateAll.test'
+import updateManyTest from './updateMany.test'
+
+import {assert} from 'chai'
+import sinon from 'sinon'
+
assert.equalObjects = function (a, b, m) {
assert.deepEqual(JSON.parse(JSON.stringify(a)), JSON.parse(JSON.stringify(b)), m || (JSON.stringify(a) + ' should be equal to ' + JSON.stringify(b)))
}
@@ -10,31 +30,47 @@ let debug = false
assert.debug = function (...args) {
if (debug) {
- console.log(...args)
+ args.forEach(function (arg, i) {
+ args[i] = JSON.stringify(arg, null, 2)
+ })
+ console.log('DEBUG (TEST):', ...args)
}
}
var prefix = 'TestRunner.init(options): options'
-module.exports = {
+export default {
init: function (options) {
options = options || {}
debug = !!options.debug
- options.methods = options.methods || 'all'
- options.features = options.features || 'all'
- if (!options.DS || typeof options.DS !== 'function') {
- throw new Error(prefix + '.DS: Expected function, Actual: ' + typeof options.DS)
+ 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.$$store = new options.DS(options.storeConfig || {
- log: false,
- debug: false
+ this.$$container = new options.JSData.Container(options.containerConfig || {
+ mapperDefaults: {
+ debug: false
+ }
+ })
+ this.$$store = new options.JSData.DataStore(options.storeConfig || {
+ mapperDefaults: {
+ debug: false
+ }
})
- this.$$User = this.$$store.defineResource(options.userConfig || {
+ this.$$container.registerAdapter('adapter', this.$$adapter, { 'default': true })
+ this.$$store.registerAdapter('adapter', this.$$adapter, { 'default': true })
+ var userOptions = {
name: 'user',
relations: {
hasMany: {
@@ -52,98 +88,173 @@ module.exports = {
localField: 'address',
foreignKey: 'userId'
}
- }
- }
- })
- this.$$Profile = this.$$store.defineResource(options.profileConfig || {
- name: 'profile',
- relations: {
+ },
belongsTo: {
- user: {
- localField: 'user',
- localkey: 'userId'
+ organization: {
+ localField: 'organization',
+ foreignKey: 'organizationId'
}
}
}
- })
- this.$$Address = this.$$store.defineResource(options.addressConfig || {
- name: 'address',
+ }
+ var organizationOptions = {
+ name: 'organization',
relations: {
- belongsTo: {
+ hasMany: {
user: {
- localField: 'user',
- localkey: 'userId'
+ localField: 'users',
+ foreignKey: 'organizationId'
}
}
}
- })
- this.$$Post = this.$$store.defineResource(options.postConfig || {
+ }
+ var postOptions = {
name: 'post',
relations: {
belongsTo: {
user: {
localField: 'user',
- localKey: 'userId'
+ foreignKey: 'userId'
}
},
hasMany: {
comment: {
localField: 'comments',
foreignKey: 'postId'
+ },
+ tag: {
+ localField: 'tags',
+ localKeys: 'tagIds'
}
}
}
- })
- this.$$Comment = this.$$store.defineResource(options.commentConfig || {
+ }
+ var commentOptions = {
name: 'comment',
relations: {
belongsTo: {
post: {
localField: 'post',
- localKey: 'postId'
+ foreignKey: 'postId'
},
user: {
localField: 'user',
- localKey: 'userId'
+ 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.methods === 'all' || options.methods.indexOf('create') !== -1) {
- require('./create.test')(options)
+ 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.methods === 'all' || options.methods.indexOf('find') !== -1) {
- require('./find.test')(options)
+ if (options.hasMethod('createMany')) {
+ createManyTest(options)
}
- if (options.methods === 'all' || options.methods.indexOf('findAll') !== -1) {
- require('./findAll.test')(options)
+ if (options.hasMethod('extend')) {
+ extendTest(options)
}
- if (options.methods === 'all' || options.methods.indexOf('destroy') !== -1) {
- require('./destroy.test')(options)
+ if (options.hasMethod('find')) {
+ findTest(options)
}
- if (options.methods === 'all' || options.methods.indexOf('destroyAll') !== -1) {
- require('./destroyAll.test')(options)
+ if (options.hasMethod('findAll')) {
+ findAllTest(options)
}
- if (options.methods === 'all' || options.methods.indexOf('update') !== -1) {
- require('./update.test')(options)
+ if (options.hasMethod('destroy')) {
+ destroyTest(options)
}
- if (options.methods === 'all' || options.methods.indexOf('updateAll') !== -1) {
- require('./updateAll.test')(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(async function () {
- await this.$$adapter.destroyAll(this.$$Comment)
- await this.$$adapter.destroyAll(this.$$Post)
- await this.$$adapter.destroyAll(this.$$User)
- await this.$$adapter.destroyAll(this.$$Profile)
- await this.$$adapter.destroyAll(this.$$Address)
+ const Test = this
+ const 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')
+ }
+ let promise = Promise.resolve()
+ toClear.forEach(function (Mapper) {
+ promise = promise.then(function () {
+ return Test.$$adapter.destroyAll(Test['$$' + Mapper])
+ })
+ })
+ await promise
})
},
- assert: assert,
+ assert,
+ sinon,
fail: function (msg) {
assert.equal('should not reach this!: ' + msg, 'failure')
},
diff --git a/src/sum.test.js b/src/sum.test.js
new file mode 100644
index 0000000..2a7d0a1
--- /dev/null
+++ b/src/sum.test.js
@@ -0,0 +1,80 @@
+/* global assert:true */
+export default 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', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John', age: 30 }
+
+ assert.debug('sum', User.name, {})
+ let sum = await adapter.sum(User, 'age')
+ assert.debug('summed', User.name, sum)
+ assert.equal(sum, 0)
+
+ assert.debug('sum', User.name, { name: 'John' })
+ sum = await adapter.sum(User, 'age', { name: 'John' })
+ assert.debug('summed', User.name, sum)
+ assert.equal(sum, 0)
+
+ assert.debug('sum', User.name, { name: 'Sally' })
+ sum = await adapter.sum(User, 'age', { name: 'Sally' })
+ assert.debug('summed', User.name, sum)
+ assert.equal(sum, 0)
+
+ assert.debug('create', User.name, props)
+ const user = await adapter.create(User, props)
+ assert.debug('created', User.name, user)
+
+ assert.debug('sum', User.name, {})
+ sum = await adapter.sum(User, 'age')
+ assert.debug('summed', User.name, sum)
+ assert.equal(sum, 30)
+
+ assert.debug('sum', User.name, { name: 'John' })
+ sum = await adapter.sum(User, 'age', { name: 'John' })
+ assert.debug('summed', User.name, sum)
+ assert.equal(sum, 30)
+
+ assert.debug('sum', User.name, { name: 'Sally' })
+ sum = await adapter.sum(User, 'age', { name: 'Sally' })
+ assert.debug('summed', User.name, sum)
+ assert.equal(sum, 0)
+
+ assert.debug('create', User.name, { name: 'Sally' })
+ const user2 = await adapter.create(User, { name: 'Sally', age: 27 })
+ assert.debug('created', User.name, user2)
+
+ assert.debug('sum', User.name, {})
+ sum = await adapter.sum(User, 'age')
+ assert.debug('summed', User.name, sum)
+ assert.equal(sum, 57)
+
+ assert.debug('sum', User.name, { name: 'John' })
+ sum = await adapter.sum(User, 'age', { name: 'John' })
+ assert.debug('summed', User.name, sum)
+ assert.equal(sum, 30)
+
+ assert.debug('sum', User.name, { name: 'Sally' })
+ sum = await adapter.sum(User, 'age', { name: 'Sally' })
+ assert.debug('summed', User.name, sum)
+ assert.equal(sum, 27)
+ })
+ it('should sum users\' age and return raw', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John', age: 30 }
+
+ assert.debug('create', User.name, props)
+ let user = await adapter.create(User, props)
+ assert.debug('created', User.name, user)
+
+ assert.debug('sum', User.name, props)
+ const result = await adapter.sum(User, 'age', props, { raw: true })
+ assert.debug('summed', User.name, result)
+ assert.equal(result.data, 30, 'result.data')
+ })
+ })
+}
diff --git a/src/update.test.js b/src/update.test.js
index 80a3da6..114cbf1 100644
--- a/src/update.test.js
+++ b/src/update.test.js
@@ -1,4 +1,5 @@
-module.exports = function (options) {
+/* global assert:true */
+export default function (options) {
describe('Adapter#update', function () {
it('should exist', function () {
assert.equal(typeof this.$$adapter.update, 'function', 'adapter should have a "update" method')
@@ -8,32 +9,67 @@ module.exports = function (options) {
const User = this.$$User
const props = { name: 'John' }
- assert.debug('create', props)
+ assert.debug('create', User.name, props)
const user = await adapter.create(User, props)
- assert.debug('created', JSON.stringify(user, null, 2))
+ 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[User.idAttribute])
+ assert.debug('find', User.name, user[User.idAttribute])
let foundUser = await adapter.find(User, user[User.idAttribute])
- assert.debug('found', JSON.stringify(foundUser, null, 2))
+ 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[User.idAttribute], { name: 'Johnny' })
- const updatedUser = await adapter.update(User, user[User.idAttribute], { name: 'Johnny' })
- assert.debug('found', JSON.stringify(updatedUser, null, 2))
+ assert.debug('update', User.name, user[User.idAttribute], { name: 'Johnny' })
+ let updatedUser = await adapter.update(User, user[User.idAttribute], { name: 'Johnny' })
+ assert.debug('updated', User.name, updatedUser)
assert.equal(updatedUser.name, 'Johnny')
assert.equal(updatedUser[User.idAttribute], user[User.idAttribute])
- assert.debug('find', user[User.idAttribute])
+ assert.debug('find', User.name, user[User.idAttribute])
foundUser = await adapter.find(User, user[User.idAttribute])
- assert.debug('found', JSON.stringify(foundUser, null, 2))
+ assert.debug('found', User.name, foundUser)
assert.equal(foundUser.name, 'Johnny')
assert.equal(foundUser[User.idAttribute], user[User.idAttribute])
})
+ it('should update a user and return raw', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+ const props = { name: 'John' }
+
+ assert.debug('create', User.name, props)
+ const user = await adapter.create(User, props)
+ 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' })
+ const result = await adapter.update(User, user[User.idAttribute], { name: 'Johnny' }, { raw: true })
+ 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')
+ })
+ it('should throw when updating non-existent row', async function () {
+ const adapter = this.$$adapter
+ const User = this.$$User
+
+ assert.debug('update', 'non-existent-id', { name: 'Johnny' })
+ try {
+ await adapter.update(User, 'non-existent-id', { name: 'Johnny' })
+ throw new Error('update should have failed!')
+ } catch (err) {
+ assert.debug('correctly threw error', err.message)
+ assert.isDefined(err.message, 'err.message is defined')
+ assert.equal(err.message, 'Not Found', 'err.message should be "Not Found"')
+ }
+ })
})
}
diff --git a/src/updateAll.test.js b/src/updateAll.test.js
index a8e1da4..0e602b1 100644
--- a/src/updateAll.test.js
+++ b/src/updateAll.test.js
@@ -1,4 +1,5 @@
-module.exports = function (options) {
+/* global assert:true */
+export default function (options) {
describe('Adapter#updateAll', function () {
it('should exist', function () {
assert.equal(typeof this.$$adapter.updateAll, 'function', 'adapter should have a "updateAll" method')
@@ -8,21 +9,21 @@ module.exports = function (options) {
const User = this.$$User
let props = { name: 'John', age: 20 }
- assert.debug('create', props)
+ assert.debug('create', User.name, props)
const user1 = await adapter.create(User, props)
- assert.debug('created', JSON.stringify(user1, null, 2))
+ assert.debug('created', User.name, user1)
const userId1 = user1[User.idAttribute]
props = { name: 'John', age: 30 }
- assert.debug('create', props)
+ assert.debug('create', User.name, props)
const user2 = await adapter.create(User, props)
- assert.debug('created', JSON.stringify(user2, null, 2))
+ assert.debug('created', User.name, user2)
const userId2 = user2[User.idAttribute]
- assert.debug('findAll', { name: 'John' })
+ assert.debug('findAll', User.name, { name: 'John' })
const users = await adapter.findAll(User, { name: 'John' })
- assert.debug('found', JSON.stringify(users, null, 2))
+ assert.debug('found', User.name, users)
users.sort(function (a, b) {
return a.age - b.age
})
@@ -33,9 +34,9 @@ module.exports = function (options) {
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', { name: 'Johnny' }, { name: 'John' })
+ assert.debug('updateAll', User.name, { name: 'Johnny' }, { name: 'John' })
const users2 = await adapter.updateAll(User, { name: 'Johnny' }, { name: 'John' })
- assert.debug('updated', JSON.stringify(users2, null, 2))
+ assert.debug('updated', User.name, users2)
users2.sort(function (a, b) {
return a.age - b.age
})
@@ -46,15 +47,16 @@ module.exports = function (options) {
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', { name: 'John' })
+ assert.debug('findAll', User.name, { name: 'John' })
const users3 = await adapter.findAll(User, { name: 'John' })
- assert.debug('found', JSON.stringify(users3, null, 2))
+ assert.debug('found', User.name, users3)
assert.equalObjects(users3, [])
assert.equal(users3.length, 0)
- assert.debug('findAll', { name: 'Johnny' })
+ assert.debug('findAll', User.name, { name: 'Johnny' })
const users4 = await adapter.findAll(User, { name: 'Johnny' })
- assert.debug('found', JSON.stringify(users4, null, 2))
+ assert.debug('found', User.name, users4)
+
users4.sort(function (a, b) {
return a.age - b.age
})
diff --git a/src/updateMany.test.js b/src/updateMany.test.js
new file mode 100644
index 0000000..09143c7
--- /dev/null
+++ b/src/updateMany.test.js
@@ -0,0 +1,52 @@
+/* global assert:true */
+export default 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', async function () {
+ var adapter = this.$$adapter
+ var User = this.$$User
+ var user1 = await adapter.create(User, {name: 'John', age: 20})
+ var userId1 = user1.id
+
+ var user2 = await adapter.create(User, {name: 'John', age: 30})
+ var userId2 = user2.id
+
+ var users = await adapter.findAll(User, { name: 'John' })
+ 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
+ var users2 = await adapter.updateMany(User, [user1, user2])
+ 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)
+
+ var users3 = await adapter.findAll(User, { age: 20 })
+ assert.objectsEqual(users3, [])
+ assert.equal(users3.length, 0)
+
+ var users4 = await adapter.findAll(User, { age: 101 })
+ 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)
+ })
+ })
+}
diff --git a/webpack.config.js b/webpack.config.js
deleted file mode 100644
index 8282517..0000000
--- a/webpack.config.js
+++ /dev/null
@@ -1,18 +0,0 @@
-module.exports = {
- devtool: 'source-map',
- entry: './src/index.js',
- output: {
- filename: './dist/js-data-adapter-tests.js',
- libraryTarget: 'umd',
- library: 'TestRunner'
- },
- module: {
- loaders: [
- {
- test: /(src)(.+)\.js$/,
- exclude: /(node_modules|bower_components)/,
- loader: 'babel'
- }
- ]
- }
-};