diff --git a/dev/create-sequelize-instance.ts b/dev/create-sequelize-instance.ts index 1ec6d6438..3d25701dd 100644 --- a/dev/create-sequelize-instance.ts +++ b/dev/create-sequelize-instance.ts @@ -1,15 +1,13 @@ -import type { Options as Sequelize6Options } from 'sequelize'; -import { Sequelize as Sequelize6 } from 'sequelize'; -import type { Options as Sequelize7Options, Sequelize as Sequelize7 } from '@sequelize/core'; -import { wrapOptions } from './wrap-options'; +import type { Options as Sequelize6Options } from "sequelize"; +import { Sequelize as Sequelize6 } from "sequelize"; +import type { + Options as Sequelize7Options, + Sequelize as Sequelize7, +} from "@sequelize/core"; +import { wrapOptions } from "./wrap-options"; -export function createSequelize6Instance(options?: Sequelize6Options): Sequelize6 { +export function createSequelize6Instance( + options?: Sequelize6Options +): Sequelize6 { return new Sequelize6(wrapOptions(options)); } - -export function createSequelize7Instance(options?: Sequelize7Options): Sequelize7 { - // not compatible with node 10 - const { Sequelize: Sequelize7Constructor } = require('@sequelize/core'); - // @ts-expect-error -- wrapOptions expect sequelize 6. - return new Sequelize7Constructor(wrapOptions(options)); -} diff --git a/package.json b/package.json index b54c66b62..28c066b0d 100644 --- a/package.json +++ b/package.json @@ -6,14 +6,15 @@ "type": "commonjs", "license": "MIT", "dependencies": { + "@sequelize/core": "alpha", "chai": "^4", "chai-as-promised": "^7", "chai-datetime": "^1", "chalk": "^4.1.2", "cross-env": "^7", "fs-jetpack": "^4", + "pg": "^8.13.1", "sequelize": "^6", - "@sequelize/core": "alpha", "sinon": "^13", "sinon-chai": "^3" }, diff --git a/src/sscce-sequelize-6.ts b/src/sscce-sequelize-6.ts index 132a311d5..1ddd8fe2e 100644 --- a/src/sscce-sequelize-6.ts +++ b/src/sscce-sequelize-6.ts @@ -1,10 +1,17 @@ -import { DataTypes, Model } from 'sequelize'; -import { createSequelize6Instance } from '../dev/create-sequelize-instance'; -import { expect } from 'chai'; -import sinon from 'sinon'; +import { DataTypes, Model, fn, col, where, Association } from "sequelize"; +import { createSequelize6Instance } from "../dev/create-sequelize-instance"; +import { expect, use } from "chai"; +import sinon from "sinon"; // if your issue is dialect specific, remove the dialects you don't need to test on. -export const testingOnDialects = new Set(['mssql', 'sqlite', 'mysql', 'mariadb', 'postgres', 'postgres-native']); +export const testingOnDialects = new Set([ + "mssql", + "sqlite", + "mysql", + "mariadb", + "postgres", + "postgres-native", +]); // You can delete this file if you don't want your SSCCE to be tested against Sequelize 6 @@ -21,21 +28,136 @@ export async function run() { }, }); - class Foo extends Model {} + class User extends Model { + public readonly id!: number; + public name!: string; + static Tags: Association; + } - Foo.init({ - name: DataTypes.TEXT, - }, { - sequelize, - modelName: 'Foo', - }); + User.init( + { + id: { type: DataTypes.INTEGER, autoIncrement: true, primaryKey: true }, + name: DataTypes.TEXT, + }, + { + sequelize, + modelName: "User", + } + ); + + class Tag extends Model { + public readonly id!: number; + public name!: string; + static Users: Association; + } + + Tag.init( + { + id: { type: DataTypes.INTEGER, autoIncrement: true, primaryKey: true }, + name: DataTypes.TEXT, + }, + { + sequelize, + modelName: "Tag", + } + ); + + class UserTag extends Model { + public readonly id!: number; + static User: Association; + static Tag: Association; + } + + UserTag.init( + { + id: { type: DataTypes.INTEGER, autoIncrement: true, primaryKey: true }, + // userId: { + // type: DataTypes.INTEGER, + // }, + // tagId: { + // type: DataTypes.INTEGER, + // }, + }, + { + sequelize, + modelName: "UserTag", + } + ); + + UserTag.User = UserTag.hasOne(User); + UserTag.Tag = UserTag.hasOne(Tag); + + User.Tags = User.belongsToMany(Tag, { through: UserTag }); + Tag.Users = Tag.belongsToMany(User, { through: UserTag }); // You can use sinon and chai assertions directly in your SSCCE. - const spy = sinon.spy(); - sequelize.afterBulkSync(() => spy()); + // const spy = sinon.spy(); + // sequelize.afterBulkSync(() => spy()); await sequelize.sync({ force: true }); - expect(spy).to.have.been.called; + // expect(spy).to.have.been.called; + + const bob = await User.create({ name: "Bob" }); + const joe = await User.create({ name: "Joe" }); + const sue = await User.create({ name: "Sue" }); + const walt = await User.create({ name: "Walt" }); + const ann = await User.create({ name: "Annette" }); + const pat = await User.create({ name: "Patricia" }); + const contribTag = await Tag.create({ name: "Contributer" }); + const adminTag = await Tag.create({ name: "Admin" }); + const ownerTag = await Tag.create({ name: "Owner" }); + + await UserTag.create({ + user: bob, + tag: contribTag, + }); + + await UserTag.create({ + user: joe, + tag: contribTag, + }); + + await UserTag.create({ + user: sue, + tag: contribTag, + }); + + await UserTag.create({ + user: walt, + tag: adminTag, + }); + + await UserTag.create({ + user: ann, + tag: adminTag, + }); + + await UserTag.create({ + user: pat, + tag: ownerTag, + }); + + await UserTag.create({ + user: pat, + tag: adminTag, + }); + + expect(await User.count()).to.equal(6); + expect(await Tag.count()).to.equal(3); + expect(await UserTag.count()).to.equal(7); + + const rowsPerPage = 30; + const page = 1; + + const users = await User.findAll({ + include: [{ association: User.Tags }], + order: [fn("BOOL_OR", where(col("userTags.tagId"), adminTag.id)), "DESC"], + group: ["users.id"], + offset: rowsPerPage * (page - 1), + limit: rowsPerPage, + }); - console.log(await Foo.create({ name: 'TS foo' })); - expect(await Foo.count()).to.equal(1); + expect(users.length).to.equal(6); + expect(users[0].name).to.equal("Walt"); + expect(users[1].name).to.equal("Annette"); + expect(users[2].name).to.equal("Patricia"); } diff --git a/src/sscce-sequelize-7.ts b/src/sscce-sequelize-7.ts deleted file mode 100644 index 603cb219c..000000000 --- a/src/sscce-sequelize-7.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { CreationOptional, DataTypes, InferAttributes, InferCreationAttributes, Model } from '@sequelize/core'; -import { Attribute, NotNull } from '@sequelize/core/decorators-legacy'; -import { createSequelize7Instance } from '../dev/create-sequelize-instance'; -import { expect } from 'chai'; -import sinon from 'sinon'; - -// if your issue is dialect specific, remove the dialects you don't need to test on. -export const testingOnDialects = new Set(['mssql', 'sqlite', 'mysql', 'mariadb', 'postgres', 'postgres-native']); - -// You can delete this file if you don't want your SSCCE to be tested against Sequelize 7 - -// Your SSCCE goes inside this function. -export async function run() { - // This function should be used instead of `new Sequelize()`. - // It applies the config for your SSCCE to work on CI. - const sequelize = createSequelize7Instance({ - logQueryParameters: true, - benchmark: true, - define: { - // For less clutter in the SSCCE - timestamps: false, - }, - }); - - class Foo extends Model, InferCreationAttributes> { - declare id: CreationOptional; - - @Attribute(DataTypes.TEXT) - @NotNull - declare name: string; - } - - sequelize.addModels([Foo]); - - // You can use sinon and chai assertions directly in your SSCCE. - const spy = sinon.spy(); - sequelize.afterBulkSync(() => spy()); - await sequelize.sync({ force: true }); - expect(spy).to.have.been.called; - - console.log(await Foo.create({ name: 'TS foo' })); - expect(await Foo.count()).to.equal(1); -}