forge/
encounter_fixture.rs1use anyhow::{Context, Result};
4#[cfg(test)]
5use googletest::{Result as GtestResult, prelude::*};
6use wowlab_types::sim::EncounterDefinition;
7
8#[derive(Clone, Copy, Debug, Eq, PartialEq, clap::ValueEnum)]
9#[value(rename_all = "snake_case")]
10#[non_exhaustive]
11pub(crate) enum EncounterFixture {
12 TwoTargetPack,
13 BossAddWave,
14 TwoPullDungeon,
15 SpatialShowcase,
17}
18
19impl EncounterFixture {
20 #[must_use]
21 pub(crate) const fn slug(self) -> &'static str {
22 match self {
23 Self::TwoTargetPack => "two_target_pack",
24 Self::BossAddWave => "boss_add_wave",
25 Self::TwoPullDungeon => "two_pull_dungeon",
26 Self::SpatialShowcase => "spatial_showcase",
27 }
28 }
29
30 pub(crate) fn definition(self) -> Result<EncounterDefinition> {
31 let definition: EncounterDefinition = toml::from_str(self.source())
32 .with_context(|| format!("failed to parse encounter fixture '{}'", self.slug()))?;
33
34 definition
35 .validate()
36 .with_context(|| format!("invalid encounter fixture '{}'", self.slug()))?;
37
38 Ok(definition)
39 }
40
41 const fn source(self) -> &'static str {
42 match self {
43 Self::TwoTargetPack => {
44 include_str!("../../engine/tests/fixtures/encounters/two_target_pack.toml")
45 }
46 Self::BossAddWave => {
47 include_str!("../../engine/tests/fixtures/encounters/boss_add_wave.toml")
48 }
49 Self::TwoPullDungeon => {
50 include_str!("../../engine/tests/fixtures/encounters/two_pull_dungeon.toml")
51 }
52 Self::SpatialShowcase => {
53 include_str!("../fixtures/encounters/spatial_showcase.toml")
54 }
55 }
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[gtest]
64 fn phase_eight_fixtures_parse_with_stable_dense_identities() -> GtestResult<()> {
65 let fixtures = [
66 (EncounterFixture::TwoTargetPack, 2, 1, 1),
67 (EncounterFixture::BossAddWave, 3, 3, 1),
68 (EncounterFixture::TwoPullDungeon, 2, 2, 2),
69 ];
70
71 for (fixture, enemies, groups, pulls) in fixtures {
72 let definition = fixture.definition().or_fail()?;
73
74 verify_that!(definition.enemies.len(), eq(enemies))?;
75 verify_that!(definition.groups.len(), eq(groups))?;
76 verify_that!(definition.pulls.len(), eq(pulls))?;
77
78 for (index, enemy) in definition.enemies.iter().enumerate() {
79 verify_that!(enemy.id.as_usize(), eq(index))?;
80 }
81 }
82
83 Ok(())
84 }
85
86 #[gtest]
87 fn fixture_slugs_match_the_phase_eight_filenames() -> GtestResult<()> {
88 verify_that!(
89 EncounterFixture::TwoTargetPack.slug(),
90 eq("two_target_pack")
91 )?;
92 verify_that!(EncounterFixture::BossAddWave.slug(), eq("boss_add_wave"))?;
93 verify_that!(
94 EncounterFixture::TwoPullDungeon.slug(),
95 eq("two_pull_dungeon")
96 )?;
97
98 Ok(())
99 }
100}