Give residents identities and an ID card
Clicking a resident (or aiming the walk/fly crosshair at one and pressing E) selects them: they stop walking, glow pink with a wider halo, get a name tag above their head, and the sidebar shows a resident ID card instead of code. The card has a drawn head-and-shoulders portrait (eyes and hair in their colours), name, sex, age, occupation and employer, eye colour, hair colour, blood type, where they were last seen, an ID number and a barcode. people.js generates identities deterministically from the repository name and resident index using nymshift's England/Wales names and taxonomy tables, so the same resident is always the same person. Picking projects each figure to the screen and ignores residents hidden behind buildings. Tested for stability, table membership and sex/first-name consistency.
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { personFor, residentSeed, NAMES, OCCUPATIONS, EMPLOYERS, BLOOD_TYPES, EYE_COLOURS, HAIR_COLOURS } from '../web/people.js';
|
||||
|
||||
test('the same resident is always the same person', () => {
|
||||
const seed = residentSeed('prometheus', 17);
|
||||
assert.equal(seed, residentSeed('prometheus', 17));
|
||||
assert.deepEqual({ ...personFor(seed) }, { ...personFor(seed) });
|
||||
assert.equal(personFor(seed).name, personFor(seed).name);
|
||||
assert.notEqual(residentSeed('prometheus', 17), residentSeed('prometheus', 18));
|
||||
assert.notEqual(residentSeed('prometheus', 17), residentSeed('grafana', 17));
|
||||
});
|
||||
|
||||
test('identities come from the lookup tables and are internally consistent', () => {
|
||||
const sexes = new Set(), names = new Set();
|
||||
for (let i = 0; i < 500; i++) {
|
||||
const p = personFor(residentSeed('repo', i));
|
||||
sexes.add(p.sex); names.add(p.name);
|
||||
assert.ok(['Male', 'Female'].includes(p.sex));
|
||||
assert.ok((p.sex === 'Male' ? NAMES.male : NAMES.female).includes(p.firstName), `${p.firstName} matches ${p.sex}`);
|
||||
assert.ok(NAMES.surnames.includes(p.surname) && OCCUPATIONS.includes(p.occupation) && EMPLOYERS.includes(p.employer));
|
||||
assert.ok(BLOOD_TYPES.includes(p.bloodType) && EYE_COLOURS.includes(p.eyeColour) && HAIR_COLOURS.includes(p.hairColour));
|
||||
assert.ok(Number.isInteger(p.age) && p.age >= 18 && p.age <= 80);
|
||||
assert.match(p.id, /^CN-[0-9A-F]{8}$/);
|
||||
}
|
||||
assert.equal(sexes.size, 2);
|
||||
assert.ok(names.size > 300, `plenty of variety (${names.size} names)`);
|
||||
});
|
||||
Reference in New Issue
Block a user