不要怂,就是干,撸起袖子干!

Commit 914279aa by papb

test(types): refactor adding `expect-type`

Closes #11829
1 parent 9634338d
......@@ -58,7 +58,6 @@
"cls-hooked": "^4.2.2",
"cross-env": "^7.0.2",
"delay": "^4.3.0",
"dtslint": "^3.6.4",
"env-cmd": "^10.1.0",
"esdoc": "^1.1.0",
"esdoc-ecmascript-proposal-plugin": "^1.0.0",
......@@ -67,6 +66,7 @@
"eslint": "^6.8.0",
"eslint-plugin-jsdoc": "^20.4.0",
"eslint-plugin-mocha": "^6.2.2",
"expect-type": "^0.11.0",
"fs-jetpack": "^4.1.0",
"husky": "^4.2.5",
"js-combinatorics": "^0.5.5",
......@@ -185,7 +185,7 @@
"test-postgresn": "npm run test-postgres-native",
"test-mssql": "cross-env DIALECT=mssql npm test",
"test-all": "npm run test-mariadb && npm run test-mysql && npm run test-sqlite && npm run test-postgres && npm run test-postgres-native && npm run test-mssql",
"test-typings": "tsc -b types/tsconfig.json && dtslint --expectOnly types/test",
"test-typings": "tsc -b types/tsconfig.json && tsc -b types/test/tsconfig.json",
"cover": "rimraf coverage && npm run teaser && npm run cover-integration && npm run cover-unit && npm run merge-coverage",
"cover-integration": "cross-env COVERAGE=true nyc --reporter=lcovonly mocha -t 30000 --exit \"test/integration/**/*.test.js\" && node -e \"require('fs').renameSync('coverage/lcov.info', 'coverage/integration.info')\"",
"cover-unit": "cross-env COVERAGE=true nyc --reporter=lcovonly mocha -t 30000 --exit \"test/unit/**/*.test.js\" && node -e \"require('fs').renameSync('coverage/lcov.info', 'coverage/unit.info')\"",
......
import { expectTypeOf } from "expect-type";
import { QueryTypes, Sequelize, SyncOptions } from 'sequelize';
import { User } from 'models/User';
......@@ -8,22 +9,18 @@ sequelize.afterBulkSync((options: SyncOptions) => {
});
async function test() {
const rows: unknown[] = await sequelize
.query('SELECT * FROM `test`', {
type: QueryTypes.SELECT,
});
const [autoIncrementId, affectedRows] = await sequelize
.query('INSERT into test set test=1', {
type: QueryTypes.INSERT,
});
}
expectTypeOf(
await sequelize.query('SELECT * FROM `test`', { type: QueryTypes.SELECT })
).toEqualTypeOf<unknown[]>();
expectTypeOf(
await sequelize.query('INSERT into test set test=1', { type: QueryTypes.INSERT })
).toEqualTypeOf<[number, number]>();
}
sequelize.transaction<void>(async transaction => {
const rows = await sequelize
.query('SELECT * FROM `user`', {
expectTypeOf(
await sequelize.query('SELECT * FROM `user`', {
retry: {
max: 123,
},
......@@ -31,12 +28,15 @@ sequelize.transaction<void>(async transaction => {
transaction,
logging: true,
})
).toEqualTypeOf<User[]>();
});
sequelize.query('SELECT * FROM `user` WHERE status = $1',
sequelize.query(
'SELECT * FROM `user` WHERE status = $1',
{ bind: ['active'], type: QueryTypes.SELECT }
);
sequelize.query('SELECT * FROM `user` WHERE status = $status',
sequelize.query(
'SELECT * FROM `user` WHERE status = $status',
{ bind: { status: 'active' }, type: QueryTypes.SELECT }
);
import { expectTypeOf } from "expect-type";
import { Model, Op } from 'sequelize';
class MyModel extends Model {}
const grouped: Promise<{ [key: string]: number }> = MyModel.count({ group: 'tag' });
const counted: Promise<number> = MyModel.count();
const countedDistinct: Promise<number> = MyModel.count({ col: 'tag', distinct: true });
const countedDistinctOnReader: Promise<number> = MyModel.count({ where: { updatedAt: { [Op.gte]: new Date() } }, useMaster: false })
expectTypeOf(MyModel.count()).toEqualTypeOf<Promise<number>>();
expectTypeOf(MyModel.count({ group: 'tag' })).toEqualTypeOf<Promise<{ [key: string]: number }>>();
expectTypeOf(MyModel.count({ col: 'tag', distinct: true })).toEqualTypeOf<Promise<number>>();
expectTypeOf(MyModel.count({
where: {
updatedAt: {
[Op.gte]: new Date()
}
},
useMaster: false
})).toEqualTypeOf<Promise<number>>();
import { INTEGER, IntegerDataType, TINYINT } from 'sequelize';
import { SmallIntegerDataType, SMALLINT, MEDIUMINT, MediumIntegerDataType, BigIntDataType, BIGINT } from '../lib/data-types';
import { expectTypeOf } from 'expect-type';
import { DataTypes } from 'sequelize';
let tinyint: IntegerDataType;
tinyint = TINYINT();
tinyint = new TINYINT();
tinyint = TINYINT.UNSIGNED.ZEROFILL();
tinyint = new TINYINT.UNSIGNED.ZEROFILL();
const { TINYINT, SMALLINT, MEDIUMINT, BIGINT, INTEGER } = DataTypes;
let smallint: SmallIntegerDataType;
smallint = SMALLINT();
smallint = new SMALLINT();
smallint = SMALLINT.UNSIGNED.ZEROFILL();
smallint = new SMALLINT.UNSIGNED.ZEROFILL();
// TINYINT
expectTypeOf(TINYINT()).toEqualTypeOf<DataTypes.TinyIntegerDataType>();
expectTypeOf(new TINYINT()).toEqualTypeOf<DataTypes.TinyIntegerDataType>();
expectTypeOf(TINYINT.UNSIGNED.ZEROFILL()).toEqualTypeOf<DataTypes.TinyIntegerDataType>();
expectTypeOf(new TINYINT.UNSIGNED.ZEROFILL()).toEqualTypeOf<DataTypes.TinyIntegerDataType>();
let mediumint: MediumIntegerDataType;
mediumint = MEDIUMINT();
mediumint = new MEDIUMINT();
mediumint = MEDIUMINT.UNSIGNED.ZEROFILL();
mediumint = new MEDIUMINT.UNSIGNED.ZEROFILL();
// SMALLINT
expectTypeOf(SMALLINT()).toEqualTypeOf<DataTypes.SmallIntegerDataType>();
expectTypeOf(new SMALLINT()).toEqualTypeOf<DataTypes.SmallIntegerDataType>();
expectTypeOf(SMALLINT.UNSIGNED.ZEROFILL()).toEqualTypeOf<DataTypes.SmallIntegerDataType>();
expectTypeOf(new SMALLINT.UNSIGNED.ZEROFILL()).toEqualTypeOf<DataTypes.SmallIntegerDataType>();
let int: IntegerDataType;
int = INTEGER();
int = new INTEGER();
int = INTEGER.UNSIGNED.ZEROFILL();
int = new INTEGER.UNSIGNED.ZEROFILL();
// MEDIUMINT
expectTypeOf(MEDIUMINT()).toEqualTypeOf<DataTypes.MediumIntegerDataType>();
expectTypeOf(new MEDIUMINT()).toEqualTypeOf<DataTypes.MediumIntegerDataType>();
expectTypeOf(MEDIUMINT.UNSIGNED.ZEROFILL()).toEqualTypeOf<DataTypes.MediumIntegerDataType>();
expectTypeOf(new MEDIUMINT.UNSIGNED.ZEROFILL()).toEqualTypeOf<DataTypes.MediumIntegerDataType>();
let bigint: BigIntDataType;
bigint = BIGINT();
bigint = new BIGINT();
bigint = BIGINT.UNSIGNED.ZEROFILL();
bigint = new BIGINT.UNSIGNED.ZEROFILL();
// BIGINT
expectTypeOf(BIGINT()).toEqualTypeOf<DataTypes.BigIntDataType>();
expectTypeOf(new BIGINT()).toEqualTypeOf<DataTypes.BigIntDataType>();
expectTypeOf(BIGINT.UNSIGNED.ZEROFILL()).toEqualTypeOf<DataTypes.BigIntDataType>();
expectTypeOf(new BIGINT.UNSIGNED.ZEROFILL()).toEqualTypeOf<DataTypes.BigIntDataType>();
// INTEGER
expectTypeOf(INTEGER()).toEqualTypeOf<DataTypes.IntegerDataType>();
expectTypeOf(new INTEGER()).toEqualTypeOf<DataTypes.IntegerDataType>();
expectTypeOf(INTEGER.UNSIGNED.ZEROFILL()).toEqualTypeOf<DataTypes.IntegerDataType>();
expectTypeOf(new INTEGER.UNSIGNED.ZEROFILL()).toEqualTypeOf<DataTypes.IntegerDataType>();
import { expectTypeOf } from 'expect-type';
import { BuildOptions, DataTypes, Model, Optional } from 'sequelize';
import { sequelize } from './connection';
......@@ -12,9 +13,7 @@ interface UserAttributes {
interface UserCreationAttributes extends Optional<UserAttributes, 'id'> {}
interface UserModel
extends Model<UserAttributes, UserCreationAttributes>,
UserAttributes {}
interface UserModel extends Model<UserAttributes, UserCreationAttributes>, UserAttributes {}
const User = sequelize.define<UserModel>(
'User',
......@@ -28,14 +27,14 @@ const User = sequelize.define<UserModel>(
);
async function test() {
const user: UserModel = new User() as UserModel;
expectTypeOf<UserModel>().toMatchTypeOf(new User());
const user2: UserModel | null = await User.findOne();
if (!user2) return;
const user = await User.findOne();
expectTypeOf(user).toEqualTypeOf<UserModel | null>();
user2.firstName = 'John';
await user2.save();
if (!user) return;
user.firstName = 'John';
await user.save();
}
// The below doesn't define Attribute types, but should still work
......@@ -61,12 +60,12 @@ UntypedUser.customStaticMethod = () => {};
async function testUntyped() {
UntypedUser.customStaticMethod();
const user: UntypedUserModel = new UntypedUser() as UntypedUserModel;
const user2: UntypedUserModel | null = await UntypedUser.findOne();
if (!user2) return;
expectTypeOf<UntypedUserModel>().toMatchTypeOf(new UntypedUser());
user2.firstName = 'John';
const user = await UntypedUser.findOne();
expectTypeOf(user).toEqualTypeOf<UntypedUserModel | null>();
await user2.save();
if (!user) return;
user.firstName = 'John';
await user.save();
}
// Error === BaseError
import { BaseError, EmptyResultError, Error, UniqueConstraintError } from 'sequelize';
import { User } from './models/User';
import { expectTypeOf } from "expect-type";
import { BaseError, EmptyResultError, Error as AliasedBaseError, UniqueConstraintError } from 'sequelize';
import { OptimisticLockError } from '../lib/errors';
async function test() {
try {
await User.create({ username: 'john_doe', firstName: 'John' });
} catch (e) {
if (e instanceof UniqueConstraintError) {
throw new Error((e as UniqueConstraintError).sql);
}
}
try {
await User.findOne({
rejectOnEmpty: true,
where: {
username: 'something_that_doesnt_exist',
},
});
} catch (e) {
if (!(e instanceof EmptyResultError)) {
throw new Error('should return emptyresulterror');
}
}
class CustomError extends Error {}
try {
await User.findOne({
rejectOnEmpty: new CustomError('User does not exist'),
where: {
username: 'something_that_doesnt_exist',
},
});
} catch (e) {
if (!(e instanceof CustomError)) {
throw new Error('should return CustomError');
}
if (e.message !== 'User does not exist') {
throw new Error('should return CustomError with the proper message')
}
}
try {
const user: User | null = await User.findByPk(1);
if (user != null) {
user.username = 'foo';
user.save();
}
} catch (e) {
if (!(e instanceof OptimisticLockError)) {
throw new Error('should return OptimisticLockError');
}
}
}
expectTypeOf<AliasedBaseError>().toEqualTypeOf<BaseError>();
expectTypeOf<UniqueConstraintError>().toHaveProperty('sql').toBeString();
expectTypeOf<EmptyResultError>().toMatchTypeOf<BaseError>();
expectTypeOf<UniqueConstraintError>().toMatchTypeOf<BaseError>();
expectTypeOf<OptimisticLockError>().toMatchTypeOf<BaseError>();
import { User } from "./models/User";
User.findOne({ where: { firstName: 'John' }});
User.findOne({ where: { firstName: 'John' } });
// The below line should be an error if uncommented, thanks to the new
// TAttributes-based typechecking
// User.findOne({ where: { blah: 'blah2' }});
// @ts-expect-error
User.findOne({ where: { blah: 'blah2' } });
// Controls typescript version for testing the types
// TypeScript Version: 3.6
import { expectTypeOf } from "expect-type";
import { Association, BelongsToManyGetAssociationsMixin, DataTypes, HasOne, Model, Sequelize } from 'sequelize';
expectTypeOf<HasOne>().toMatchTypeOf<Association>();
class MyModel extends Model {
public num!: number;
public static associations: {
......@@ -12,10 +14,9 @@ class MyModel extends Model {
class OtherModel extends Model {}
const assoc: Association = MyModel.associations.other;
const Instance: MyModel = new MyModel({ int: 10 });
const num: number = Instance.get('num');
expectTypeOf(Instance.get('num')).toEqualTypeOf<number>();
MyModel.findOne({
include: [
......@@ -102,7 +103,7 @@ UserModel.findCreateFind({
* Tests for findOrCreate() type.
*/
UserModel.findOrCreate({
UserModel.findOrCreate({
fields: [ "jane.doe" ],
where: {
username: "jane.doe"
......@@ -122,13 +123,13 @@ TestModel.primaryKeyAttributes;
* Test for joinTableAttributes on BelongsToManyGetAssociationsMixin
*/
class SomeModel extends Model {
public getOthers!: BelongsToManyGetAssociationsMixin<OtherModel>
public getOthers!: BelongsToManyGetAssociationsMixin<OtherModel>
}
const someInstance = new SomeModel()
const someInstance = new SomeModel();
someInstance.getOthers({
joinTableAttributes: { include: [ 'id' ] }
})
joinTableAttributes: { include: ['id'] }
});
/**
* Test for through options in creating a BelongsToMany association
......@@ -142,11 +143,11 @@ Film.belongsToMany(Actor, {
model: 'FilmActors',
paranoid: true
}
})
});
Actor.belongsToMany(Film, {
through: {
model: 'FilmActors',
paranoid: true
}
})
});
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!