129 lines
4.6 KiB
TypeScript
129 lines
4.6 KiB
TypeScript
import { describe, it, expect } from 'bun:test';
|
|
import { World } from '@common/rpg/core/world';
|
|
import { Reputation, Factions } from '@common/rpg/components/faction';
|
|
import { resolveVariables } from '@common/rpg/utils/variables';
|
|
|
|
function world() { return new World(); }
|
|
|
|
describe('FactionMember', () => {
|
|
it('join() adds membership, isMember() returns true', () => {
|
|
const w = world();
|
|
const e = w.createEntity();
|
|
Factions.join(e, 'guards');
|
|
expect(Factions.isMember(e, 'guards')).toBeTrue();
|
|
});
|
|
|
|
it('leave() removes membership, isMember() returns false', () => {
|
|
const w = world();
|
|
const e = w.createEntity();
|
|
Factions.join(e, 'guards');
|
|
Factions.leave(e, 'guards');
|
|
expect(Factions.isMember(e, 'guards')).toBeFalse();
|
|
});
|
|
|
|
it('isMember() returns false when entity has no FactionMember', () => {
|
|
const w = world();
|
|
const e = w.createEntity();
|
|
expect(Factions.isMember(e, 'guards')).toBeFalse();
|
|
});
|
|
|
|
it('getFactions() returns all factionIds', () => {
|
|
const w = world();
|
|
const e = w.createEntity();
|
|
Factions.join(e, 'guards');
|
|
Factions.join(e, 'merchants');
|
|
expect(Factions.getFactions(e).sort()).toEqual(['guards', 'merchants']);
|
|
});
|
|
|
|
it('member variable resolves on world', () => {
|
|
const w = world();
|
|
const e = w.createEntity('player');
|
|
Factions.join(e, 'guards');
|
|
expect(resolveVariables(w)['player.FactionMember.guards']).toBeTrue();
|
|
});
|
|
});
|
|
|
|
describe('Reputation', () => {
|
|
it('getReputation() returns 0 when no component', () => {
|
|
const w = world();
|
|
const e = w.createEntity();
|
|
expect(Factions.getReputation(e, 'guards')).toBe(0);
|
|
});
|
|
|
|
it('setReputation() creates component on first call', () => {
|
|
const w = world();
|
|
const e = w.createEntity();
|
|
Factions.setReputation(e, 'guards', 50);
|
|
expect(Factions.getReputation(e, 'guards')).toBe(50);
|
|
});
|
|
|
|
it('setReputation() updates score on second call without duplicate component', () => {
|
|
const w = world();
|
|
const e = w.createEntity();
|
|
Factions.setReputation(e, 'guards', 50);
|
|
Factions.setReputation(e, 'guards', 75);
|
|
expect(Factions.getReputation(e, 'guards')).toBe(75);
|
|
expect(e.getAll(Reputation).length).toBe(1);
|
|
});
|
|
|
|
it('adjustReputation() adds delta from zero default', () => {
|
|
const w = world();
|
|
const e = w.createEntity();
|
|
Factions.adjustReputation(e, 'guards', 20);
|
|
expect(Factions.getReputation(e, 'guards')).toBe(20);
|
|
});
|
|
|
|
it('adjustReputation() accumulates correctly', () => {
|
|
const w = world();
|
|
const e = w.createEntity();
|
|
Factions.adjustReputation(e, 'guards', 20);
|
|
Factions.adjustReputation(e, 'guards', -5);
|
|
expect(Factions.getReputation(e, 'guards')).toBe(15);
|
|
});
|
|
|
|
it('Reputation component adjust() mutates score', () => {
|
|
const w = world();
|
|
const e = w.createEntity();
|
|
Factions.setReputation(e, 'guards', 10);
|
|
const comp = e.get(Reputation, (c) => c.factionId == 'guards')!;
|
|
comp.adjust(30);
|
|
expect(comp.score).toBe(40);
|
|
});
|
|
|
|
it('score variable resolves on world', () => {
|
|
const w = world();
|
|
const e = w.createEntity('player');
|
|
Factions.setReputation(e, 'guards', 50);
|
|
expect(resolveVariables(w)['player.Reputation.guards']).toBe(50);
|
|
});
|
|
});
|
|
|
|
describe('Factions.getReputationBetween', () => {
|
|
it('returns null when target has no factions', () => {
|
|
const w = world();
|
|
const observer = w.createEntity();
|
|
const target = w.createEntity();
|
|
expect(Factions.getReputationBetween(observer, target)).toBeNull();
|
|
});
|
|
|
|
it("returns observer's rep with target's sole faction", () => {
|
|
const w = world();
|
|
const observer = w.createEntity();
|
|
const target = w.createEntity();
|
|
Factions.join(target, 'guards');
|
|
Factions.setReputation(observer, 'guards', 40);
|
|
expect(Factions.getReputationBetween(observer, target)).toBe(40);
|
|
});
|
|
|
|
it('returns the minimum when target belongs to multiple factions', () => {
|
|
const w = world();
|
|
const observer = w.createEntity();
|
|
const target = w.createEntity();
|
|
Factions.join(target, 'guards');
|
|
Factions.join(target, 'bandits');
|
|
Factions.setReputation(observer, 'guards', 60);
|
|
Factions.setReputation(observer, 'bandits', -30);
|
|
expect(Factions.getReputationBetween(observer, target)).toBe(-30);
|
|
});
|
|
});
|