<commit_before>import { StatBlock } from "../../common/StatBlock";
import { Encounter } from "../Encounter/Encounter";
import { InitializeSettings } from "../Settings/Settings";
import { buildEncounter } from "../test/buildEncounter";

function buildEncounterState() {
  const statBlock = { ...StatBlock.Default(), Name: "Goblin" };
  const oldEncounter = buildEncounter();
  oldEncounter.AddCombatantFromStatBlock(statBlock);
  oldEncounter.AddCombatantFromStatBlock(statBlock);
  const savedEncounter = oldEncounter.GetEncounterState();
  return savedEncounter;
}

describe("Index labeling", () => {
  let encounter: Encounter;
  beforeEach(() => {
    InitializeSettings();
    encounter = buildEncounter();
  });

  test("A lone combatant is not index labelled.", () => {
    const statBlock = { ...StatBlock.Default(), Name: "Goblin" };
    const combatant1 = encounter.AddCombatantFromStatBlock(statBlock);
    expect(combatant1.DisplayName()).toEqual("Goblin");
  });

  test("When multiple combatants are added with the same name, they should display index labels.", () => {
    const statBlock = { ...StatBlock.Default(), Name: "Goblin" };

    const combatant1 = encounter.AddCombatantFromStatBlock(statBlock);
    const combatant2 = encounter.AddCombatantFromStatBlock(statBlock);
    expect(combatant1.DisplayName()).toEqual("Goblin 1");
    expect(combatant2.DisplayName()).toEqual("Goblin 2");
  });

  test("When a combatant statblock name changes, it receives an index label if necessary", () => {
    const statBlock1 = { ...StatBlock.Default(), Name: "Goblin" };
    const statBlock2 = { ...StatBlock.Default(), Name: "Not Goblin" };

    const combatant1 = encounter.AddCombatantFromStatBlock(statBlock1);
    const combatant2 = encounter.AddCombatantFromStatBlock(statBlock2);
    combatant2.StatBlock(statBlock1);

    expect(combatant1.DisplayName()).toEqual("Goblin 1");
    expect(combatant2.DisplayName()).toEqual("Goblin 2");
  });

  test("When all combatants the same name are removed, index labelling should reset.", () => {
    const statBlock = { ...StatBlock.Default(), Name: "Goblin" };

    const combatant1 = encounter.AddCombatantFromStatBlock(statBlock);
    const combatant2 = encounter.AddCombatantFromStatBlock(statBlock);
    encounter.RemoveCombatant(combatant1);
    encounter.RemoveCombatant(combatant2);

    const newCombatant1 = encounter.AddCombatantFromStatBlock(statBlock);

    expect(newCombatant1.DisplayName()).toEqual("Goblin");

    const newCombatant2 = encounter.AddCombatantFromStatBlock(statBlock);

    expect(newCombatant1.DisplayName()).toEqual("Goblin 1");
    expect(newCombatant2.DisplayName()).toEqual("Goblin 2");
  });

  test("When a combatant is added from a saved encounter, it retains its saved index label", () => {
    const savedEncounter = buildEncounterState();
    const combatantStates = savedEncounter.Combatants;

    const combatant1 = encounter.AddCombatantFromState(combatantStates[0]);
    expect(combatant1.DisplayName()).toEqual("Goblin");

    const combatant2 = encounter.AddCombatantFromState(combatantStates[1]);

    expect(combatant1.DisplayName()).toEqual("Goblin 1");
    expect(combatant2.DisplayName()).toEqual("Goblin 2");
  });

  test("When a saved encounter is added twice, it relabels existing creatures", () => {
    const savedEncounter = buildEncounterState();
    const combatantStates = savedEncounter.Combatants;

    const combatant1 = encounter.AddCombatantFromState(combatantStates[0]);
    const combatant2 = encounter.AddCombatantFromState(combatantStates[1]);

    const combatant3 = encounter.AddCombatantFromState(combatantStates[0]);
    const combatant4 = encounter.AddCombatantFromState(combatantStates[1]);

    expect(combatant1.DisplayName()).toEqual("Goblin 1");
    expect(combatant2.DisplayName()).toEqual("Goblin 2");
    expect(combatant3.DisplayName()).toEqual("Goblin 3");
    expect(combatant4.DisplayName()).toEqual("Goblin 4");
  });

  test("When a labelled combatant is removed, its index label is not reused.", () => {
    const statBlock = { ...StatBlock.Default(), Name: "Goblin" };

    const combatant1 = encounter.AddCombatantFromStatBlock(statBlock);
    const combatant2 = encounter.AddCombatantFromStatBlock(statBlock);
    encounter.RemoveCombatant(combatant2);

    const combatant3 = encounter.AddCombatantFromStatBlock(statBlock);

    expect(combatant1.DisplayName()).toEqual("Goblin 1");
    expect(combatant2.DisplayName()).toEqual("Goblin 2");
    expect(combatant3.DisplayName()).toEqual("Goblin 3");
  });

  test("When a saved encounter is repeatedly added in waves, index labeling is consistent", () => {
    const savedEncounter = buildEncounterState();
    const combatantStates = savedEncounter.Combatants;

    const combatant1 = encounter.AddCombatantFromState(combatantStates[0]);
    const combatant2 = encounter.AddCombatantFromState(combatantStates[1]);

    encounter.RemoveCombatant(combatant2);

    const combatant3 = encounter.AddCombatantFromState(combatantStates[0]);
    const combatant4 = encounter.AddCombatantFromState(combatantStates[1]);

    expect(combatant1.DisplayName()).toEqual("Goblin 1");
    expect(combatant2.DisplayName()).toEqual("Goblin 2");
    expect(combatant3.DisplayName()).toEqual("Goblin 3");
    expect(combatant4.DisplayName()).toEqual("Goblin 4");
  });
});
<commit_msg>Add failing tests to repro labeling issue<commit_after>import { StatBlock } from "../../common/StatBlock";
import { Encounter } from "../Encounter/Encounter";
import { InitializeSettings } from "../Settings/Settings";
import { buildEncounter } from "../test/buildEncounter";

function buildEncounterState() {
  const statBlock = { ...StatBlock.Default(), Name: "Goblin" };
  const oldEncounter = buildEncounter();
  for (const initiative of [8, 10]) {
    const combatant = oldEncounter.AddCombatantFromStatBlock(statBlock);
    combatant.Initiative(initiative);
  }
  oldEncounter.EncounterFlow.StartEncounter();
  const savedEncounter = oldEncounter.GetEncounterState();
  return savedEncounter;
}

describe("Index labeling", () => {
  let encounter: Encounter;
  beforeEach(() => {
    InitializeSettings();
    encounter = buildEncounter();
  });

  test("A lone combatant is not index labelled.", () => {
    const statBlock = { ...StatBlock.Default(), Name: "Goblin" };
    const combatant1 = encounter.AddCombatantFromStatBlock(statBlock);
    expect(combatant1.DisplayName()).toEqual("Goblin");
  });

  test("When multiple combatants are added with the same name, they should display index labels.", () => {
    const statBlock = { ...StatBlock.Default(), Name: "Goblin" };

    const combatant1 = encounter.AddCombatantFromStatBlock(statBlock);
    const combatant2 = encounter.AddCombatantFromStatBlock(statBlock);
    expect(combatant1.DisplayName()).toEqual("Goblin 1");
    expect(combatant2.DisplayName()).toEqual("Goblin 2");
  });

  test("When a combatant statblock name changes, it receives an index label if necessary", () => {
    const statBlock1 = { ...StatBlock.Default(), Name: "Goblin" };
    const statBlock2 = { ...StatBlock.Default(), Name: "Not Goblin" };

    const combatant1 = encounter.AddCombatantFromStatBlock(statBlock1);
    const combatant2 = encounter.AddCombatantFromStatBlock(statBlock2);
    combatant2.StatBlock(statBlock1);

    expect(combatant1.DisplayName()).toEqual("Goblin 1");
    expect(combatant2.DisplayName()).toEqual("Goblin 2");
  });

  test("When all combatants the same name are removed, index labelling should reset.", () => {
    const statBlock = { ...StatBlock.Default(), Name: "Goblin" };

    const combatant1 = encounter.AddCombatantFromStatBlock(statBlock);
    const combatant2 = encounter.AddCombatantFromStatBlock(statBlock);
    encounter.RemoveCombatant(combatant1);
    encounter.RemoveCombatant(combatant2);

    const newCombatant1 = encounter.AddCombatantFromStatBlock(statBlock);

    expect(newCombatant1.DisplayName()).toEqual("Goblin");

    const newCombatant2 = encounter.AddCombatantFromStatBlock(statBlock);

    expect(newCombatant1.DisplayName()).toEqual("Goblin 1");
    expect(newCombatant2.DisplayName()).toEqual("Goblin 2");
  });

  test("When a combatant is added from a saved encounter, it retains its saved index label", () => {
    const savedEncounter = buildEncounterState();
    const combatantStates = savedEncounter.Combatants;

    const combatant1 = encounter.AddCombatantFromState(combatantStates[0]);
    expect(combatant1.DisplayName()).toEqual("Goblin");

    const combatant2 = encounter.AddCombatantFromState(combatantStates[1]);

    expect(combatant1.DisplayName()).toEqual("Goblin 1");
    expect(combatant2.DisplayName()).toEqual("Goblin 2");
  });

  test("When a saved encounter is added twice, it relabels existing creatures", () => {
    const savedEncounter = buildEncounterState();
    const combatantStates = savedEncounter.Combatants;

    const combatant1 = encounter.AddCombatantFromState(combatantStates[0]);
    const combatant2 = encounter.AddCombatantFromState(combatantStates[1]);

    const combatant3 = encounter.AddCombatantFromState(combatantStates[0]);
    const combatant4 = encounter.AddCombatantFromState(combatantStates[1]);

    expect(combatant1.DisplayName()).toEqual("Goblin 1");
    expect(combatant2.DisplayName()).toEqual("Goblin 2");
    expect(combatant3.DisplayName()).toEqual("Goblin 3");
    expect(combatant4.DisplayName()).toEqual("Goblin 4");
  });

  test("When a labelled combatant is removed, its index label is not reused.", () => {
    const statBlock = { ...StatBlock.Default(), Name: "Goblin" };

    const combatant1 = encounter.AddCombatantFromStatBlock(statBlock);
    const combatant2 = encounter.AddCombatantFromStatBlock(statBlock);
    encounter.RemoveCombatant(combatant2);

    const combatant3 = encounter.AddCombatantFromStatBlock(statBlock);

    expect(combatant1.DisplayName()).toEqual("Goblin 1");
    expect(combatant2.DisplayName()).toEqual("Goblin 2");
    expect(combatant3.DisplayName()).toEqual("Goblin 3");
  });

  test("When a saved encounter is repeatedly added in waves, index labeling is consistent", () => {
    const savedEncounter = buildEncounterState();
    const combatantStates = savedEncounter.Combatants;

    const combatant1 = encounter.AddCombatantFromState(combatantStates[0]);
    const combatant2 = encounter.AddCombatantFromState(combatantStates[1]);

    encounter.RemoveCombatant(combatant2);

    const combatant3 = encounter.AddCombatantFromState(combatantStates[0]);
    const combatant4 = encounter.AddCombatantFromState(combatantStates[1]);

    expect(combatant1.DisplayName()).toEqual("Goblin 1");
    expect(combatant2.DisplayName()).toEqual("Goblin 2");
    expect(combatant3.DisplayName()).toEqual("Goblin 3");
    expect(combatant4.DisplayName()).toEqual("Goblin 4");
  });

  test("When a saved encounter state is loaded, it keeps the correct index labels", () => {
    const encounterState = buildEncounterState();
    const newEncounter = buildEncounter();
    newEncounter.LoadEncounterState(encounterState, null);

    const combatantDisplayNames = newEncounter
      .Combatants()
      .map(c => c.DisplayName());
    expect(combatantDisplayNames).toContain("Goblin 2");
    expect(combatantDisplayNames).toContain("Goblin 1");
  });
});

{'fraction_non_alphanumeric': 0.13167416821110228, 'fraction_numerical': 0.015091342335186657, 'mean_word_length': 5.152008686210641, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3614872', 'n_tokens_mistral': 3447, 'n_tokens_neox': 3385, 'n_words': 646}