From c23a36b1700a7832fb9422cf2edf8cf7db90876e Mon Sep 17 00:00:00 2001 From: Vincent Smith Date: Wed, 23 Jul 2025 11:48:18 -0400 Subject: [PATCH 1/5] Create SSCCE --- dev/create-sequelize-instance.ts | 2 +- package.json | 5 +- src/sscce-sequelize-6.ts | 86 +++++++++++++++++++++++++---- src/sscce-sequelize-7.ts | 95 +++++++++++++++++++++++++++----- 4 files changed, 159 insertions(+), 29 deletions(-) diff --git a/dev/create-sequelize-instance.ts b/dev/create-sequelize-instance.ts index 1ec6d6438..5011c99a1 100644 --- a/dev/create-sequelize-instance.ts +++ b/dev/create-sequelize-instance.ts @@ -7,7 +7,7 @@ export function createSequelize6Instance(options?: Sequelize6Options): Sequelize return new Sequelize6(wrapOptions(options)); } -export function createSequelize7Instance(options?: Sequelize7Options): Sequelize7 { +export function createSequelize7Instance(options?: Sequelize7Options): Sequelize7 { // not compatible with node 10 const { Sequelize: Sequelize7Constructor } = require('@sequelize/core'); // @ts-expect-error -- wrapOptions expect sequelize 6. diff --git a/package.json b/package.json index b54c66b62..b4dd09a82 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "type": "commonjs", "license": "MIT", "dependencies": { + "@sequelize/core": "alpha", "chai": "^4", "chai-as-promised": "^7", "chai-datetime": "^1", @@ -13,9 +14,9 @@ "cross-env": "^7", "fs-jetpack": "^4", "sequelize": "^6", - "@sequelize/core": "alpha", "sinon": "^13", - "sinon-chai": "^3" + "sinon-chai": "^3", + "yarn": "^1.22.22" }, "scripts": { "_test": "ts-node dev/runner.ts", diff --git a/src/sscce-sequelize-6.ts b/src/sscce-sequelize-6.ts index 132a311d5..78a48522b 100644 --- a/src/sscce-sequelize-6.ts +++ b/src/sscce-sequelize-6.ts @@ -6,8 +6,6 @@ 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 6 - // Your SSCCE goes inside this function. export async function run() { // This function should be used instead of `new Sequelize()`. @@ -18,17 +16,66 @@ export async function run() { define: { // For less clutter in the SSCCE timestamps: false, + underscored: true }, }); - class Foo extends Model {} - - Foo.init({ +class Parents extends Model {}; +Parents.init( + { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + }, name: DataTypes.TEXT, - }, { - sequelize, - modelName: 'Foo', - }); + }, + {sequelize}, +); + +class Children extends Model {}; +Children.init( + { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + parentId: { + type: DataTypes.INTEGER, + references: { + model: Parents, + key: 'id' + } + } + }, + {sequelize} + +) + +class GrandChildren extends Model {}; +GrandChildren.init( + { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + parentId: { + type: DataTypes.INTEGER, + references: { + model: Children, + key: 'id' + } + } + }, + {sequelize} +); + +Parents.hasMany(Children) +Children.belongsTo(Parents) +Children.hasMany(GrandChildren) +GrandChildren.belongsTo(Children) // You can use sinon and chai assertions directly in your SSCCE. const spy = sinon.spy(); @@ -36,6 +83,23 @@ export async function run() { 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); + const created = await Parents.create() + const {rows, count} = await Parents.findAndCountAll({ + include: { + model: Children, + required: false, + include: [{ + model: GrandChildren, + required: true, + }] + }, + limit: 1 + }) + + console.log(rows); + expect(created).to.not.be.undefined; + expect(created).to.not.be.null; + expect(count).to.equal(1); } + + diff --git a/src/sscce-sequelize-7.ts b/src/sscce-sequelize-7.ts index 603cb219c..4f095dccd 100644 --- a/src/sscce-sequelize-7.ts +++ b/src/sscce-sequelize-7.ts @@ -1,4 +1,4 @@ -import { CreationOptional, DataTypes, InferAttributes, InferCreationAttributes, Model } from '@sequelize/core'; +import { CreationOptional, DataTypes, InferAttributes, InferCreationAttributes, Model, DialectOptions } from '@sequelize/core'; import { Attribute, NotNull } from '@sequelize/core/decorators-legacy'; import { createSequelize7Instance } from '../dev/create-sequelize-instance'; import { expect } from 'chai'; @@ -13,31 +13,96 @@ export const testingOnDialects = new Set(['mssql', 'sqlite', 'mysql', 'mariadb', 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, + underscored: true }, + dialect: 'sqlite3' }); - class Foo extends Model, InferCreationAttributes> { - declare id: CreationOptional; + class Parents extends Model {}; + Parents.init( + { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + name: DataTypes.TEXT, + }, + {sequelize}, + ); + + class Children extends Model {}; + Children.init( + { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + parentId: { + type: DataTypes.INTEGER, + references: { + model: Parents, + key: 'id' + } + } + }, + {sequelize} + + ) + + class GrandChildren extends Model {}; + GrandChildren.init( + { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + parentId: { + type: DataTypes.INTEGER, + references: { + model: Children, + key: 'id' + } + } + }, + {sequelize} + ); - @Attribute(DataTypes.TEXT) - @NotNull - declare name: string; - } + Parents.hasMany(Children) + Children.belongsTo(Parents) + Children.hasMany(GrandChildren) + GrandChildren.belongsTo(Children) - 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; - // 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; + const created = await Parents.create() + const {rows, count} = await Parents.findAndCountAll({ + include: { + model: Children, + required: false, + include: [{ + model: GrandChildren, + required: true, + }] + }, + limit: 1 + }) - console.log(await Foo.create({ name: 'TS foo' })); - expect(await Foo.count()).to.equal(1); + console.log(rows); + expect(created).to.not.be.undefined; + expect(created).to.not.be.null; + expect(count).to.equal(1); } From 590f92f6e21210da929ae5d8f83e0de401a4b8e8 Mon Sep 17 00:00:00 2001 From: Vincent Smith Date: Wed, 23 Jul 2025 11:49:02 -0400 Subject: [PATCH 2/5] Revert package --- package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index b4dd09a82..b54c66b62 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,6 @@ "type": "commonjs", "license": "MIT", "dependencies": { - "@sequelize/core": "alpha", "chai": "^4", "chai-as-promised": "^7", "chai-datetime": "^1", @@ -14,9 +13,9 @@ "cross-env": "^7", "fs-jetpack": "^4", "sequelize": "^6", + "@sequelize/core": "alpha", "sinon": "^13", - "sinon-chai": "^3", - "yarn": "^1.22.22" + "sinon-chai": "^3" }, "scripts": { "_test": "ts-node dev/runner.ts", From 06d7dccb91fd5f017c3d1847d2548ecec280bab0 Mon Sep 17 00:00:00 2001 From: Vincent Smith Date: Wed, 23 Jul 2025 11:51:49 -0400 Subject: [PATCH 3/5] Revert dev --- dev/create-sequelize-instance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/create-sequelize-instance.ts b/dev/create-sequelize-instance.ts index 5011c99a1..1ec6d6438 100644 --- a/dev/create-sequelize-instance.ts +++ b/dev/create-sequelize-instance.ts @@ -7,7 +7,7 @@ export function createSequelize6Instance(options?: Sequelize6Options): Sequelize return new Sequelize6(wrapOptions(options)); } -export function createSequelize7Instance(options?: Sequelize7Options): Sequelize7 { +export function createSequelize7Instance(options?: Sequelize7Options): Sequelize7 { // not compatible with node 10 const { Sequelize: Sequelize7Constructor } = require('@sequelize/core'); // @ts-expect-error -- wrapOptions expect sequelize 6. From c18b5230265592b0ba3b47bbe8c98d941b1ce284 Mon Sep 17 00:00:00 2001 From: Vincent Smith Date: Wed, 23 Jul 2025 11:52:10 -0400 Subject: [PATCH 4/5] Remove dialect --- src/sscce-sequelize-7.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sscce-sequelize-7.ts b/src/sscce-sequelize-7.ts index 4f095dccd..2c17124ba 100644 --- a/src/sscce-sequelize-7.ts +++ b/src/sscce-sequelize-7.ts @@ -22,7 +22,6 @@ export async function run() { timestamps: false, underscored: true }, - dialect: 'sqlite3' }); class Parents extends Model {}; From c684d347873674eeb24615ceeebab384050e3892 Mon Sep 17 00:00:00 2001 From: Vincent Smith Date: Wed, 23 Jul 2025 11:56:16 -0400 Subject: [PATCH 5/5] Assert on rows --- src/sscce-sequelize-6.ts | 1 + src/sscce-sequelize-7.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/sscce-sequelize-6.ts b/src/sscce-sequelize-6.ts index 78a48522b..1a592a9b0 100644 --- a/src/sscce-sequelize-6.ts +++ b/src/sscce-sequelize-6.ts @@ -100,6 +100,7 @@ GrandChildren.belongsTo(Children) expect(created).to.not.be.undefined; expect(created).to.not.be.null; expect(count).to.equal(1); + expect(rows.length).to.equal(1); } diff --git a/src/sscce-sequelize-7.ts b/src/sscce-sequelize-7.ts index 2c17124ba..a54a445e2 100644 --- a/src/sscce-sequelize-7.ts +++ b/src/sscce-sequelize-7.ts @@ -104,4 +104,5 @@ export async function run() { expect(created).to.not.be.undefined; expect(created).to.not.be.null; expect(count).to.equal(1); + expect(rows.length).to.equal(1); }