Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Import Functions to Resolve Circular Dependency Issues in Tests #1125

Merged
merged 3 commits into from
May 24, 2024

Conversation

Greenlamp2
Copy link
Collaborator

@Greenlamp2 Greenlamp2 commented May 19, 2024

What are the changes?

I've refactored the code by converting all anonymous functions executed during imports into named functions.
These named functions are now executed in the loading scene.

This change prevents crashes during tests caused by circular dependencies, which occur when anonymous functions are imported in an unpredictable order.

This refactoring is crucial because, for example, the biomes module crashes if the pokemon-evolution module isn't imported first, and the pokemon-evolution module crashes if the pokemon-forms module isn't imported first, and so on.

Why am I doing these changes?

This change is introduced to fix the circular dependency issues causing crashes during imports in tests. This improvement comes from the need to write better tests and ensure stable imports. The current state with anonymous functions executed at import leads to unpredictable behavior and crashes.

What did change?

Explicitly, the changes involve wrapping the previously anonymous functions into named functions. For example:

Before:

(function () {
  const statKeys = Object.keys(displayStats);

  for (const key of statKeys) {
    if (typeof displayStats[key] === "string") {
      let label = displayStats[key] as string;
      let hidden = false;
      if (label endsWith("?")) {
        label = label.slice(0, -1);
        hidden = true;
      }
      displayStats[key] = {
        label: label,
        sourceFunc: gameData => gameData.gameStats[key].toString(),
        hidden: hidden
      };
    } else if (displayStats[key] === null) {
      displayStats[key] = {
        sourceFunc: gameData => gameData.gameStats[key].toString()
      };
    }
    if (!(displayStats[key] as DisplayStat).label) {
      const splittableKey = key.replace(/([a-z]{2,})([A-Z]{1}(?:[^A-Z]|$))/g, "$1_$2");
      (displayStats[key] as DisplayStat).label = Utils.toReadableString(`${splittableKey[0].toUpperCase()}${splittableKey.slice(1)}`);
    }
  }
})();

After:

export function initStatsKeys() {
  const statKeys = Object.keys(displayStats);

  for (const key of statKeys) {
    if (typeof displayStats[key] === "string") {
      let label = displayStats[key] as string;
      let hidden = false;
      if (label endsWith("?")) {
        label = label.slice(0, -1);
        hidden = true.
      }
      displayStats[key] = {
        label: label,
        sourceFunc: gameData => gameData.gameStats[key].toString(),
        hidden: hidden
      };
    } else if (displayStats[key] === null) {
      displayStats[key] = {
        sourceFunc: gameData => gameData.gameStats[key].toString()
      };
    }
    if (!(displayStats[key] as DisplayStat).label) {
      const splittableKey = key.replace(/([a-z]{2,})([A-Z]{1}(?:[^A-Z]|$))/g, "$1_$2");
      (displayStats[key] as DisplayStat).label = Utils.toReadableString(`${splittableKey[0].toUpperCase()}${splittableKey.slice(1)}`);
    }
  }
}

This change was applied to the following files:

  • src/ui/game-stats-ui-handler.ts -> initStatsKeys()
  • src/data/pokemon-evolutions.ts -> initPokemonPrevolutions()
  • src/data/biomes.ts -> initBiomes()
  • src/data/egg-moves.ts -> initEggMoves()
  • src/data/pokemon-forms.ts -> initPokemonForms()

With these changes, we can now write tests like:

it("should create an enemypokemon with specified moveset", () => {
  const ennemyPokemon = new PokemonData({
    species: Species.MEWTWO,
    level: 100,
    moveset: [
      new PokemonMove(Moves.ACID),
      new PokemonMove(Moves.ACROBATICS),
      new PokemonMove(Moves.FOCUS_ENERGY),
    ]
  });
  expect(ennemyPokemon.moveset[0].moveId).toBe(Moves.ACID);
  expect(ennemyPokemon.moveset[1].moveId).toBe(Moves.ACROBATICS);
  expect(ennemyPokemon.moveset[2].moveId).toBe(Moves.FOCUS_ENERGY);
});

Without this fix, errors occur when importing. With this fix, no more errors are present.

Screenshots/Videos

Without this fix:
image

With this fix
image

How to test the changes?

To test these changes:

  1. Check out the branch.
  2. Import the mentionned files in the tests.
  3. Run some tests to ensure they pass without spitting unknown errors.

Checklist

  • Have I checked that there is no overlap with another PR?
  • Have I made sure the PR is self-contained and cannot be split into smaller PRs?
  • Have I provided a clear explanation of the changes?
  • Have I tested the changes (manually)?
  • Are the changes visual?
    • Have I provided screenshots/videos of the changes?

@bennybroseph bennybroseph added documentation Improvements or additions to documentation enhancement New feature or request labels May 19, 2024
@Greenlamp2 Greenlamp2 marked this pull request as draft May 23, 2024 15:24
@Greenlamp2 Greenlamp2 marked this pull request as ready for review May 23, 2024 22:19
…/fix_imports

# Conflicts:
#	src/battle-scene.ts
#	src/data/biomes.ts
@Greenlamp2 Greenlamp2 changed the title Tests - Fix imports to use them in tests Refactor Import Functions to Resolve Circular Dependency Issues in Tests May 24, 2024
Copy link
Collaborator

@brain-frog brain-frog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@brain-frog brain-frog merged commit c1a7df9 into pagefaultgames:main May 24, 2024
2 checks passed
@Greenlamp2 Greenlamp2 deleted the tests/fix_imports branch May 24, 2024 17:46
Icehawk78 added a commit to Icehawk78/pokerogue that referenced this pull request May 24, 2024
* main:
  init dialog call in the loading-scene (pagefaultgames#1331)
  Added a champion ribbon on enemy pokemon if they have a classic win. (pagefaultgames#881)
  Update encounter levels for some Pokémon
  refactor executed code while importing and initializing all of these in loading-scene (pagefaultgames#1125)
Icehawk78 added a commit to Icehawk78/pokerogue that referenced this pull request May 24, 2024
; By Greenlamp2 (4) and others
; Via GitHub
* main:
  Fixed champion ribbon boss segments. (pagefaultgames#1334)
  Acrobatics does not treat vitamins as held items (pagefaultgames#718)
  Fix Aftermath not working (pagefaultgames#1209)
  Implement Destiny Bond move (pagefaultgames#1104)
  init dialog call in the loading-scene (pagefaultgames#1331)
  Added a champion ribbon on enemy pokemon if they have a classic win. (pagefaultgames#881)
  Update encounter levels for some Pokémon
  refactor executed code while importing and initializing all of these in loading-scene (pagefaultgames#1125)
  Update pokemon.ts (pagefaultgames#1297)
  Make zh_CN translation easier to understand (pagefaultgames#1292)
  Update Chinese battle.ts and egg-list-ui-handler.ts (pagefaultgames#1314)
  Enforce Consistent Spacing with ESLint's space-before-blocks and keyword-spacing Rules (pagefaultgames#1308)
  added rule no-trailing-spaces (pagefaultgames#1307)
  Add BattleInfo to TargetSelectUiHandler to move when target selected (pagefaultgames#1255)
  Increases the Amount of Time Until a Reconnect up to a Maximum (pagefaultgames#1295)

; Conflicts:
;	src/ui/unavailable-modal-ui-handler.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants