mirror of
https://github.com/nocobase/nocobase
synced 2024-11-15 07:25:15 +00:00
Test cases for database (#16)
* fix: remove unused import * fix: use env instead of hard code for create database instance * refactor: change most "all" hook to "each" hook * refactor: split test suits into files * add: use DB_LOG_SQL in env to control SQL in log * add: test for logical operator and fixes
This commit is contained in:
parent
53729e188a
commit
b0ba1472bb
@ -5,6 +5,9 @@ DB_DATABASE=nocobase
|
|||||||
DB_USER=test
|
DB_USER=test
|
||||||
DB_PASSWORD=test
|
DB_PASSWORD=test
|
||||||
|
|
||||||
|
# set to 'on' to enable log
|
||||||
|
DB_LOG_SQL=
|
||||||
|
|
||||||
# DB_DIALECT=mysql
|
# DB_DIALECT=mysql
|
||||||
# DB_PORT=3306
|
# DB_PORT=3306
|
||||||
|
|
||||||
|
@ -2,9 +2,9 @@ import { resolve } from 'path';
|
|||||||
|
|
||||||
import glob from 'glob';
|
import glob from 'glob';
|
||||||
import Koa from 'koa';
|
import Koa from 'koa';
|
||||||
import { Options, Dialect } from 'sequelize';
|
import { Dialect } from 'sequelize';
|
||||||
import bodyParser from 'koa-bodyparser';
|
import bodyParser from 'koa-bodyparser';
|
||||||
import supertest, { SuperAgentTest } from 'supertest';
|
import supertest from 'supertest';
|
||||||
|
|
||||||
import Database, { requireModule } from '@nocobase/database';
|
import Database, { requireModule } from '@nocobase/database';
|
||||||
import Resourcer from '@nocobase/resourcer';
|
import Resourcer from '@nocobase/resourcer';
|
||||||
|
@ -3,11 +3,21 @@ import {
|
|||||||
HasMany, HasOne, Integer, BelongsTo, BelongsToMany
|
HasMany, HasOne, Integer, BelongsTo, BelongsToMany
|
||||||
} from '../fields';
|
} from '../fields';
|
||||||
import { DataTypes } from 'sequelize';
|
import { DataTypes } from 'sequelize';
|
||||||
|
import Database from '..';
|
||||||
|
|
||||||
|
let db: Database;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
db = getDatabase();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
db.close();
|
||||||
|
});
|
||||||
|
|
||||||
describe('associations', () => {
|
describe('associations', () => {
|
||||||
describe('hasOne', () => {
|
describe('hasOne', () => {
|
||||||
it('shound be defaults', async () => {
|
it('should be defaults', async () => {
|
||||||
const db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'foos',
|
name: 'foos',
|
||||||
});
|
});
|
||||||
@ -25,8 +35,7 @@ describe('associations', () => {
|
|||||||
expect(field.options.foreignKey).toBe('bar_id');
|
expect(field.options.foreignKey).toBe('bar_id');
|
||||||
expect(field.options.sourceKey).toBe('id');
|
expect(field.options.sourceKey).toBe('id');
|
||||||
});
|
});
|
||||||
it('shound be ok when the association table is defined later', async () => {
|
it('should be ok when the association table is defined later', async () => {
|
||||||
const db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'bars',
|
name: 'bars',
|
||||||
fields: [
|
fields: [
|
||||||
@ -44,8 +53,7 @@ describe('associations', () => {
|
|||||||
expect(field.options.foreignKey).toBe('bar_id');
|
expect(field.options.foreignKey).toBe('bar_id');
|
||||||
expect(field.options.sourceKey).toBe('id');
|
expect(field.options.sourceKey).toBe('id');
|
||||||
});
|
});
|
||||||
it('shound be custom when target is defined', () => {
|
it('should be custom when target is defined', () => {
|
||||||
const db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'foos',
|
name: 'foos',
|
||||||
});
|
});
|
||||||
@ -65,8 +73,7 @@ describe('associations', () => {
|
|||||||
expect(field.options.sourceKey).toBe('id');
|
expect(field.options.sourceKey).toBe('id');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shound be custom when sourceKey is defined', () => {
|
it('should be custom when sourceKey is defined', () => {
|
||||||
const db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'foos',
|
name: 'foos',
|
||||||
});
|
});
|
||||||
@ -86,8 +93,7 @@ describe('associations', () => {
|
|||||||
expect(field.options.sourceKey).toBe('sid');
|
expect(field.options.sourceKey).toBe('sid');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shound be integer type when the column of sourceKey does not exist', () => {
|
it('should be integer type when the column of sourceKey does not exist', () => {
|
||||||
const db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'foos',
|
name: 'foos',
|
||||||
});
|
});
|
||||||
@ -112,8 +118,7 @@ describe('associations', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('hasMany', () => {
|
describe('hasMany', () => {
|
||||||
it('shound be defaults', async () => {
|
it('should be defaults', async () => {
|
||||||
const db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
});
|
});
|
||||||
@ -131,8 +136,7 @@ describe('associations', () => {
|
|||||||
expect(field.options.foreignKey).toBe('bar_id');
|
expect(field.options.foreignKey).toBe('bar_id');
|
||||||
expect(field.options.sourceKey).toBe('id');
|
expect(field.options.sourceKey).toBe('id');
|
||||||
});
|
});
|
||||||
it('shound be ok when the association table is defined later', async () => {
|
it('should be ok when the association table is defined later', async () => {
|
||||||
const db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'bars',
|
name: 'bars',
|
||||||
fields: [
|
fields: [
|
||||||
@ -150,8 +154,7 @@ describe('associations', () => {
|
|||||||
expect(field.options.foreignKey).toBe('bar_id');
|
expect(field.options.foreignKey).toBe('bar_id');
|
||||||
expect(field.options.sourceKey).toBe('id');
|
expect(field.options.sourceKey).toBe('id');
|
||||||
});
|
});
|
||||||
it('shound be custom when target is defined', () => {
|
it('should be custom when target is defined', () => {
|
||||||
const db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'foos',
|
name: 'foos',
|
||||||
});
|
});
|
||||||
@ -171,8 +174,7 @@ describe('associations', () => {
|
|||||||
expect(field.options.sourceKey).toBe('id');
|
expect(field.options.sourceKey).toBe('id');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shound be custom when sourceKey is defined', () => {
|
it('should be custom when sourceKey is defined', () => {
|
||||||
const db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'foos',
|
name: 'foos',
|
||||||
});
|
});
|
||||||
@ -192,8 +194,7 @@ describe('associations', () => {
|
|||||||
expect(field.options.sourceKey).toBe('sid');
|
expect(field.options.sourceKey).toBe('sid');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shound be integer type when the column of sourceKey does not exist', () => {
|
it('should be integer type when the column of sourceKey does not exist', () => {
|
||||||
const db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'foos',
|
name: 'foos',
|
||||||
});
|
});
|
||||||
@ -218,8 +219,7 @@ describe('associations', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('belongsTo', () => {
|
describe('belongsTo', () => {
|
||||||
it('shound be custom foreignKey', async () => {
|
it('should be custom foreignKey', async () => {
|
||||||
const db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'bars',
|
name: 'bars',
|
||||||
fields: [
|
fields: [
|
||||||
@ -236,8 +236,7 @@ describe('associations', () => {
|
|||||||
expect(field.options.targetKey).toBe('id');
|
expect(field.options.targetKey).toBe('id');
|
||||||
expect(field.options.foreignKey).toBe('foo_id');
|
expect(field.options.foreignKey).toBe('foo_id');
|
||||||
});
|
});
|
||||||
it('shound be custom foreignKey', async () => {
|
it('should be custom foreignKey', async () => {
|
||||||
const db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'bars',
|
name: 'bars',
|
||||||
fields: [
|
fields: [
|
||||||
@ -255,8 +254,7 @@ describe('associations', () => {
|
|||||||
expect(field.options.targetKey).toBe('id');
|
expect(field.options.targetKey).toBe('id');
|
||||||
expect(field.options.foreignKey).toBe('custom_foo_id');
|
expect(field.options.foreignKey).toBe('custom_foo_id');
|
||||||
});
|
});
|
||||||
it('shound be custom primaryKey', () => {
|
it('should be custom primaryKey', () => {
|
||||||
const db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'foos',
|
name: 'foos',
|
||||||
fields: [
|
fields: [
|
||||||
@ -282,8 +280,7 @@ describe('associations', () => {
|
|||||||
expect(field.options.targetKey).toBe('fid');
|
expect(field.options.targetKey).toBe('fid');
|
||||||
expect(field.options.foreignKey).toBe('foo_fid');
|
expect(field.options.foreignKey).toBe('foo_fid');
|
||||||
});
|
});
|
||||||
it('shound be custom primaryKey', () => {
|
it('should be custom primaryKey', () => {
|
||||||
const db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'bars',
|
name: 'bars',
|
||||||
fields: [
|
fields: [
|
||||||
@ -309,8 +306,7 @@ describe('associations', () => {
|
|||||||
expect(field.options.targetKey).toBe('fid');
|
expect(field.options.targetKey).toBe('fid');
|
||||||
expect(field.options.foreignKey).toBe('foo_fid');
|
expect(field.options.foreignKey).toBe('foo_fid');
|
||||||
});
|
});
|
||||||
it('shound throw error', () => {
|
it('should throw error', () => {
|
||||||
const db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'foos',
|
name: 'foos',
|
||||||
});
|
});
|
||||||
@ -327,8 +323,7 @@ describe('associations', () => {
|
|||||||
});
|
});
|
||||||
}).toThrow('Unknown attribute "fid" passed as targetKey, define this attribute on model "foos" first')
|
}).toThrow('Unknown attribute "fid" passed as targetKey, define this attribute on model "foos" first')
|
||||||
});
|
});
|
||||||
it('shound be ok when the association table is defined later', async () => {
|
it('should be ok when the association table is defined later', async () => {
|
||||||
const db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'bars',
|
name: 'bars',
|
||||||
fields: [
|
fields: [
|
||||||
@ -353,8 +348,7 @@ describe('associations', () => {
|
|||||||
expect(field.options.foreignKey).toBe('foo_fid');
|
expect(field.options.foreignKey).toBe('foo_fid');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shound work', async () => {
|
it('should work', async () => {
|
||||||
const db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'rows',
|
name: 'rows',
|
||||||
fields: [
|
fields: [
|
||||||
@ -392,10 +386,7 @@ describe('associations', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('belongsToMany', () => {
|
describe('belongsToMany', () => {
|
||||||
it('shound be defaults', async () => {
|
it('should be defaults', async () => {
|
||||||
const db = getDatabase({
|
|
||||||
logging: false,
|
|
||||||
});
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'foos',
|
name: 'foos',
|
||||||
fields: [
|
fields: [
|
||||||
@ -447,8 +438,7 @@ describe('associations', () => {
|
|||||||
expect(db.getModel('bars').associations.foos).toBeDefined();
|
expect(db.getModel('bars').associations.foos).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shound be correct when use custom primary key', async () => {
|
it('should be correct when use custom primary key', async () => {
|
||||||
const db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'foos',
|
name: 'foos',
|
||||||
fields: [
|
fields: [
|
||||||
@ -515,9 +505,6 @@ describe('associations', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('through be defined after source and target', async () => {
|
it('through be defined after source and target', async () => {
|
||||||
const db = getDatabase({
|
|
||||||
logging: false,
|
|
||||||
});
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'foos',
|
name: 'foos',
|
||||||
fields: [
|
fields: [
|
||||||
@ -555,9 +542,6 @@ describe('associations', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('through be defined after source', async () => {
|
it('through be defined after source', async () => {
|
||||||
const db = getDatabase({
|
|
||||||
logging: false,
|
|
||||||
});
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'foos',
|
name: 'foos',
|
||||||
fields: [
|
fields: [
|
||||||
@ -596,9 +580,6 @@ describe('associations', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('#', () => {
|
it('#', () => {
|
||||||
const db = getDatabase({
|
|
||||||
logging: false,
|
|
||||||
});
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'posts',
|
name: 'posts',
|
||||||
fields: [
|
fields: [
|
||||||
@ -657,8 +638,7 @@ describe('associations', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shound be defined', () => {
|
it('should be defined', () => {
|
||||||
const db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'bars',
|
name: 'bars',
|
||||||
fields: [
|
fields: [
|
||||||
|
@ -1,24 +1,15 @@
|
|||||||
import Database from '../database';
|
import Database from '../database';
|
||||||
import { Options } from 'sequelize';
|
import { Dialect } from 'sequelize';
|
||||||
|
|
||||||
export const config: {
|
|
||||||
[key: string]: Options;
|
|
||||||
} = {
|
const config = {
|
||||||
mysql: {
|
username: process.env.DB_USER,
|
||||||
username: 'test',
|
password: process.env.DB_PASSWORD,
|
||||||
password: 'test',
|
database: process.env.DB_DATABASE,
|
||||||
database: 'test',
|
host: process.env.DB_HOST,
|
||||||
host: '127.0.0.1',
|
port: Number.parseInt(process.env.DB_PORT, 10),
|
||||||
port: 43306,
|
dialect: process.env.DB_DIALECT as Dialect,
|
||||||
dialect: 'mysql',
|
|
||||||
},
|
|
||||||
postgres: {
|
|
||||||
username: 'test',
|
|
||||||
password: 'test',
|
|
||||||
database: 'test',
|
|
||||||
host: '127.0.0.1',
|
|
||||||
port: 45432,
|
|
||||||
dialect: 'postgres',
|
|
||||||
define: {
|
define: {
|
||||||
hooks: {
|
hooks: {
|
||||||
beforeCreate(model, options) {
|
beforeCreate(model, options) {
|
||||||
@ -26,12 +17,9 @@ export const config: {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// logging: false,
|
logging: false,
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function getDatabase(options: Options = {}) {
|
export function getDatabase() {
|
||||||
// console.log(process.env.DB_DIALECT);
|
return new Database(config);
|
||||||
const db = new Database({...config[process.env.DB_DIALECT||'postgres'], ...options});
|
|
||||||
return db;
|
|
||||||
};
|
};
|
||||||
|
@ -1,18 +1,23 @@
|
|||||||
import { getDatabase } from '.';
|
|
||||||
import Database from '..';
|
import Database from '..';
|
||||||
|
import { getDatabase } from '.';
|
||||||
import { Op, Sequelize } from 'sequelize';
|
import { Op, Sequelize } from 'sequelize';
|
||||||
import Model from '../model';
|
import Model, { ModelCtor } from '../model';
|
||||||
import { BelongsToMany } from '../fields';
|
import { BelongsToMany } from '../fields';
|
||||||
import { Mode } from 'fs';
|
import { Mode } from 'fs';
|
||||||
|
|
||||||
|
|
||||||
|
let db: Database;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
db = await getDatabase();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await db.close();
|
||||||
|
});
|
||||||
|
|
||||||
describe('actions', () => {
|
describe('actions', () => {
|
||||||
let db: Database;
|
beforeEach(async () => {
|
||||||
|
|
||||||
beforeAll(async () => {
|
|
||||||
db = getDatabase({
|
|
||||||
logging: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'users',
|
name: 'users',
|
||||||
tableName: 'user1234',
|
tableName: 'user1234',
|
||||||
@ -196,11 +201,6 @@ describe('actions', () => {
|
|||||||
await db.sync({
|
await db.sync({
|
||||||
force: true,
|
force: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
await db.close();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('through attributes', async () => {
|
it('through attributes', async () => {
|
||||||
@ -235,9 +235,9 @@ describe('actions', () => {
|
|||||||
it('scope', async () => {
|
it('scope', async () => {
|
||||||
const [User, Post, Comment] = db.getModels(['users', 'posts', 'comments']);
|
const [User, Post, Comment] = db.getModels(['users', 'posts', 'comments']);
|
||||||
const user1 = await User.create();
|
const user1 = await User.create();
|
||||||
const user2 =await User.create();
|
const user2 = await User.create();
|
||||||
const user3 =await User.create();
|
const user3 = await User.create();
|
||||||
const user4 =await User.create();
|
const user4 = await User.create();
|
||||||
const post = await Post.create();
|
const post = await Post.create();
|
||||||
const comment = await Comment.create();
|
const comment = await Comment.create();
|
||||||
comment.updateAssociations({
|
comment.updateAssociations({
|
||||||
@ -265,16 +265,144 @@ describe('actions', () => {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
const comments = await post.getCurrent_user_comments();
|
const comments = await post.getCurrent_user_comments();
|
||||||
// console.log(comments);
|
// TODO: no expect
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('parseApiJson', () => {
|
||||||
|
let db: Database;
|
||||||
|
let Foo: ModelCtor<Model>;
|
||||||
|
beforeEach(() => {
|
||||||
|
db = getDatabase();
|
||||||
|
db.table({
|
||||||
|
name: 'bazs',
|
||||||
|
tableName: 'bazs_model'
|
||||||
|
});
|
||||||
|
db.table({
|
||||||
|
name: 'bays',
|
||||||
|
tableName: 'bays_model'
|
||||||
|
});
|
||||||
|
db.table({
|
||||||
|
name: 'bars',
|
||||||
|
tableName: 'bars_model',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: 'belongsTo',
|
||||||
|
name: 'baz',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'belongsTo',
|
||||||
|
name: 'bay',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
db.table({
|
||||||
|
name: 'foos',
|
||||||
|
tableName: 'foos_model',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: 'hasMany',
|
||||||
|
name: 'bars',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'hasMany',
|
||||||
|
name: 'fozs',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'hasMany',
|
||||||
|
name: 'coos',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
db.table({
|
||||||
|
name: 'fozs',
|
||||||
|
tableName: 'fozs_model',
|
||||||
|
});
|
||||||
|
db.table({
|
||||||
|
name: 'coos',
|
||||||
|
tableName: 'coos_model',
|
||||||
|
});
|
||||||
|
Foo = db.getModel('foos');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => db.close());
|
||||||
|
|
||||||
|
it('parseApiJson', () => {
|
||||||
|
const data = Foo.parseApiJson({
|
||||||
|
filter: {
|
||||||
|
col1: 'co2',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
expect(data).toEqual({ where: { col1: 'co2' } });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('parseApiJson', () => {
|
||||||
|
const data = Foo.parseApiJson({
|
||||||
|
fields: ['col1'],
|
||||||
|
});
|
||||||
|
expect(data).toEqual({ attributes: ['col1'] });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('parseApiJson', () => {
|
||||||
|
const data = Foo.parseApiJson({
|
||||||
|
fields: ['col1'],
|
||||||
|
filter: {
|
||||||
|
col1: 'co2',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(data).toEqual({ attributes: ['col1'], where: { col1: 'co2' } });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('parseApiJson', () => {
|
||||||
|
const data = Foo.parseApiJson({
|
||||||
|
fields: ['col1'],
|
||||||
|
filter: {
|
||||||
|
col1: 'val1',
|
||||||
|
bars: {
|
||||||
|
col1: 'val1',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(data).toEqual({
|
||||||
|
attributes: ['col1'],
|
||||||
|
where: { col1: 'val1' },
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
association: 'bars',
|
||||||
|
where: { col1: 'val1' },
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('parseApiJson', () => {
|
||||||
|
const data = Foo.parseApiJson({
|
||||||
|
fields: ['col1', 'bars.col1'],
|
||||||
|
filter: {
|
||||||
|
col1: 'val1',
|
||||||
|
bars: {
|
||||||
|
col1: 'val1',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(data).toEqual({
|
||||||
|
attributes: ['col1'],
|
||||||
|
where: { col1: 'val1' },
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
association: 'bars',
|
||||||
|
attributes: ['col1'],
|
||||||
|
where: { col1: 'val1' },
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('findByApiJson', () => {
|
describe('findByApiJson', () => {
|
||||||
it('q', async () => {
|
it('q', async () => {
|
||||||
|
|
||||||
db.getModel('tags').addScope('scopeName', (name, ctx) => {
|
db.getModel('tags').addScope('scopeName', (name, ctx) => {
|
||||||
expect(ctx.scopeName).toBe(name);
|
expect(ctx.scopeName).toBe(name);
|
||||||
console.log(ctx);
|
|
||||||
return {
|
return {
|
||||||
where: {
|
where: {
|
||||||
name: name,
|
name: name,
|
||||||
@ -330,7 +458,11 @@ describe('actions', () => {
|
|||||||
scopeName: 'tag3',
|
scopeName: 'tag3',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
console.log(options);
|
||||||
|
|
||||||
|
try{
|
||||||
|
// DatabaseError [SequelizeDatabaseError]: column tags.scopeName does not exist
|
||||||
|
// SELECT count("posts"."id") AS "count" FROM "post123456" AS "posts" INNER JOIN ( "posts_tags1234" AS "tags->posts_tags" INNER JOIN "tag1234" AS "tags" ON "tags"."id" = "tags->posts_tags"."tag_id") ON "posts"."id" = "tags->posts_tags"."post_id" AND "tags"."scopeName" = 'tag3' INNER JOIN "user1234" AS "user" ON "posts"."user_id" = "user"."id" AND "user"."name" = 'name112233' WHERE "posts"."title" = 'title112233';
|
||||||
const { rows, count } = await Post.findAndCountAll({
|
const { rows, count } = await Post.findAndCountAll({
|
||||||
...options,
|
...options,
|
||||||
// group: ['id'],
|
// group: ['id'],
|
||||||
@ -340,11 +472,14 @@ describe('actions', () => {
|
|||||||
|
|
||||||
// console.log(JSON.stringify(rows[0].toJSON(), null, 2));
|
// console.log(JSON.stringify(rows[0].toJSON(), null, 2));
|
||||||
|
|
||||||
rows.forEach(post => {
|
rows.forEach(row => {
|
||||||
// expect(post.toJSON()).toEqual({ title: 'title112233', 'tags_count': 3, user: { name: 'name112233', posts_count: 1 } });
|
// expect(row.toJSON()).toEqual({ title: 'title112233', 'tags_count': 3, user: { name: 'name112233', posts_count: 1 } });
|
||||||
expect(post.get('title')).toBe('title112233');
|
expect(row.get('title')).toBe('title112233');
|
||||||
expect(post.user.get('name')).toBe('name112233');
|
expect(row.user.get('name')).toBe('name112233');
|
||||||
});
|
});
|
||||||
|
} catch(error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
// console.log(count);
|
// console.log(count);
|
||||||
|
|
||||||
@ -878,15 +1013,11 @@ describe('actions', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('belongsToMany', () => {
|
describe('belongsToMany', () => {
|
||||||
let db: Database;
|
|
||||||
let post: Model;
|
let post: Model;
|
||||||
let tag1: Model;
|
let tag1: Model;
|
||||||
let tag2: Model;
|
let tag2: Model;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeEach(async () => {
|
||||||
db = getDatabase({
|
|
||||||
logging: false,
|
|
||||||
});
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'posts',
|
name: 'posts',
|
||||||
tableName: 't333333_posts',
|
tableName: 't333333_posts',
|
||||||
@ -928,10 +1059,6 @@ describe('belongsToMany', () => {
|
|||||||
tag2 = await Tag.create({name: 'tag2'});
|
tag2 = await Tag.create({name: 'tag2'});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
await db.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('@', async () => {
|
it('@', async () => {
|
||||||
await post.updateAssociations({
|
await post.updateAssociations({
|
||||||
tags: tag1.name,
|
tags: tag1.name,
|
||||||
|
@ -1,21 +1,27 @@
|
|||||||
|
import Database from '..';
|
||||||
import { getDatabase } from './';
|
import { getDatabase } from './';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
let db: Database;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
db = await getDatabase();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await db.close();
|
||||||
|
});
|
||||||
|
|
||||||
describe('db sync', () => {
|
describe('db sync', () => {
|
||||||
describe('table.sync', () => {
|
describe('table.sync', () => {
|
||||||
it('shound be ok1', async () => {
|
it('shound be ok1', async () => {
|
||||||
const db = getDatabase({
|
|
||||||
logging: false,
|
|
||||||
});
|
|
||||||
const table = db.table({
|
const table = db.table({
|
||||||
name: 'foos',
|
name: 'foos',
|
||||||
});
|
});
|
||||||
await table.sync();
|
await table.sync();
|
||||||
await db.close();
|
|
||||||
});
|
});
|
||||||
it('sync#belongsTo', async () => {
|
it('sync#belongsTo', async () => {
|
||||||
const db = getDatabase({
|
|
||||||
logging: false,
|
|
||||||
});
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'foos',
|
name: 'foos',
|
||||||
tableName: 'foos1',
|
tableName: 'foos1',
|
||||||
@ -43,12 +49,8 @@ describe('db sync', () => {
|
|||||||
drop: false,
|
drop: false,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await db.close();
|
|
||||||
});
|
});
|
||||||
it('sync#hasMany', async () => {
|
it('sync#hasMany', async () => {
|
||||||
const db = getDatabase({
|
|
||||||
logging: false,
|
|
||||||
});
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'foos',
|
name: 'foos',
|
||||||
tableName: 'foos2',
|
tableName: 'foos2',
|
||||||
@ -76,12 +78,8 @@ describe('db sync', () => {
|
|||||||
drop: false,
|
drop: false,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await db.close();
|
|
||||||
});
|
});
|
||||||
it('sync#belongsToMany', async () => {
|
it('sync#belongsToMany', async () => {
|
||||||
const db = getDatabase({
|
|
||||||
logging: false,
|
|
||||||
});
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'foos',
|
name: 'foos',
|
||||||
fields: [
|
fields: [
|
||||||
@ -134,12 +132,8 @@ describe('db sync', () => {
|
|||||||
col1: 'val1'
|
col1: 'val1'
|
||||||
});
|
});
|
||||||
expect(await db.getModel('bars').count()).toBe(2);
|
expect(await db.getModel('bars').count()).toBe(2);
|
||||||
await db.close();
|
|
||||||
});
|
});
|
||||||
it('shound be ok2', async () => {
|
it('shound be ok2', async () => {
|
||||||
const db = getDatabase({
|
|
||||||
logging: false,
|
|
||||||
});
|
|
||||||
const table = db.table({
|
const table = db.table({
|
||||||
name: 'goos',
|
name: 'goos',
|
||||||
});
|
});
|
||||||
@ -166,7 +160,6 @@ describe('db sync', () => {
|
|||||||
drop: false,
|
drop: false,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await db.close();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -3,20 +3,19 @@ import Database from '../database';
|
|||||||
import Table from '../table';
|
import Table from '../table';
|
||||||
import Model from '../model';
|
import Model from '../model';
|
||||||
|
|
||||||
|
let db: Database;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
db = await getDatabase();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await db.close();
|
||||||
|
});
|
||||||
|
|
||||||
describe('tables', () => {
|
describe('tables', () => {
|
||||||
let db: Database;
|
|
||||||
|
|
||||||
// beforeAll(() => {
|
|
||||||
// db = getDatabase();
|
|
||||||
// });
|
|
||||||
|
|
||||||
// afterAll(async () => {
|
|
||||||
// await db.sequelize.close();
|
|
||||||
// });
|
|
||||||
|
|
||||||
describe('options', () => {
|
describe('options', () => {
|
||||||
it('shoud be defined', () => {
|
it('should be defined', () => {
|
||||||
db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
});
|
});
|
||||||
@ -34,7 +33,6 @@ describe('tables', () => {
|
|||||||
return 'test12345';
|
return 'test12345';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
db = getDatabase();
|
|
||||||
const table = db.table({
|
const table = db.table({
|
||||||
name: 'abc',
|
name: 'abc',
|
||||||
model: Abc,
|
model: Abc,
|
||||||
@ -44,8 +42,7 @@ describe('tables', () => {
|
|||||||
expect(Abc.getModel('abc').test12345()).toBe('test12345');
|
expect(Abc.getModel('abc').test12345()).toBe('test12345');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shoud tableName === name', async () => {
|
it('should tableName === name', async () => {
|
||||||
db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'foos',
|
name: 'foos',
|
||||||
});
|
});
|
||||||
@ -53,8 +50,7 @@ describe('tables', () => {
|
|||||||
expect(db.getModel('foos').getTableName()).toBe('foos');
|
expect(db.getModel('foos').getTableName()).toBe('foos');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shoud be custom when tableName is defined', async () => {
|
it('should be custom when tableName is defined', async () => {
|
||||||
db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'bar',
|
name: 'bar',
|
||||||
tableName: 'bar_v2'
|
tableName: 'bar_v2'
|
||||||
@ -63,8 +59,7 @@ describe('tables', () => {
|
|||||||
expect(db.getModel('bar').getTableName()).toBe('bar_v2');
|
expect(db.getModel('bar').getTableName()).toBe('bar_v2');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shoud be custom when timestamps is defined', async () => {
|
it('should be custom when timestamps is defined', async () => {
|
||||||
db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'baz',
|
name: 'baz',
|
||||||
createdAt: 'created',
|
createdAt: 'created',
|
||||||
@ -74,8 +69,7 @@ describe('tables', () => {
|
|||||||
expect(db.getModel('baz').rawAttributes.updated).toBeDefined();
|
expect(db.getModel('baz').rawAttributes.updated).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('index shound be defined', async () => {
|
it('index should be defined', async () => {
|
||||||
db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'baz',
|
name: 'baz',
|
||||||
fields: [
|
fields: [
|
||||||
@ -104,8 +98,7 @@ describe('tables', () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('index shound be defined', async () => {
|
it('index should be defined', async () => {
|
||||||
db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'baz2',
|
name: 'baz2',
|
||||||
indexes: [
|
indexes: [
|
||||||
@ -140,8 +133,7 @@ describe('tables', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('#extend()', () => {
|
describe('#extend()', () => {
|
||||||
it('shoud be extend', async () => {
|
it('should be extend', async () => {
|
||||||
db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'baz',
|
name: 'baz',
|
||||||
});
|
});
|
||||||
@ -155,8 +147,7 @@ describe('tables', () => {
|
|||||||
expect(db.getModel('baz').rawAttributes.created).toBeDefined();
|
expect(db.getModel('baz').rawAttributes.created).toBeDefined();
|
||||||
expect(db.getModel('baz').rawAttributes.updated).toBeDefined();
|
expect(db.getModel('baz').rawAttributes.updated).toBeDefined();
|
||||||
});
|
});
|
||||||
it('shoud be extend', async () => {
|
it('should be extend', async () => {
|
||||||
db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'foos',
|
name: 'foos',
|
||||||
});
|
});
|
||||||
@ -196,10 +187,9 @@ describe('tables', () => {
|
|||||||
|
|
||||||
describe('associations', () => {
|
describe('associations', () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
db = getDatabase();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shound be undefined when target table does not exist', () => {
|
it('should be undefined when target table does not exist', () => {
|
||||||
db.table({
|
db.table({
|
||||||
name: 'bars',
|
name: 'bars',
|
||||||
fields: [
|
fields: [
|
||||||
@ -212,14 +202,22 @@ describe('tables', () => {
|
|||||||
expect(db.getModel('bars').associations.foo).toBeUndefined();
|
expect(db.getModel('bars').associations.foo).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shound be defined when target table exists', () => {
|
it('should be defined when target table exists', () => {
|
||||||
|
db.table({
|
||||||
|
name: 'bars',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: 'hasOne',
|
||||||
|
name: 'foo',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
db.table({name: 'foos'});
|
db.table({name: 'foos'});
|
||||||
expect(db.getModel('bars').associations.foo).toBeDefined();
|
expect(db.getModel('bars').associations.foo).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#setFields()', () => {
|
describe('#setFields()', () => {
|
||||||
beforeAll(() => {
|
beforeEach(() => {
|
||||||
db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'table1',
|
name: 'table1',
|
||||||
fields: [
|
fields: [
|
||||||
@ -239,13 +237,13 @@ describe('tables', () => {
|
|||||||
name: 'table2',
|
name: 'table2',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('shound be defined', () => {
|
it('should be defined', () => {
|
||||||
const table1 = db.getModel('table1');
|
const table1 = db.getModel('table1');
|
||||||
expect(Object.keys(table1.associations).length).toBe(2);
|
expect(Object.keys(table1.associations).length).toBe(2);
|
||||||
expect(table1.associations.table21).toBeDefined();
|
expect(table1.associations.table21).toBeDefined();
|
||||||
expect(table1.associations.table22).toBeDefined();
|
expect(table1.associations.table22).toBeDefined();
|
||||||
});
|
});
|
||||||
it('shound be defined', () => {
|
it('should be defined', () => {
|
||||||
db.getTable('table1').setFields([
|
db.getTable('table1').setFields([
|
||||||
{
|
{
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@ -267,8 +265,7 @@ describe('tables', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('#addField()', () => {
|
describe('#addField()', () => {
|
||||||
beforeAll(() => {
|
beforeEach(() => {
|
||||||
db = getDatabase();
|
|
||||||
db.table({
|
db.table({
|
||||||
name: 'table1',
|
name: 'table1',
|
||||||
});
|
});
|
||||||
@ -276,7 +273,7 @@ describe('tables', () => {
|
|||||||
name: 'table2',
|
name: 'table2',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('shound be defined when the field be added after initialization', () => {
|
it('should be defined when the field be added after initialization', () => {
|
||||||
db.getTable('table1').addField({
|
db.getTable('table1').addField({
|
||||||
type: 'hasOne',
|
type: 'hasOne',
|
||||||
name: 'table2',
|
name: 'table2',
|
||||||
@ -285,7 +282,12 @@ describe('tables', () => {
|
|||||||
expect(Object.keys(db.getModel('table1').associations).length).toBe(1);
|
expect(Object.keys(db.getModel('table1').associations).length).toBe(1);
|
||||||
expect(db.getModel('table1').associations.table2).toBeDefined();
|
expect(db.getModel('table1').associations.table2).toBeDefined();
|
||||||
});
|
});
|
||||||
it('shound be defined when continue to add', () => {
|
it('should be defined when continue to add', () => {
|
||||||
|
db.getTable('table1').addField({
|
||||||
|
type: 'hasOne',
|
||||||
|
name: 'table2',
|
||||||
|
target: 'table2',
|
||||||
|
});
|
||||||
db.getTable('table1').addField({
|
db.getTable('table1').addField({
|
||||||
type: 'hasOne',
|
type: 'hasOne',
|
||||||
name: 'table21',
|
name: 'table21',
|
||||||
|
@ -28,7 +28,7 @@ import Database from '..';
|
|||||||
|
|
||||||
describe('field types', () => {
|
describe('field types', () => {
|
||||||
const assertTypeInstanceOf = (expected, actual) => {
|
const assertTypeInstanceOf = (expected, actual) => {
|
||||||
const db = getDatabase();
|
const db: Database = getDatabase();
|
||||||
const table = db.table({
|
const table = db.table({
|
||||||
name: 'test',
|
name: 'test',
|
||||||
});
|
});
|
||||||
@ -56,6 +56,7 @@ describe('field types', () => {
|
|||||||
expect(type).toBe(field.getDataType());
|
expect(type).toBe(field.getDataType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
it('shound be boolean', () => {
|
it('shound be boolean', () => {
|
||||||
@ -212,7 +213,7 @@ describe('field types', () => {
|
|||||||
|
|
||||||
describe('virtual', () => {
|
describe('virtual', () => {
|
||||||
let db: Database;
|
let db: Database;
|
||||||
beforeAll(async () => {
|
beforeEach(async () => {
|
||||||
db = getDatabase();
|
db = getDatabase();
|
||||||
db.table({
|
db.table({
|
||||||
name: 'formula_tests',
|
name: 'formula_tests',
|
||||||
@ -283,7 +284,7 @@ describe('field types', () => {
|
|||||||
})
|
})
|
||||||
await db.sync({force: true});
|
await db.sync({force: true});
|
||||||
});
|
});
|
||||||
afterAll(async () => {
|
afterEach(async () => {
|
||||||
await db.close();
|
await db.close();
|
||||||
});
|
});
|
||||||
it('pwd', async () => {
|
it('pwd', async () => {
|
||||||
|
@ -1,658 +0,0 @@
|
|||||||
import { requireModule, toWhere, toInclude } from '../utils';
|
|
||||||
import path from 'path';
|
|
||||||
import { Op } from 'sequelize';
|
|
||||||
import { getDatabase } from '.';
|
|
||||||
import Database from '../database';
|
|
||||||
import Model, { ModelCtor } from '../model';
|
|
||||||
|
|
||||||
describe('utils', () => {
|
|
||||||
describe('toWhere', () => {
|
|
||||||
it('Op.eq', () => {
|
|
||||||
const where = toWhere({
|
|
||||||
id: {
|
|
||||||
eq: 12
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(where).toEqual({
|
|
||||||
id: {
|
|
||||||
[Op.eq]: 12,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Op.ilike', () => {
|
|
||||||
const where = toWhere({
|
|
||||||
id: {
|
|
||||||
ilike: 'val1'
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(where).toEqual({
|
|
||||||
id: {
|
|
||||||
[Op.iLike]: 'val1',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Op.ilike', () => {
|
|
||||||
const where = toWhere({
|
|
||||||
'id.ilike': 'val1',
|
|
||||||
});
|
|
||||||
expect(where).toEqual({
|
|
||||||
id: {
|
|
||||||
[Op.iLike]: 'val1',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Op.is null', () => {
|
|
||||||
const where = toWhere({
|
|
||||||
'id.is': null,
|
|
||||||
});
|
|
||||||
expect(where).toEqual({
|
|
||||||
id: {
|
|
||||||
[Op.is]: null,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Op.in', () => {
|
|
||||||
const where = toWhere({
|
|
||||||
id: {
|
|
||||||
in: [12]
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(where).toEqual({
|
|
||||||
id: {
|
|
||||||
[Op.in]: [12],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Op.in', () => {
|
|
||||||
const where = toWhere({
|
|
||||||
'id.in': [11, 12],
|
|
||||||
});
|
|
||||||
expect(where).toEqual({
|
|
||||||
id: {
|
|
||||||
[Op.in]: [11, 12],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('association', () => {
|
|
||||||
let db: Database;
|
|
||||||
let Foo: ModelCtor<Model>;
|
|
||||||
beforeAll(() => {
|
|
||||||
db = getDatabase();
|
|
||||||
db.table({
|
|
||||||
name: 'bazs',
|
|
||||||
});
|
|
||||||
db.table({
|
|
||||||
name: 'bars',
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
type: 'belongsTo',
|
|
||||||
name: 'baz',
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
db.table({
|
|
||||||
name: 'foos',
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
type: 'hasMany',
|
|
||||||
name: 'bars',
|
|
||||||
}
|
|
||||||
],
|
|
||||||
});
|
|
||||||
Foo = db.getModel('foos');
|
|
||||||
});
|
|
||||||
|
|
||||||
const toWhereExpect = (options, logging = false) => {
|
|
||||||
const where = toWhere(options, {
|
|
||||||
associations: Foo.associations,
|
|
||||||
});
|
|
||||||
return expect(where);
|
|
||||||
}
|
|
||||||
|
|
||||||
it('association', () => {
|
|
||||||
toWhereExpect({
|
|
||||||
col1: 'val1',
|
|
||||||
bars: {
|
|
||||||
name: {
|
|
||||||
ilike: 'aa',
|
|
||||||
},
|
|
||||||
col2: {
|
|
||||||
lt: 2,
|
|
||||||
},
|
|
||||||
baz: {
|
|
||||||
col1: 12,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'bars.col3.ilike': 'aa',
|
|
||||||
}).toEqual({
|
|
||||||
col1: 'val1',
|
|
||||||
$__include: {
|
|
||||||
bars: {
|
|
||||||
name: {
|
|
||||||
[Op.iLike]: 'aa',
|
|
||||||
},
|
|
||||||
col2: {
|
|
||||||
[Op.lt]: 2,
|
|
||||||
},
|
|
||||||
col3: {
|
|
||||||
[Op.iLike]: 'aa',
|
|
||||||
},
|
|
||||||
$__include: {
|
|
||||||
baz: {
|
|
||||||
col1: 12
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('toInclude', () => {
|
|
||||||
let db: Database;
|
|
||||||
let Foo: ModelCtor<Model>;
|
|
||||||
beforeAll(() => {
|
|
||||||
db = getDatabase();
|
|
||||||
db.table({
|
|
||||||
name: 'bazs',
|
|
||||||
});
|
|
||||||
db.table({
|
|
||||||
name: 'bays',
|
|
||||||
});
|
|
||||||
db.table({
|
|
||||||
name: 'bars',
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
type: 'belongsTo',
|
|
||||||
name: 'baz',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'belongsTo',
|
|
||||||
name: 'bay',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
db.table({
|
|
||||||
name: 'foos',
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
type: 'hasMany',
|
|
||||||
name: 'bars',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'hasMany',
|
|
||||||
name: 'fozs',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'hasMany',
|
|
||||||
name: 'coos',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
db.table({
|
|
||||||
name: 'fozs',
|
|
||||||
});
|
|
||||||
db.table({
|
|
||||||
name: 'coos',
|
|
||||||
});
|
|
||||||
Foo = db.getModel('foos');
|
|
||||||
});
|
|
||||||
|
|
||||||
const toIncludeExpect = (options: any, logging = false) => {
|
|
||||||
const include = toInclude(options, {
|
|
||||||
Model: Foo,
|
|
||||||
associations: Foo.associations,
|
|
||||||
});
|
|
||||||
if (logging) {
|
|
||||||
console.log(JSON.stringify(include, null, 2));
|
|
||||||
}
|
|
||||||
return expect(include);
|
|
||||||
};
|
|
||||||
|
|
||||||
it('normal columns', () => {
|
|
||||||
toIncludeExpect({
|
|
||||||
fields: ['col1', 'col2'],
|
|
||||||
}).toEqual({ attributes: [ 'col1', 'col2' ] });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('association count attribute', () => {
|
|
||||||
toIncludeExpect({
|
|
||||||
fields: ['col1', 'bars_count'],
|
|
||||||
}).toEqual({ attributes: [ 'col1', Foo.withCountAttribute('bars') ] });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('association without attributes', () => {
|
|
||||||
toIncludeExpect({
|
|
||||||
fields: ['col1', 'bars'],
|
|
||||||
}).toEqual({
|
|
||||||
attributes: [ 'col1' ],
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
association: 'bars',
|
|
||||||
}
|
|
||||||
],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('association attributes', () => {
|
|
||||||
toIncludeExpect({
|
|
||||||
fields: ['col1', 'bars.col1', 'bars.col2'],
|
|
||||||
}).toEqual({
|
|
||||||
attributes: [ 'col1' ],
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
association: 'bars',
|
|
||||||
attributes: [ 'col1', 'col2' ],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('association attributes', () => {
|
|
||||||
toIncludeExpect({
|
|
||||||
fields: ['col1', ['bars', 'col1'], ['bars', 'col2']],
|
|
||||||
}).toEqual({
|
|
||||||
attributes: [ 'col1' ],
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
association: 'bars',
|
|
||||||
attributes: [ 'col1', 'col2' ],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('nested association', () => {
|
|
||||||
toIncludeExpect({
|
|
||||||
fields: ['col1', 'bars.baz'],
|
|
||||||
}).toEqual({
|
|
||||||
attributes: [ 'col1' ],
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
association: 'bars',
|
|
||||||
attributes: [],
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
association: 'baz',
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it.skip('nested association', () => {
|
|
||||||
// TODO,输出 bars 的所有字段
|
|
||||||
toIncludeExpect({
|
|
||||||
fields: ['col1', 'bars', 'bars.baz'],
|
|
||||||
}, true).toEqual({
|
|
||||||
attributes: [ 'col1' ],
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
association: 'bars',
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
association: 'baz',
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('nested association', () => {
|
|
||||||
toIncludeExpect({
|
|
||||||
fields: ['col1', 'bars.col1', 'bars.col2', 'bars.baz'],
|
|
||||||
}).toEqual({
|
|
||||||
attributes: [ 'col1' ],
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
association: 'bars',
|
|
||||||
attributes: ['col1', 'col2'],
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
association: 'baz',
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('nested association', () => {
|
|
||||||
// TODO,输出 bars 的所有字段
|
|
||||||
toIncludeExpect({
|
|
||||||
fields: ['col1', 'bars.col1', 'bars.col2', 'bars.baz.col1', 'bars.baz.col2'],
|
|
||||||
}).toEqual({
|
|
||||||
attributes: [ 'col1' ],
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
association: 'bars',
|
|
||||||
attributes: ['col1', 'col2'],
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
association: 'baz',
|
|
||||||
attributes: ['col1', 'col2'],
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('append attributes', () => {
|
|
||||||
toIncludeExpect({
|
|
||||||
fields: {
|
|
||||||
appends: ['bars_count'],
|
|
||||||
},
|
|
||||||
}).toEqual({
|
|
||||||
attributes: {
|
|
||||||
include: [Foo.withCountAttribute('bars')],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('append attributes', () => {
|
|
||||||
toIncludeExpect({
|
|
||||||
fields: {
|
|
||||||
appends: ['bars.col1', 'bars_count'],
|
|
||||||
},
|
|
||||||
}).toEqual({
|
|
||||||
attributes: {
|
|
||||||
include: [Foo.withCountAttribute('bars')],
|
|
||||||
},
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
association: 'bars',
|
|
||||||
attributes: {
|
|
||||||
include: ['col1'],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('only & append attributes', () => {
|
|
||||||
toIncludeExpect({
|
|
||||||
fields: {
|
|
||||||
only: ['col1'],
|
|
||||||
appends: ['bars_count'],
|
|
||||||
},
|
|
||||||
}).toEqual({
|
|
||||||
attributes: ['col1', Foo.withCountAttribute('bars')],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('only & append attributes', () => {
|
|
||||||
toIncludeExpect({
|
|
||||||
fields: {
|
|
||||||
only: ['col1', 'bars.col1'],
|
|
||||||
appends: ['bars_count'],
|
|
||||||
},
|
|
||||||
}).toEqual({
|
|
||||||
attributes: ['col1', Foo.withCountAttribute('bars')],
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
association: 'bars',
|
|
||||||
attributes: ['col1'],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('excpet attributes', () => {
|
|
||||||
toIncludeExpect({
|
|
||||||
fields: {
|
|
||||||
except: ['col1'],
|
|
||||||
},
|
|
||||||
}).toEqual({
|
|
||||||
attributes: {
|
|
||||||
include: [],
|
|
||||||
exclude: ['col1'],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('excpet attributes', () => {
|
|
||||||
toIncludeExpect({
|
|
||||||
fields: {
|
|
||||||
except: ['col1', 'bars.col1'],
|
|
||||||
},
|
|
||||||
}).toEqual({
|
|
||||||
attributes: {
|
|
||||||
include: [],
|
|
||||||
exclude: ['col1'],
|
|
||||||
},
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
association: 'bars',
|
|
||||||
attributes: {
|
|
||||||
include: [],
|
|
||||||
exclude: ['col1'],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('excpet & append attributes', () => {
|
|
||||||
toIncludeExpect({
|
|
||||||
fields: {
|
|
||||||
except: ['col1'],
|
|
||||||
appends: ['bars_count'],
|
|
||||||
},
|
|
||||||
}).toEqual({
|
|
||||||
attributes: {
|
|
||||||
include: [Foo.withCountAttribute('bars')],
|
|
||||||
exclude: ['col1'],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('where options', () => {
|
|
||||||
it('where', () => {
|
|
||||||
toIncludeExpect({
|
|
||||||
filter: {
|
|
||||||
col1: 'val1',
|
|
||||||
},
|
|
||||||
fields: {
|
|
||||||
except: ['col1'],
|
|
||||||
appends: ['bars_count'],
|
|
||||||
},
|
|
||||||
}).toEqual({
|
|
||||||
attributes: {
|
|
||||||
include: [Foo.withCountAttribute('bars')],
|
|
||||||
exclude: ['col1'],
|
|
||||||
},
|
|
||||||
where: {
|
|
||||||
col1: 'val1',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('where', () => {
|
|
||||||
toIncludeExpect({
|
|
||||||
filter: {
|
|
||||||
col1: 'val1',
|
|
||||||
bars: {
|
|
||||||
col1: 'val1',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fields: {
|
|
||||||
except: ['col1'],
|
|
||||||
appends: ['bars', 'bars_count'],
|
|
||||||
},
|
|
||||||
}).toEqual({
|
|
||||||
attributes: {
|
|
||||||
include: [Foo.withCountAttribute('bars')],
|
|
||||||
exclude: ['col1'],
|
|
||||||
},
|
|
||||||
where: {
|
|
||||||
col1: 'val1',
|
|
||||||
},
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
association: 'bars',
|
|
||||||
where: {
|
|
||||||
col1: 'val1',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('where', () => {
|
|
||||||
toIncludeExpect({
|
|
||||||
filter: {
|
|
||||||
col1: 'val1',
|
|
||||||
bars: {
|
|
||||||
col1: 'val1',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fields: {
|
|
||||||
except: ['col1'],
|
|
||||||
appends: ['bars_count'],
|
|
||||||
},
|
|
||||||
}).toEqual({
|
|
||||||
attributes: {
|
|
||||||
include: [Foo.withCountAttribute('bars')],
|
|
||||||
exclude: ['col1'],
|
|
||||||
},
|
|
||||||
where: {
|
|
||||||
col1: 'val1',
|
|
||||||
},
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
association: 'bars',
|
|
||||||
where: {
|
|
||||||
col1: 'val1',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('parseApiJson', () => {
|
|
||||||
const data = Foo.parseApiJson({
|
|
||||||
filter: {
|
|
||||||
col1: 'co2',
|
|
||||||
}
|
|
||||||
});
|
|
||||||
expect(data).toEqual({ where: { col1: 'co2' } });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('parseApiJson', () => {
|
|
||||||
const data = Foo.parseApiJson({
|
|
||||||
fields: ['col1'],
|
|
||||||
});
|
|
||||||
expect(data).toEqual({ attributes: ['col1'] });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('parseApiJson', () => {
|
|
||||||
const data = Foo.parseApiJson({
|
|
||||||
fields: ['col1'],
|
|
||||||
filter: {
|
|
||||||
col1: 'co2',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(data).toEqual({ attributes: ['col1'], where: { col1: 'co2' } });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('parseApiJson', () => {
|
|
||||||
const data = Foo.parseApiJson({
|
|
||||||
fields: ['col1'],
|
|
||||||
filter: {
|
|
||||||
col1: 'val1',
|
|
||||||
bars: {
|
|
||||||
col1: 'val1',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(data).toEqual({
|
|
||||||
attributes: ['col1'],
|
|
||||||
where: { col1: 'val1' },
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
association: 'bars',
|
|
||||||
where: { col1: 'val1' },
|
|
||||||
}
|
|
||||||
],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('parseApiJson', () => {
|
|
||||||
const data = Foo.parseApiJson({
|
|
||||||
fields: ['col1', 'bars.col1'],
|
|
||||||
filter: {
|
|
||||||
col1: 'val1',
|
|
||||||
bars: {
|
|
||||||
col1: 'val1',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(data).toEqual({
|
|
||||||
attributes: ['col1'],
|
|
||||||
where: { col1: 'val1' },
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
association: 'bars',
|
|
||||||
attributes: ['col1'],
|
|
||||||
where: { col1: 'val1' },
|
|
||||||
}
|
|
||||||
],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('requireModule', () => {
|
|
||||||
test('toBeTruthy', () => {
|
|
||||||
const r = requireModule(true);
|
|
||||||
expect(r).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('toBeInstanceOf Function', () => {
|
|
||||||
const r = requireModule(() => {});
|
|
||||||
expect(r).toBeInstanceOf(Function);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('toBeInstanceOf Function', () => {
|
|
||||||
const r = requireModule(path.resolve(__dirname, './modules/fn'));
|
|
||||||
expect(r).toBeInstanceOf(Function);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('toBeInstanceOf Function', () => {
|
|
||||||
const r = requireModule(path.resolve(__dirname, './modules/fnts'));
|
|
||||||
expect(r).toBeInstanceOf(Function);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('object', () => {
|
|
||||||
const r = requireModule(path.resolve(__dirname, './modules/obj'));
|
|
||||||
expect(r).toEqual({
|
|
||||||
'foo': 'bar',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test('object', () => {
|
|
||||||
const r = requireModule(path.resolve(__dirname, './modules/objts'));
|
|
||||||
expect(r).toEqual({
|
|
||||||
'foo': 'bar',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test('json', () => {
|
|
||||||
const r = requireModule(path.resolve(__dirname, './modules/json'));
|
|
||||||
expect(r).toEqual({
|
|
||||||
'foo': 'bar',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
48
packages/database/src/__tests__/utils/requireModule.test.ts
Normal file
48
packages/database/src/__tests__/utils/requireModule.test.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import path from "path";
|
||||||
|
|
||||||
|
import { requireModule } from "../../utils";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
describe('utils.requireModule', () => {
|
||||||
|
test('toBeTruthy', () => {
|
||||||
|
const r = requireModule(true);
|
||||||
|
expect(r).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('toBeInstanceOf Function', () => {
|
||||||
|
const r = requireModule(() => {});
|
||||||
|
expect(r).toBeInstanceOf(Function);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('toBeInstanceOf Function', () => {
|
||||||
|
const r = requireModule(path.resolve(__dirname, './modules/fn'));
|
||||||
|
expect(r).toBeInstanceOf(Function);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('toBeInstanceOf Function', () => {
|
||||||
|
const r = requireModule(path.resolve(__dirname, './modules/fnts'));
|
||||||
|
expect(r).toBeInstanceOf(Function);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('object', () => {
|
||||||
|
const r = requireModule(path.resolve(__dirname, './modules/obj'));
|
||||||
|
expect(r).toEqual({
|
||||||
|
'foo': 'bar',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('object', () => {
|
||||||
|
const r = requireModule(path.resolve(__dirname, './modules/objts'));
|
||||||
|
expect(r).toEqual({
|
||||||
|
'foo': 'bar',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('json', () => {
|
||||||
|
const r = requireModule(path.resolve(__dirname, './modules/json'));
|
||||||
|
expect(r).toEqual({
|
||||||
|
'foo': 'bar',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
396
packages/database/src/__tests__/utils/toInclude.test.ts
Normal file
396
packages/database/src/__tests__/utils/toInclude.test.ts
Normal file
@ -0,0 +1,396 @@
|
|||||||
|
import { getDatabase } from '..';
|
||||||
|
import Database from '../../database';
|
||||||
|
import Model, { ModelCtor } from '../../model';
|
||||||
|
import { toInclude } from '../../utils';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
describe('toInclude', () => {
|
||||||
|
let db: Database;
|
||||||
|
let Foo: ModelCtor<Model>;
|
||||||
|
beforeEach(() => {
|
||||||
|
db = getDatabase();
|
||||||
|
db.table({
|
||||||
|
name: 'bazs',
|
||||||
|
});
|
||||||
|
db.table({
|
||||||
|
name: 'bays',
|
||||||
|
});
|
||||||
|
db.table({
|
||||||
|
name: 'bars',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: 'belongsTo',
|
||||||
|
name: 'baz',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'belongsTo',
|
||||||
|
name: 'bay',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
db.table({
|
||||||
|
name: 'foos',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: 'hasMany',
|
||||||
|
name: 'bars',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'hasMany',
|
||||||
|
name: 'fozs',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'hasMany',
|
||||||
|
name: 'coos',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
db.table({
|
||||||
|
name: 'fozs',
|
||||||
|
});
|
||||||
|
db.table({
|
||||||
|
name: 'coos',
|
||||||
|
});
|
||||||
|
Foo = db.getModel('foos');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => db.close());
|
||||||
|
|
||||||
|
const toIncludeExpect = (options: any, logging = false) => {
|
||||||
|
const include = toInclude(options, {
|
||||||
|
Model: Foo,
|
||||||
|
associations: Foo.associations,
|
||||||
|
});
|
||||||
|
if (logging) {
|
||||||
|
console.log(JSON.stringify(include, null, 2));
|
||||||
|
}
|
||||||
|
return expect(include);
|
||||||
|
};
|
||||||
|
|
||||||
|
it('normal columns', () => {
|
||||||
|
toIncludeExpect({
|
||||||
|
fields: ['col1', 'col2'],
|
||||||
|
}).toEqual({ attributes: [ 'col1', 'col2' ] });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('association count attribute', () => {
|
||||||
|
toIncludeExpect({
|
||||||
|
fields: ['col1', 'bars_count'],
|
||||||
|
}).toEqual({ attributes: [ 'col1', Foo.withCountAttribute('bars') ] });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('association without attributes', () => {
|
||||||
|
toIncludeExpect({
|
||||||
|
fields: ['col1', 'bars'],
|
||||||
|
}).toEqual({
|
||||||
|
attributes: [ 'col1' ],
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
association: 'bars',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('association attributes', () => {
|
||||||
|
toIncludeExpect({
|
||||||
|
fields: ['col1', 'bars.col1', 'bars.col2'],
|
||||||
|
}).toEqual({
|
||||||
|
attributes: [ 'col1' ],
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
association: 'bars',
|
||||||
|
attributes: [ 'col1', 'col2' ],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('association attributes', () => {
|
||||||
|
toIncludeExpect({
|
||||||
|
fields: ['col1', ['bars', 'col1'], ['bars', 'col2']],
|
||||||
|
}).toEqual({
|
||||||
|
attributes: [ 'col1' ],
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
association: 'bars',
|
||||||
|
attributes: [ 'col1', 'col2' ],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('nested association', () => {
|
||||||
|
toIncludeExpect({
|
||||||
|
fields: ['col1', 'bars.baz'],
|
||||||
|
}).toEqual({
|
||||||
|
attributes: [ 'col1' ],
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
association: 'bars',
|
||||||
|
attributes: [],
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
association: 'baz',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it.skip('nested association', () => {
|
||||||
|
// TODO,输出 bars 的所有字段
|
||||||
|
toIncludeExpect({
|
||||||
|
fields: ['col1', 'bars', 'bars.baz'],
|
||||||
|
}, true).toEqual({
|
||||||
|
attributes: [ 'col1' ],
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
association: 'bars',
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
association: 'baz',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('nested association', () => {
|
||||||
|
toIncludeExpect({
|
||||||
|
fields: ['col1', 'bars.col1', 'bars.col2', 'bars.baz'],
|
||||||
|
}).toEqual({
|
||||||
|
attributes: [ 'col1' ],
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
association: 'bars',
|
||||||
|
attributes: ['col1', 'col2'],
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
association: 'baz',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('nested association', () => {
|
||||||
|
// TODO,输出 bars 的所有字段
|
||||||
|
toIncludeExpect({
|
||||||
|
fields: ['col1', 'bars.col1', 'bars.col2', 'bars.baz.col1', 'bars.baz.col2'],
|
||||||
|
}).toEqual({
|
||||||
|
attributes: [ 'col1' ],
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
association: 'bars',
|
||||||
|
attributes: ['col1', 'col2'],
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
association: 'baz',
|
||||||
|
attributes: ['col1', 'col2'],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('append attributes', () => {
|
||||||
|
toIncludeExpect({
|
||||||
|
fields: {
|
||||||
|
appends: ['bars_count'],
|
||||||
|
},
|
||||||
|
}).toEqual({
|
||||||
|
attributes: {
|
||||||
|
include: [Foo.withCountAttribute('bars')],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('append attributes', () => {
|
||||||
|
toIncludeExpect({
|
||||||
|
fields: {
|
||||||
|
appends: ['bars.col1', 'bars_count'],
|
||||||
|
},
|
||||||
|
}).toEqual({
|
||||||
|
attributes: {
|
||||||
|
include: [Foo.withCountAttribute('bars')],
|
||||||
|
},
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
association: 'bars',
|
||||||
|
attributes: {
|
||||||
|
include: ['col1'],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('only & append attributes', () => {
|
||||||
|
toIncludeExpect({
|
||||||
|
fields: {
|
||||||
|
only: ['col1'],
|
||||||
|
appends: ['bars_count'],
|
||||||
|
},
|
||||||
|
}).toEqual({
|
||||||
|
attributes: ['col1', Foo.withCountAttribute('bars')],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('only & append attributes', () => {
|
||||||
|
toIncludeExpect({
|
||||||
|
fields: {
|
||||||
|
only: ['col1', 'bars.col1'],
|
||||||
|
appends: ['bars_count'],
|
||||||
|
},
|
||||||
|
}).toEqual({
|
||||||
|
attributes: ['col1', Foo.withCountAttribute('bars')],
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
association: 'bars',
|
||||||
|
attributes: ['col1'],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('excpet attributes', () => {
|
||||||
|
toIncludeExpect({
|
||||||
|
fields: {
|
||||||
|
except: ['col1'],
|
||||||
|
},
|
||||||
|
}).toEqual({
|
||||||
|
attributes: {
|
||||||
|
include: [],
|
||||||
|
exclude: ['col1'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('excpet attributes', () => {
|
||||||
|
toIncludeExpect({
|
||||||
|
fields: {
|
||||||
|
except: ['col1', 'bars.col1'],
|
||||||
|
},
|
||||||
|
}).toEqual({
|
||||||
|
attributes: {
|
||||||
|
include: [],
|
||||||
|
exclude: ['col1'],
|
||||||
|
},
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
association: 'bars',
|
||||||
|
attributes: {
|
||||||
|
include: [],
|
||||||
|
exclude: ['col1'],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('excpet & append attributes', () => {
|
||||||
|
toIncludeExpect({
|
||||||
|
fields: {
|
||||||
|
except: ['col1'],
|
||||||
|
appends: ['bars_count'],
|
||||||
|
},
|
||||||
|
}).toEqual({
|
||||||
|
attributes: {
|
||||||
|
include: [Foo.withCountAttribute('bars')],
|
||||||
|
exclude: ['col1'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('where options', () => {
|
||||||
|
it('where', () => {
|
||||||
|
toIncludeExpect({
|
||||||
|
filter: {
|
||||||
|
col1: 'val1',
|
||||||
|
},
|
||||||
|
fields: {
|
||||||
|
except: ['col1'],
|
||||||
|
appends: ['bars_count'],
|
||||||
|
},
|
||||||
|
}).toEqual({
|
||||||
|
attributes: {
|
||||||
|
include: [Foo.withCountAttribute('bars')],
|
||||||
|
exclude: ['col1'],
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
col1: 'val1',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('where', () => {
|
||||||
|
toIncludeExpect({
|
||||||
|
filter: {
|
||||||
|
col1: 'val1',
|
||||||
|
bars: {
|
||||||
|
col1: 'val1',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fields: {
|
||||||
|
except: ['col1'],
|
||||||
|
appends: ['bars', 'bars_count'],
|
||||||
|
},
|
||||||
|
}).toEqual({
|
||||||
|
attributes: {
|
||||||
|
include: [Foo.withCountAttribute('bars')],
|
||||||
|
exclude: ['col1'],
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
col1: 'val1',
|
||||||
|
},
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
association: 'bars',
|
||||||
|
where: {
|
||||||
|
col1: 'val1',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('where', () => {
|
||||||
|
toIncludeExpect({
|
||||||
|
filter: {
|
||||||
|
col1: 'val1',
|
||||||
|
bars: {
|
||||||
|
col1: 'val1',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fields: {
|
||||||
|
except: ['col1'],
|
||||||
|
appends: ['bars_count'],
|
||||||
|
},
|
||||||
|
}).toEqual({
|
||||||
|
attributes: {
|
||||||
|
include: [Foo.withCountAttribute('bars')],
|
||||||
|
exclude: ['col1'],
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
col1: 'val1',
|
||||||
|
},
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
association: 'bars',
|
||||||
|
where: {
|
||||||
|
col1: 'val1',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
262
packages/database/src/__tests__/utils/toWhere.test.ts
Normal file
262
packages/database/src/__tests__/utils/toWhere.test.ts
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
import { Op } from "sequelize";
|
||||||
|
import Database from "../../database";
|
||||||
|
import Model, { ModelCtor } from '../../model';
|
||||||
|
import { toWhere } from "../../utils";
|
||||||
|
import { getDatabase } from "..";
|
||||||
|
|
||||||
|
describe('utils.toWhere', () => {
|
||||||
|
describe('single', () => {
|
||||||
|
it('=', () => {
|
||||||
|
const where = toWhere({
|
||||||
|
id: 12,
|
||||||
|
});
|
||||||
|
expect(where).toEqual({
|
||||||
|
id: 12,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Op.eq', () => {
|
||||||
|
const where = toWhere({
|
||||||
|
id: {
|
||||||
|
eq: 12
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(where).toEqual({
|
||||||
|
id: {
|
||||||
|
[Op.eq]: 12,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Op.ilike', () => {
|
||||||
|
const where = toWhere({
|
||||||
|
id: {
|
||||||
|
ilike: 'val1'
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(where).toEqual({
|
||||||
|
id: {
|
||||||
|
[Op.iLike]: 'val1',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Op.ilike', () => {
|
||||||
|
const where = toWhere({
|
||||||
|
'id.ilike': 'val1',
|
||||||
|
});
|
||||||
|
expect(where).toEqual({
|
||||||
|
id: {
|
||||||
|
[Op.iLike]: 'val1',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Op.is null', () => {
|
||||||
|
const where = toWhere({
|
||||||
|
'id.is': null,
|
||||||
|
});
|
||||||
|
expect(where).toEqual({
|
||||||
|
id: {
|
||||||
|
[Op.is]: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Op.in', () => {
|
||||||
|
const where = toWhere({
|
||||||
|
id: {
|
||||||
|
in: [12]
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(where).toEqual({
|
||||||
|
id: {
|
||||||
|
[Op.in]: [12],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Op.in', () => {
|
||||||
|
const where = toWhere({
|
||||||
|
'id.in': [11, 12],
|
||||||
|
});
|
||||||
|
expect(where).toEqual({
|
||||||
|
id: {
|
||||||
|
[Op.in]: [11, 12],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Op.between', () => {
|
||||||
|
expect(toWhere({
|
||||||
|
'id.between': [1, 2]
|
||||||
|
})).toEqual({
|
||||||
|
id: { [Op.between]: [1, 2] }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('group by logical operator', () => {
|
||||||
|
it('field.or', () => {
|
||||||
|
expect(toWhere({
|
||||||
|
'id.or': [1, 2]
|
||||||
|
})).toEqual({
|
||||||
|
id: { [Op.or]: [1, 2] }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('field.and', () => {
|
||||||
|
expect(toWhere({
|
||||||
|
'id.and': [1, 2]
|
||||||
|
})).toEqual({
|
||||||
|
id: { [Op.and]: [1, 2] }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('root or', () => {
|
||||||
|
expect(toWhere({
|
||||||
|
or: [{ a: 1 }, { b: 2 }]
|
||||||
|
})).toEqual({
|
||||||
|
[Op.or]: [{ a: 1 }, { b: 2 }]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('root and', () => {
|
||||||
|
expect(toWhere({
|
||||||
|
and: [{ a: 1 }, { b: 2 }]
|
||||||
|
})).toEqual({
|
||||||
|
[Op.and]: [{ a: 1 }, { b: 2 }]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('root "and" and "or"', () => {
|
||||||
|
expect(toWhere({
|
||||||
|
and: [{ a: 1 }, { b: 2 }],
|
||||||
|
or: [{ c: 3 }, { d: 4 }]
|
||||||
|
})).toEqual({
|
||||||
|
[Op.and]: [{ a: 1 }, { b: 2 }],
|
||||||
|
[Op.or]: [{ c: 3 }, { d: 4 }]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('root "and" and field', () => {
|
||||||
|
expect(toWhere({
|
||||||
|
and: [{ a: 1 }, { b: 2 }],
|
||||||
|
'id.or': [3, 4]
|
||||||
|
})).toEqual({
|
||||||
|
[Op.and]: [{ a: 1 }, { b: 2 }],
|
||||||
|
id: { [Op.or]: [3, 4] }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('or in and', () => {
|
||||||
|
expect(toWhere({
|
||||||
|
and: [{ a: 1 }, { 'b.or': [3, 4] }],
|
||||||
|
})).toEqual({
|
||||||
|
[Op.and]: [{ a: 1 }, { b: { [Op.or]: [3, 4] } }],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('and in or', () => {
|
||||||
|
expect(toWhere({
|
||||||
|
or: [{ a: 1 }, { and: [{ c: 3 }, { d: 4 }] }],
|
||||||
|
})).toEqual({
|
||||||
|
[Op.or]: [{ a: 1 }, { [Op.and]: [{ c: 3 }, { d: 4 }] }],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO: bug
|
||||||
|
it.skip('field as or', () => {
|
||||||
|
expect(toWhere({
|
||||||
|
or: 1,
|
||||||
|
})).toEqual({
|
||||||
|
or: 1,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO: bug
|
||||||
|
it.skip('or for field as or', () => {
|
||||||
|
expect(toWhere({
|
||||||
|
'or.or': [1, 2],
|
||||||
|
})).toEqual({
|
||||||
|
or: { [Op.or]: [1, 2] },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('association', () => {
|
||||||
|
let db: Database;
|
||||||
|
let Foo: ModelCtor<Model>;
|
||||||
|
beforeAll(() => {
|
||||||
|
db = getDatabase();
|
||||||
|
db.table({
|
||||||
|
name: 'bazs',
|
||||||
|
});
|
||||||
|
db.table({
|
||||||
|
name: 'bars',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: 'belongsTo',
|
||||||
|
name: 'baz',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
db.table({
|
||||||
|
name: 'foos',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: 'hasMany',
|
||||||
|
name: 'bars',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
Foo = db.getModel('foos');
|
||||||
|
});
|
||||||
|
afterAll(() => db.close());
|
||||||
|
|
||||||
|
const toWhereExpect = (options, logging = false) => {
|
||||||
|
const where = toWhere(options, {
|
||||||
|
associations: Foo.associations,
|
||||||
|
});
|
||||||
|
return expect(where);
|
||||||
|
}
|
||||||
|
|
||||||
|
it('association', () => {
|
||||||
|
toWhereExpect({
|
||||||
|
col1: 'val1',
|
||||||
|
bars: {
|
||||||
|
name: {
|
||||||
|
ilike: 'aa',
|
||||||
|
},
|
||||||
|
col2: {
|
||||||
|
lt: 2,
|
||||||
|
},
|
||||||
|
baz: {
|
||||||
|
col1: 12,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'bars.col3.ilike': 'aa',
|
||||||
|
}).toEqual({
|
||||||
|
col1: 'val1',
|
||||||
|
$__include: {
|
||||||
|
bars: {
|
||||||
|
name: {
|
||||||
|
[Op.iLike]: 'aa',
|
||||||
|
},
|
||||||
|
col2: {
|
||||||
|
[Op.lt]: 2,
|
||||||
|
},
|
||||||
|
col3: {
|
||||||
|
[Op.iLike]: 'aa',
|
||||||
|
},
|
||||||
|
$__include: {
|
||||||
|
baz: {
|
||||||
|
col1: 12
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -19,9 +19,12 @@ interface ToWhereContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function toWhere(options: any, context: ToWhereContext = {}) {
|
export function toWhere(options: any, context: ToWhereContext = {}) {
|
||||||
if (options === null || Array.isArray(options) || typeof options !== 'object') {
|
if (options === null || typeof options !== 'object') {
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
if (Array.isArray(options)) {
|
||||||
|
return options.map((item) => toWhere(item, context));
|
||||||
|
}
|
||||||
const { Model, associations = {}, ctx, dialect } = context;
|
const { Model, associations = {}, ctx, dialect } = context;
|
||||||
const items = {};
|
const items = {};
|
||||||
// 先处理「点号」的问题
|
// 先处理「点号」的问题
|
||||||
@ -48,6 +51,7 @@ export function toWhere(options: any, context: ToWhereContext = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// TODO: to fix same op key as field name
|
||||||
values[op.has(key) ? op.get(key) : key] = toWhere(items[key], context);
|
values[op.has(key) ? op.get(key) : key] = toWhere(items[key], context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user