UNPKG

@civ-clone/core-city-build

Version:

The repo contains the `CityBuild` and associated objects that deal with building items in `City`s.

164 lines (126 loc) 4.9 kB
import { Build, IBuildCriterion } from '../Rules/Build'; import { Horseman, Spearman, Warrior } from '@civ-clone/civ1-unit/Units'; import { Barracks, Granary, Temple, } from '@civ-clone/civ1-city-improvement/CityImprovements'; import { expect, use, spy } from 'chai'; import AvailableCityBuildItemsRegistry from '../AvailableCityBuildItemsRegistry'; import { BuildProgress } from '../Yields'; import Buildable from '../Buildable'; import BuildingCancelled from '../Rules/BulidingCancelled'; import BuildingComplete from '../Rules/BulidingComplete'; import CityBuild from '../CityBuild'; import Criterion from '@civ-clone/core-rule/Criterion'; import Effect from '@civ-clone/core-rule/Effect'; import RuleRegistry from '@civ-clone/core-rule/RuleRegistry'; import { buildCost } from '../Rules/BuildCost'; import { setUpCity } from '@civ-clone/civ1-city/tests/lib/setUpCity'; import * as spies from 'chai-spies'; use(spies); describe('CityBuild', (): void => { class Unit extends Buildable { public static build() { return new Unit(); } } it('should be possible to register well defined items', async () => { const availableBuildItemsRegistry = new AvailableCityBuildItemsRegistry(); availableBuildItemsRegistry.register( Horseman, Spearman, Warrior, Barracks, Granary, Temple ); }); it('should have expected initial state', async (): Promise<void> => { const cityBuild = new CityBuild(await setUpCity()); expect(cityBuild.progress().value()).equal(0); expect(cityBuild.cost().value()).equal(Infinity); expect(cityBuild.building()).null; }); it('should correctly use `Rule`s to determine the cost and availability of BuildItems', async (): Promise<void> => { const availableBuildItemsRegistry = new AvailableCityBuildItemsRegistry(), ruleRegistry = new RuleRegistry(), cityBuild = new CityBuild( await setUpCity(), availableBuildItemsRegistry, ruleRegistry ), effectSpy = spy(); ruleRegistry.register( new Build(new Effect((): IBuildCriterion => new Criterion(() => true))), new BuildingCancelled(new Effect(effectSpy)) ); expect(() => cityBuild.build(Unit)).throw(TypeError); availableBuildItemsRegistry.register(Unit); expect(() => cityBuild.build(Unit)).not.throw(TypeError); expect(cityBuild.cost().value()).not.finite; expect(cityBuild.building()!.item()).equal(Unit); availableBuildItemsRegistry.unregister(Unit); cityBuild.revalidate(); expect(effectSpy).called.once; }); it('should accept `BuildProgress` until the `cost` is reached', async (): Promise<void> => { const availableBuildItemsRegistry = new AvailableCityBuildItemsRegistry(), ruleRegistry = new RuleRegistry(), cityBuild = new CityBuild( await setUpCity(), availableBuildItemsRegistry, ruleRegistry ), effectSpy = spy(); ruleRegistry.register( new Build(new Effect((): IBuildCriterion => new Criterion(() => true))), ...buildCost(Unit, 10), new BuildingComplete(new Effect(effectSpy)) ); availableBuildItemsRegistry.register(Unit); cityBuild.build(Unit); expect(cityBuild.cost().value()).equal(10); expect(effectSpy).not.called.once; cityBuild.add(new BuildProgress(5)); cityBuild.check(); expect(effectSpy).not.called; expect(cityBuild.remaining()).equal(5); cityBuild.add(new BuildProgress(5)); cityBuild.check(); expect(effectSpy).called.once; }); it("should throw and error if a `Build` `Rule` doesn't return a `Criterion`", async (): Promise<void> => { const availableBuildItemsRegistry = new AvailableCityBuildItemsRegistry(), ruleRegistry = new RuleRegistry(), cityBuild = new CityBuild( await setUpCity(), availableBuildItemsRegistry, ruleRegistry ); ruleRegistry.register( new Build(new Effect(() => 0 as unknown as IBuildCriterion)) ); availableBuildItemsRegistry.register(Unit); expect(() => cityBuild.build(Unit)).throw(TypeError); }); it("should remove an item that's no longer available on `revalidate()`", async (): Promise<void> => { const availableBuildItemsRegistry = new AvailableCityBuildItemsRegistry(), ruleRegistry = new RuleRegistry(), cityBuild = new CityBuild( await setUpCity(), availableBuildItemsRegistry, ruleRegistry ); ruleRegistry.register( new Build(new Effect((): IBuildCriterion => new Criterion(() => true))), ...buildCost(Unit, 10) ); availableBuildItemsRegistry.register(Unit); cityBuild.build(Unit); expect(cityBuild.building()!.item()).equal(Unit); availableBuildItemsRegistry.unregister(Unit); cityBuild.revalidate(); expect(cityBuild.building()).null; }); });