tachybase_todo/packages/database/src/__tests__/tables.test.ts
2021-03-28 13:34:51 +08:00

380 lines
9.9 KiB
TypeScript

import { getDatabase } from './';
import Database from '../database';
import Table from '../table';
import Model from '../model';
import path from 'path';
let db: Database;
beforeEach(async () => {
db = getDatabase();
});
afterEach(async () => {
await db.close();
});
describe('tables', () => {
describe('options', () => {
it('should be defined', () => {
db.table({
name: 'foo',
});
expect(db.getTable('foo')).toBeInstanceOf(Table);
expect(db.isDefined('foo')).toBe(true);
});
it('custom model test', () => {
class Abc extends Model {
public static database: Database;
static getModel(name: string) {
return this.database.getModel(name);
}
static test12345() {
return 'test12345';
}
}
const table = db.table({
name: 'abc',
model: Abc,
});
expect(Abc.database).toBe(db);
expect(table.getModel().test12345()).toBe('test12345');
expect(Abc.getModel('abc').test12345()).toBe('test12345');
});
it('should tableName === name', async () => {
db.table({
name: 'foos',
});
expect(db.getModel('foos').name).toBe('foos');
// hooked by beforeDefine in index.ts
expect(db.getModel('foos').getTableName()).toBe('_database__tables_foos');
});
it('should be custom when tableName is defined', async () => {
db.table({
name: 'bar',
tableName: 'bar_v2'
});
expect(db.getModel('bar').name).toBe('bar');
// hooked by beforeDefine in index.ts
expect(db.getModel('bar').getTableName()).toBe('_database__tables_bar_v2');
});
it('should be custom when timestamps is defined', async () => {
db.table({
name: 'baz',
createdAt: 'created',
updatedAt: 'updated',
});
expect(db.getModel('baz').rawAttributes.created).toBeDefined();
expect(db.getModel('baz').rawAttributes.updated).toBeDefined();
});
it('index should be defined', async () => {
db.table({
name: 'baz',
fields: [
{
type: 'string',
name: 'col1',
index: true,
},
{
type: 'string',
name: 'col2',
},
{
type: 'string',
name: 'col3',
index: {
fields: ['col2', 'col3'],
},
},
],
});
expect(db.getModel('baz').options.indexes).toStrictEqual(db.getTable('baz').getModelOptions().indexes);
// @ts-ignore
expect(db.getTable('baz').getModelOptions().indexes).toMatchObject([
{ fields: ['col1'], name: 'baz_col1', parser: null },
{ fields: ['col2', 'col3'], name: 'baz_col2_col3', parser: null }
]);
});
it('index should be defined', async () => {
db.table({
name: 'baz2',
indexes: [
{
fields: ['col1'],
},
{
fields: ['col2', 'col3'],
},
],
fields: [
{
type: 'string',
name: 'col1',
},
{
type: 'string',
name: 'col2',
},
{
type: 'string',
name: 'col3',
},
],
});
expect(db.getModel('baz2').options.indexes).toStrictEqual(db.getTable('baz2').getModelOptions().indexes);
// @ts-ignore
expect(db.getTable('baz2').getModelOptions().indexes).toMatchObject([
{ fields: ['col1'], name: 'baz2_col1', parser: null },
{ fields: ['col2', 'col3'], name: 'baz2_col2_col3', parser: null },
]);
});
});
describe('#extend()', () => {
it('extend options', async () => {
db.table({
name: 'baz',
});
expect(db.getModel('baz').rawAttributes.created_at).toBeDefined();
expect(db.getModel('baz').rawAttributes.updated_at).toBeDefined();
db.extend({
name: 'baz',
createdAt: 'created',
updatedAt: 'updated',
});
expect(db.getModel('baz').rawAttributes.created).toBeDefined();
expect(db.getModel('baz').rawAttributes.updated).toBeDefined();
});
it('extend fields', async () => {
db.table({
name: 'foos',
});
db.table({
name: 'baz',
fields: [
{
type: 'string',
name: 'col1',
},
{
type: 'hasOne',
name: 'foo',
}
]
});
db.extend({
name: 'baz',
timestamps: false,
fields: [
{
type: 'string',
name: 'col2',
}
],
});
expect(db.getModel('baz').rawAttributes.col1).toBeDefined();
expect(db.getModel('baz').rawAttributes.col2).toBeDefined();
expect(db.getModel('baz').rawAttributes.created_at).toBeUndefined();
expect(db.getModel('baz').rawAttributes.updated_at).toBeUndefined();
expect(db.getModel('baz').rawAttributes.col2).toBeDefined();
expect(db.getModel('baz').associations.foo).toBeDefined();
// await db.sync({force: true});
// await db.sequelize.close();
});
it('extend array options', async () => {
db.table({
name: 'baz',
actions: [
{
name: 'list',
}
]
});
db.extend({
name: 'baz',
actions: [
{
name: 'get',
}
]
});
expect(db.getTable('baz').getOptions()).toEqual({
name: 'baz',
actions: [{ name: 'get' }]
});
});
it('extend with customMerge', async () => {
db.table({
name: 'baz',
actions: [
{
name: 'list',
}
]
});
db.extend({
name: 'baz',
actions: [
{
name: 'get',
}
]
}, {
customMerge: (key, options) => {
if (key !== 'actions') {
return;
}
return (source, target) => source.concat(target);
}
});
expect(db.getTable('baz').getOptions()).toEqual({
name: 'baz',
actions: [{ name: 'list' }, { name: 'get' }]
});
});
});
describe.only('#import()', () => {
it('import tables', () => {
const tables = db.import({
directory: path.resolve(__dirname, './tables'),
});
expect([...tables.keys()]).toEqual(['demos', 'examples', 'tests']);
expect(db.getTable('demos').getOptions()).toEqual({
name: 'demos', actions: [{ name: 'create' }, { name: 'list' }]
});
expect(db.getTable('examples').getOptions()).toEqual({
name: 'examples', actions: [{ name: 'create' }]
});
expect(db.getTable('tests').getOptions()).toEqual({
name: 'tests', actions: [{ name: 'list' }]
});
});
});
describe('associations', () => {
beforeAll(() => {
});
it('should be undefined when target table does not exist', () => {
db.table({
name: 'bars',
fields: [
{
type: 'hasOne',
name: 'foo',
}
],
});
expect(db.getModel('bars').associations.foo).toBeUndefined();
});
it('should be defined when target table exists', () => {
db.table({
name: 'bars',
fields: [
{
type: 'hasOne',
name: 'foo',
}
],
});
db.table({ name: 'foos' });
expect(db.getModel('bars').associations.foo).toBeDefined();
});
describe('#setFields()', () => {
beforeEach(() => {
db.table({
name: 'table1',
fields: [
{
type: 'hasOne',
name: 'table21',
target: 'table2',
},
{
type: 'hasOne',
name: 'table22',
target: 'table2',
},
]
});
db.table({
name: 'table2',
});
});
it('should be defined', () => {
const table1 = db.getModel('table1');
expect(Object.keys(table1.associations).length).toBe(2);
expect(table1.associations.table21).toBeDefined();
expect(table1.associations.table22).toBeDefined();
});
it('should be defined', () => {
db.getTable('table1').setFields([
{
type: 'string',
name: 'name',
},
{
type: 'hasOne',
name: 'table23',
target: 'table2',
},
]);
const table1 = db.getModel('table1');
expect(table1.rawAttributes.name).toBeDefined();
expect(Object.keys(table1.associations).length).toBe(1);
expect(table1.associations.table21).toBeUndefined();
expect(table1.associations.table22).toBeUndefined();
expect(table1.associations.table23).toBeDefined();
});
});
describe('#addField()', () => {
beforeEach(() => {
db.table({
name: 'table1',
});
db.table({
name: 'table2',
});
});
it('should be defined when the field be added after initialization', () => {
db.getTable('table1').addField({
type: 'hasOne',
name: 'table2',
target: 'table2',
});
expect(Object.keys(db.getModel('table1').associations).length).toBe(1);
expect(db.getModel('table1').associations.table2).toBeDefined();
});
it('should be defined when continue to add', () => {
db.getTable('table1').addField({
type: 'hasOne',
name: 'table2',
target: 'table2',
});
db.getTable('table1').addField({
type: 'hasOne',
name: 'table21',
target: 'table2',
});
expect(Object.keys(db.getModel('table1').associations).length).toBe(2);
expect(db.getModel('table1').associations.table2).toBeDefined();
expect(db.getModel('table1').associations.table21).toBeDefined();
});
});
});
});