diff --git a/src/factions/factionClass.ts b/src/factions/factionClass.ts index f66f67c13..5b1e44d41 100644 --- a/src/factions/factionClass.ts +++ b/src/factions/factionClass.ts @@ -1,9 +1,11 @@ +import { uniq } from 'lodash' import { TGrandAlliances } from 'meta/alliances' import { TSupportedFaction } from 'meta/factions' import { TRuleSource } from 'meta/rule_sources' import { TSubfactionArmy } from 'types/army' -import { TEffects } from 'types/data' -import { TItemDescriptions } from './factionTypes' +import { SELECTION_TYPES, TEffects } from 'types/data' +import { TSelectionTypes } from 'types/selections' +import { TItemDescriptions, TItemKey } from './factionTypes' import { getAggregateArmy, temporaryAdapter } from './temporaryAdapter' /** @@ -54,6 +56,28 @@ export class Faction< a[subFactionName] = temporaryAdapter(this.SubFactions[subFactionName], subFactionName, this.flavorLabel) return a }, {} as Record) + + this.checkForDataEntryErrors() + } + + /** Throw an error if we've got bad data (this will discover bad data entry) */ + private checkForDataEntryErrors = () => { + const validSelectionKeys: TItemKey[] = [...SELECTION_TYPES, 'allied_units'] + + this.subFactionKeys.forEach(k => { + const allKeys = uniq([ + ...Object.keys(this.SubFactions[k]?.available ?? {}), + ...Object.keys(this.SubFactions[k]?.mandatory ?? {}), + ]) as TSelectionTypes[] + + allKeys.forEach(selection => { + if (!validSelectionKeys.includes(selection)) { + throw new Error( + `${this.factionName} subfaction ${k} has an invalid/unknown key: ${selection}. Please check your data in this faction's subfactions.ts file` + ) + } + }) + }) } } diff --git a/src/factions/skaven/subfactions.ts b/src/factions/skaven/subfactions.ts index 0936b2e1f..18fbb9784 100644 --- a/src/factions/skaven/subfactions.ts +++ b/src/factions/skaven/subfactions.ts @@ -23,7 +23,7 @@ const subFactions = { endless_spells: [EndlessSpells], flavors: [Flavors], grand_strategies: [GrandStrategies], - Prayers: [Prayers], + prayers: [Prayers], scenery: [Scenery], spells: [Spells], units: [Units], diff --git a/src/tests/getArmy.test.ts b/src/tests/getArmy.test.ts index 9a6ee4b5e..cfc34847b 100644 --- a/src/tests/getArmy.test.ts +++ b/src/tests/getArmy.test.ts @@ -2,6 +2,7 @@ import { GenericEndlessSpells, GenericTriumphs } from 'generic_rules' import { sortBy } from 'lodash' import { ORDER } from 'meta/alliances' import { BEASTS_OF_CHAOS, SERAPHON, SYLVANETH } from 'meta/factions' +import { getFactionList } from 'meta/faction_list' import { IArmy } from 'types/army' import { getAllianceItems } from 'utils/getArmy/getAllianceItems' import { getArmy } from 'utils/getArmy/getArmy' @@ -49,3 +50,9 @@ describe('getArmy', () => { expect(shouldNotHaveThisUnit).toBeUndefined() }) }) + +describe('getFactionList', () => { + it('should not throw errors when using getFactionList', () => { + expect(getFactionList).not.toThrow() + }) +}) diff --git a/src/types/data.ts b/src/types/data.ts index 28763577c..faf453779 100644 --- a/src/types/data.ts +++ b/src/types/data.ts @@ -41,6 +41,25 @@ export const ENTRY_PROPERTIES: TEntryProperties[] = [ 'unit', ] +export const SELECTION_TYPES: TSelectionTypes[] = [ + 'artifacts', + 'battalions', + 'command_abilities', + 'command_traits', + 'core_rules', + 'endless_spells', + 'flavors', + 'grand_strategies', + 'incarnates', + 'monstrous_rampages', + 'mount_traits', + 'prayers', + 'scenery', + 'spells', + 'triumphs', + 'units', +] + export const lowerToUpperLookup: Record = { artifacts: 'Artifacts', battalions: 'Battalions',