Entkopple Partnersuche vom Altersabstand und entferne garantierte Schwangerschaften
All checks were successful
Deploy to production / deploy (push) Successful in 2m41s
All checks were successful
Deploy to production / deploy (push) Successful in 2m41s
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import test from 'node:test';
|
||||
import { Sequelize } from 'sequelize';
|
||||
import { Sequelize, DataTypes } from 'sequelize';
|
||||
import migration from '../migrations-active/20261104000000-add-character-development-ages.cjs';
|
||||
import { getCharacterDevelopment, hasReachedFertility } from '../utils/falukant/characterDevelopment.js';
|
||||
import { buildPartnerCandidateQuery } from '../utils/falukant/partnerCandidates.js';
|
||||
|
||||
test('development follows each character, independently of the marriage age', () => {
|
||||
const early = { pubertyStartAge: 10, fertileFromAge: 13 };
|
||||
@@ -71,6 +72,25 @@ test('database migration, persistence and daemon conception paths', {
|
||||
await assert.rejects(db.query(`INSERT INTO falukant_data.character
|
||||
(puberty_start_age, fertile_from_age) VALUES (12, 11)`));
|
||||
|
||||
await t.test('partner candidates have a minimum age without age-gap or creation-age restrictions', async () => {
|
||||
const [inserted] = await db.query(`INSERT INTO falukant_data.character (gender, birthdate)
|
||||
VALUES ('male', CURRENT_DATE - INTERVAL '65 days'),
|
||||
('male', CURRENT_DATE - INTERVAL '10 days' + INTERVAL '12 hours'),
|
||||
('male', CURRENT_DATE - INTERVAL '9 days')
|
||||
RETURNING id`);
|
||||
const Candidate = db.define('DevelopmentPartnerCandidate', {
|
||||
id: { type: DataTypes.INTEGER, primaryKey: true },
|
||||
gender: DataTypes.STRING,
|
||||
birthdate: DataTypes.DATE,
|
||||
regionId: { type: DataTypes.INTEGER, field: 'region_id' },
|
||||
titleOfNobility: { type: DataTypes.INTEGER, field: 'title_of_nobility' },
|
||||
}, { schema: 'falukant_data', tableName: 'character', timestamps: false });
|
||||
const rows = await Candidate.findAll(buildPartnerCandidateQuery({
|
||||
characterId: 1, gender: 'female', regionId: 1, titleId: 1, minimumAge: 10,
|
||||
}));
|
||||
assert.deepEqual(rows.map(c => c.id).sort((a, b) => a - b), [inserted[0].id, inserted[1].id]);
|
||||
});
|
||||
|
||||
await t.test('repeating the migration preserves all existing character data', async () => {
|
||||
const [saved] = await db.query('SELECT * FROM falukant_data.character ORDER BY id');
|
||||
await migration.up(qi);
|
||||
@@ -100,11 +120,11 @@ test('database migration, persistence and daemon conception paths', {
|
||||
skip: !process.env.DAEMON_SQL_PATH,
|
||||
}, async (t) => {
|
||||
const source = await readFile(process.env.DAEMON_SQL_PATH, 'utf8');
|
||||
const sql = (name) => {
|
||||
const sql = (name, randomRoll = 0) => {
|
||||
const match = source.match(new RegExp(`pub const ${name}: &str = r#"([\\s\\S]*?)"#;`));
|
||||
assert.ok(match, name);
|
||||
// Remove chance from these eligibility tests only.
|
||||
return match[1].replaceAll('random()', '0.0');
|
||||
return match[1].replaceAll('random()', `${randomRoll}::double precision`);
|
||||
};
|
||||
await db.query(`
|
||||
TRUNCATE falukant_data.character RESTART IDENTITY;
|
||||
@@ -154,6 +174,29 @@ test('database migration, persistence and daemon conception paths', {
|
||||
}
|
||||
}
|
||||
}
|
||||
await t.test('marriage, engagement and every lover role use exactly fifty percent', async () => {
|
||||
for (const [name, type, role] of [
|
||||
['QUERY_TRY_MARRIAGE_CONCEPTION_UPDATE', 1, null],
|
||||
['QUERY_GET_LEGACY_MARRIAGE_INSTANT_PREGNANCY_CANDIDATES', 1, null],
|
||||
['QUERY_GET_LOVER_PREGNANCY_CANDIDATES', 3, null],
|
||||
...['secret_affair', 'lover', 'mistress_or_favorite'].map(role => ['QUERY_GET_LOVER_PREGNANCY_CANDIDATES', 2, role]),
|
||||
]) {
|
||||
for (const [roll, expected] of [[0.499, true], [0.5, false], [0.99, false]]) {
|
||||
await db.query(`UPDATE falukant_data.character SET birthdate = CURRENT_DATE - INTERVAL '20 days', pregnancy_due_at = NULL;
|
||||
UPDATE falukant_data.relationship SET relationship_type_id = :type, marriage_pregnancy_due_at = NULL;
|
||||
UPDATE falukant_data.relationship_state SET lover_role = :role, affection = 80, visibility = 80`, {
|
||||
replacements: { type, role },
|
||||
});
|
||||
const [rows] = await db.query(sql(name, roll));
|
||||
if (name === 'QUERY_TRY_MARRIAGE_CONCEPTION_UPDATE') {
|
||||
const [[row]] = await db.query('SELECT marriage_pregnancy_due_at FROM falukant_data.relationship');
|
||||
assert.equal(row.marriage_pregnancy_due_at != null, expected, `${name}/${role}/${roll}`);
|
||||
} else {
|
||||
assert.equal(rows.length > 0, expected, `${name}/${role}/${roll}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
await t.test('engaged couples need no lover maintenance and retain their relationship', async () => {
|
||||
const candidates = () => db.query(sql('QUERY_GET_LOVER_PREGNANCY_CANDIDATES')).then(([rows]) => rows);
|
||||
await db.query(`UPDATE falukant_data.character SET birthdate = CURRENT_DATE - INTERVAL '13 days',
|
||||
|
||||
Reference in New Issue
Block a user