mirror of
https://github.com/withastro/astro.git
synced 2025-02-03 22:29:08 -05:00
refactor: reference tests
This commit is contained in:
parent
8dd29061b4
commit
1620ed1003
1 changed files with 67 additions and 53 deletions
|
@ -1,10 +1,9 @@
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import { describe, it } from 'mocha';
|
import { describe, it } from 'mocha';
|
||||||
import { getCollectionChangeQueries } from '../../dist/core/cli/migration-queries.js';
|
import { getCollectionChangeQueries } from '../../dist/core/cli/migration-queries.js';
|
||||||
import { setCollectionsMeta } from '../../dist/core/integration/index.js';
|
import { field, defineCollection, collectionsSchema } from '../../dist/core/types.js';
|
||||||
import { field, defineCollection, collectionSchema } from '../../dist/core/types.js';
|
|
||||||
|
|
||||||
let User = defineCollection({
|
const BaseUser = defineCollection({
|
||||||
fields: {
|
fields: {
|
||||||
id: field.number({ primaryKey: true }),
|
id: field.number({ primaryKey: true }),
|
||||||
name: field.text(),
|
name: field.text(),
|
||||||
|
@ -14,27 +13,34 @@ let User = defineCollection({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let SentBox = defineCollection({
|
const BaseSentBox = defineCollection({
|
||||||
fields: {
|
fields: {
|
||||||
to: field.text(),
|
to: field.number(),
|
||||||
toName: field.text(),
|
toName: field.text(),
|
||||||
subject: field.text(),
|
subject: field.text(),
|
||||||
body: field.text(),
|
body: field.text(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set collection names for references to resolve.
|
|
||||||
// Avoid using collectionSchema.parse before this,
|
|
||||||
// since Zod will lose some object references.
|
|
||||||
setCollectionsMeta({ User, SentBox });
|
|
||||||
User = collectionSchema.parse(User);
|
|
||||||
SentBox = collectionSchema.parse(SentBox);
|
|
||||||
|
|
||||||
const defaultAmbiguityResponses = {
|
const defaultAmbiguityResponses = {
|
||||||
collectionRenames: {},
|
collectionRenames: {},
|
||||||
fieldRenames: {},
|
fieldRenames: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {import('../../dist/core/types.js').DBCollection} DBCollection
|
||||||
|
* @param {{ User: DBCollection, SentBox: DBCollection }} params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function resolveReferences(
|
||||||
|
{ User = BaseUser, SentBox = BaseSentBox } = {
|
||||||
|
User: BaseUser,
|
||||||
|
SentBox: BaseSentBox,
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
return collectionsSchema.parse({ User, SentBox });
|
||||||
|
}
|
||||||
|
|
||||||
function userChangeQueries(
|
function userChangeQueries(
|
||||||
oldCollection,
|
oldCollection,
|
||||||
newCollection,
|
newCollection,
|
||||||
|
@ -50,22 +56,24 @@ function userChangeQueries(
|
||||||
|
|
||||||
describe('reference queries', () => {
|
describe('reference queries', () => {
|
||||||
it('adds references with lossless table recreate', async () => {
|
it('adds references with lossless table recreate', async () => {
|
||||||
const SentBoxFinal = collectionSchema.parse(
|
const { SentBox: Initial } = resolveReferences();
|
||||||
defineCollection({
|
const { SentBox: Final } = resolveReferences({
|
||||||
|
SentBox: defineCollection({
|
||||||
fields: {
|
fields: {
|
||||||
...SentBox.fields,
|
...BaseSentBox.fields,
|
||||||
to: field.text({ references: () => User.fields.id }),
|
to: field.number({ references: () => BaseUser.fields.id }),
|
||||||
},
|
},
|
||||||
})
|
}),
|
||||||
);
|
});
|
||||||
|
|
||||||
const { queries } = await userChangeQueries(SentBox, SentBoxFinal);
|
const { queries } = await userChangeQueries(Initial, Final);
|
||||||
|
|
||||||
expect(queries[0]).to.not.be.undefined;
|
expect(queries[0]).to.not.be.undefined;
|
||||||
const tempTableName = getTempTableName(queries[0]);
|
const tempTableName = getTempTableName(queries[0]);
|
||||||
|
expect(tempTableName).to.not.be.undefined;
|
||||||
|
|
||||||
expect(queries).to.deep.equal([
|
expect(queries).to.deep.equal([
|
||||||
`CREATE TABLE \"${tempTableName}\" (_id INTEGER PRIMARY KEY, \"to\" text NOT NULL REFERENCES \"User\" (\"id\"), \"toName\" text NOT NULL, \"subject\" text NOT NULL, \"body\" text NOT NULL)`,
|
`CREATE TABLE \"${tempTableName}\" (_id INTEGER PRIMARY KEY, \"to\" integer NOT NULL REFERENCES \"User\" (\"id\"), \"toName\" text NOT NULL, \"subject\" text NOT NULL, \"body\" text NOT NULL)`,
|
||||||
`INSERT INTO \"${tempTableName}\" (\"_id\", \"to\", \"toName\", \"subject\", \"body\") SELECT \"_id\", \"to\", \"toName\", \"subject\", \"body\" FROM \"User\"`,
|
`INSERT INTO \"${tempTableName}\" (\"_id\", \"to\", \"toName\", \"subject\", \"body\") SELECT \"_id\", \"to\", \"toName\", \"subject\", \"body\" FROM \"User\"`,
|
||||||
'DROP TABLE "User"',
|
'DROP TABLE "User"',
|
||||||
`ALTER TABLE \"${tempTableName}\" RENAME TO \"User\"`,
|
`ALTER TABLE \"${tempTableName}\" RENAME TO \"User\"`,
|
||||||
|
@ -73,22 +81,24 @@ describe('reference queries', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('removes references with lossless table recreate', async () => {
|
it('removes references with lossless table recreate', async () => {
|
||||||
const SentBoxInitial = collectionSchema.parse(
|
const { SentBox: Initial } = resolveReferences({
|
||||||
defineCollection({
|
SentBox: defineCollection({
|
||||||
fields: {
|
fields: {
|
||||||
...SentBox.fields,
|
...BaseSentBox.fields,
|
||||||
to: field.text({ references: () => User.fields.id }),
|
to: field.number({ references: () => BaseUser.fields.id }),
|
||||||
},
|
},
|
||||||
})
|
}),
|
||||||
);
|
});
|
||||||
|
const { SentBox: Final } = resolveReferences();
|
||||||
|
|
||||||
const { queries } = await userChangeQueries(SentBoxInitial, SentBox);
|
const { queries } = await userChangeQueries(Initial, Final);
|
||||||
|
|
||||||
expect(queries[0]).to.not.be.undefined;
|
expect(queries[0]).to.not.be.undefined;
|
||||||
const tempTableName = getTempTableName(queries[0]);
|
const tempTableName = getTempTableName(queries[0]);
|
||||||
|
expect(tempTableName).to.not.be.undefined;
|
||||||
|
|
||||||
expect(queries).to.deep.equal([
|
expect(queries).to.deep.equal([
|
||||||
`CREATE TABLE \"${tempTableName}\" (_id INTEGER PRIMARY KEY, \"to\" text NOT NULL, \"toName\" text NOT NULL, \"subject\" text NOT NULL, \"body\" text NOT NULL)`,
|
`CREATE TABLE \"${tempTableName}\" (_id INTEGER PRIMARY KEY, \"to\" integer NOT NULL, \"toName\" text NOT NULL, \"subject\" text NOT NULL, \"body\" text NOT NULL)`,
|
||||||
`INSERT INTO \"${tempTableName}\" (\"_id\", \"to\", \"toName\", \"subject\", \"body\") SELECT \"_id\", \"to\", \"toName\", \"subject\", \"body\" FROM \"User\"`,
|
`INSERT INTO \"${tempTableName}\" (\"_id\", \"to\", \"toName\", \"subject\", \"body\") SELECT \"_id\", \"to\", \"toName\", \"subject\", \"body\" FROM \"User\"`,
|
||||||
'DROP TABLE "User"',
|
'DROP TABLE "User"',
|
||||||
`ALTER TABLE \"${tempTableName}\" RENAME TO \"User\"`,
|
`ALTER TABLE \"${tempTableName}\" RENAME TO \"User\"`,
|
||||||
|
@ -96,21 +106,22 @@ describe('reference queries', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not use ADD COLUMN when adding optional column with reference', async () => {
|
it('does not use ADD COLUMN when adding optional column with reference', async () => {
|
||||||
const SentBoxFinal = collectionSchema.parse(
|
const { SentBox: Initial } = resolveReferences();
|
||||||
defineCollection({
|
const { SentBox: Final } = resolveReferences({
|
||||||
|
SentBox: defineCollection({
|
||||||
fields: {
|
fields: {
|
||||||
...SentBox.fields,
|
...BaseSentBox.fields,
|
||||||
from: field.text({ references: () => User.fields.id, optional: true }),
|
from: field.number({ references: () => BaseUser.fields.id, optional: true }),
|
||||||
},
|
},
|
||||||
})
|
}),
|
||||||
);
|
});
|
||||||
|
|
||||||
const { queries } = await userChangeQueries(SentBox, SentBoxFinal);
|
const { queries } = await userChangeQueries(Initial, Final);
|
||||||
expect(queries[0]).to.not.be.undefined;
|
expect(queries[0]).to.not.be.undefined;
|
||||||
const tempTableName = getTempTableName(queries[0]);
|
const tempTableName = getTempTableName(queries[0]);
|
||||||
|
|
||||||
expect(queries).to.deep.equal([
|
expect(queries).to.deep.equal([
|
||||||
`CREATE TABLE \"${tempTableName}\" (_id INTEGER PRIMARY KEY, \"to\" text NOT NULL, \"toName\" text NOT NULL, \"subject\" text NOT NULL, \"body\" text NOT NULL, \"from\" text REFERENCES \"User\" (\"id\"))`,
|
`CREATE TABLE \"${tempTableName}\" (_id INTEGER PRIMARY KEY, \"to\" integer NOT NULL, \"toName\" text NOT NULL, \"subject\" text NOT NULL, \"body\" text NOT NULL, \"from\" integer REFERENCES \"User\" (\"id\"))`,
|
||||||
`INSERT INTO \"${tempTableName}\" (\"_id\", \"to\", \"toName\", \"subject\", \"body\") SELECT \"_id\", \"to\", \"toName\", \"subject\", \"body\" FROM \"User\"`,
|
`INSERT INTO \"${tempTableName}\" (\"_id\", \"to\", \"toName\", \"subject\", \"body\") SELECT \"_id\", \"to\", \"toName\", \"subject\", \"body\" FROM \"User\"`,
|
||||||
'DROP TABLE "User"',
|
'DROP TABLE "User"',
|
||||||
`ALTER TABLE \"${tempTableName}\" RENAME TO \"User\"`,
|
`ALTER TABLE \"${tempTableName}\" RENAME TO \"User\"`,
|
||||||
|
@ -118,31 +129,34 @@ describe('reference queries', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('adds and updates foreign key with lossless table recreate', async () => {
|
it('adds and updates foreign key with lossless table recreate', async () => {
|
||||||
const SentBoxFinal = collectionSchema.parse(
|
const { SentBox: InitialWithoutFK } = resolveReferences();
|
||||||
defineCollection({
|
const { SentBox: InitialWithDifferentFK } = resolveReferences({
|
||||||
...SentBox,
|
SentBox: defineCollection({
|
||||||
|
...BaseSentBox,
|
||||||
|
foreignKeys: [{ fields: ['to'], references: () => [BaseUser.fields.id] }],
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
const { SentBox: Final } = resolveReferences({
|
||||||
|
SentBox: defineCollection({
|
||||||
|
...BaseSentBox,
|
||||||
foreignKeys: [
|
foreignKeys: [
|
||||||
{ fields: ['to', 'toName'], references: () => [User.fields.id, User.fields.name] },
|
{
|
||||||
|
fields: ['to', 'toName'],
|
||||||
|
references: () => [BaseUser.fields.id, BaseUser.fields.name],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
})
|
}),
|
||||||
);
|
});
|
||||||
|
|
||||||
const SentBoxWithDifferentFK = collectionSchema.parse(
|
|
||||||
defineCollection({
|
|
||||||
...SentBox,
|
|
||||||
foreignKeys: [{ fields: ['to'], references: () => [User.fields.id] }],
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
const expected = (tempTableName) => [
|
const expected = (tempTableName) => [
|
||||||
`CREATE TABLE \"${tempTableName}\" (_id INTEGER PRIMARY KEY, \"to\" text NOT NULL, \"toName\" text NOT NULL, \"subject\" text NOT NULL, \"body\" text NOT NULL, FOREIGN KEY (\"to\", \"toName\") REFERENCES \"User\"(\"id\", \"name\"))`,
|
`CREATE TABLE \"${tempTableName}\" (_id INTEGER PRIMARY KEY, \"to\" integer NOT NULL, \"toName\" text NOT NULL, \"subject\" text NOT NULL, \"body\" text NOT NULL, FOREIGN KEY (\"to\", \"toName\") REFERENCES \"User\"(\"id\", \"name\"))`,
|
||||||
`INSERT INTO \"${tempTableName}\" (\"_id\", \"to\", \"toName\", \"subject\", \"body\") SELECT \"_id\", \"to\", \"toName\", \"subject\", \"body\" FROM \"User\"`,
|
`INSERT INTO \"${tempTableName}\" (\"_id\", \"to\", \"toName\", \"subject\", \"body\") SELECT \"_id\", \"to\", \"toName\", \"subject\", \"body\" FROM \"User\"`,
|
||||||
'DROP TABLE "User"',
|
'DROP TABLE "User"',
|
||||||
`ALTER TABLE \"${tempTableName}\" RENAME TO \"User\"`,
|
`ALTER TABLE \"${tempTableName}\" RENAME TO \"User\"`,
|
||||||
];
|
];
|
||||||
|
|
||||||
const addedForeignKey = await userChangeQueries(SentBox, SentBoxFinal);
|
const addedForeignKey = await userChangeQueries(InitialWithoutFK, Final);
|
||||||
const updatedForeignKey = await userChangeQueries(SentBoxWithDifferentFK, SentBoxFinal);
|
const updatedForeignKey = await userChangeQueries(InitialWithDifferentFK, Final);
|
||||||
|
|
||||||
expect(addedForeignKey.queries[0]).to.not.be.undefined;
|
expect(addedForeignKey.queries[0]).to.not.be.undefined;
|
||||||
expect(updatedForeignKey.queries[0]).to.not.be.undefined;
|
expect(updatedForeignKey.queries[0]).to.not.be.undefined;
|
||||||
|
@ -157,7 +171,7 @@ describe('reference queries', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/** @param {string} query */
|
/** @param {string | undefined} query */
|
||||||
function getTempTableName(query) {
|
function getTempTableName(query) {
|
||||||
return query.match(/User_([a-z0-9]+)/)?.[0];
|
return query.match(/User_([a-z0-9]+)/)?.[0];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue