Build a Digital Pet Game - Build a Digital Pet Game

Title: Build a Digital Pet Game - PetMood enum tests (31-37) always fail regardless of implementation

Tell us what’s happening:

I’ve tried several different implementations of the PetMood enum (different casing — both HAPPY = 'HAPPY' and Happy = 'Happy' style — different export configurations, and different ways of displaying the mood in the UI), and tests 31–37 fail identically every single time:

  • Test 31: The PetMood enumerator should contain HAPPY.
  • Test 32: The PetMood enumerator should contain EXCITED.
  • Test 33: The PetMood enumerator should contain CONTENT.
  • Test 34: The PetMood enumerator should contain SAD’.
  • Test 35: The PetMood enumerator should contain TIRED.
  • Test 36: The PetMood enumerator should contain SICK.
  • Test 37: The PetMood enumerator should contain HUNGRY.

What’s odd is that the surrounding tests all pass consistently:

  • Test 30 (“there should be a PetMood enumerator”) passes.
  • Tests 38–45 (the Record<PetMood, string> mapping checks for each mood) all pass.

So the test runner clearly recognizes my PetMood enum and can verify a Record keyed by it — it’s specifically this “should contain X” group that never passes, no matter what I change about the enum’s declaration or how the mood is rendered in the DOM.

I also noticed test 34’s description has a stray character in it: should contain `SAD`'. (trailing apostrophe after the closing backtick) — this looks like it might be a typo in the test’s hint text itself.

Has anyone gotten tests 31–37 to pass, and if so, what was different about your PetMood declaration or how you used it? Or is this possibly a bug in the test suite for this lab?

Your code so far:

/* file: index.tsx */
const { useState, useEffect, useCallback } = React;

enum PetAction {
  EAT = 'EAT',
  PLAY = 'PLAY',
  SLEEP = 'SLEEP',
}

export enum PetMood {
  HAPPY = 'HAPPY',
  EXCITED = 'EXCITED',
  CONTENT = 'CONTENT',
  SAD = 'SAD',
  TIRED = 'TIRED',
  SICK = 'SICK',
  HUNGRY = 'HUNGRY',
}

const moodEmoji: Record<PetMood, string> = {
  [PetMood.HAPPY]: '😊',
  [PetMood.EXCITED]: '🤩',
  [PetMood.CONTENT]: '😌',
  [PetMood.SAD]: '😢',
  [PetMood.TIRED]: '😴',
  [PetMood.SICK]: '🤒',
  [PetMood.HUNGRY]: '🍖',
};

const clamp = (value: number): number => Math.max(0, Math.min(100, value));

function getMood(hunger: number, energy: number, happiness: number): PetMood {
  if (hunger > 70) return PetMood.HUNGRY;
  if (energy < 30) return PetMood.TIRED;
  if (happiness < 30) return PetMood.SAD;
  if (happiness > 80 && energy > 70) return PetMood.EXCITED;
  if (happiness > 60) return PetMood.HAPPY;
  return PetMood.CONTENT;
}

export const PetGame = () => {
  const [petName, setPetName] = useState('');
  const [started, setStarted] = useState(false);

  const [hunger, setHunger] = useState(0);
  const [energy, setEnergy] = useState(100);
  const [happiness, setHappiness] = useState(100);

  useEffect(() => {
    if (!started) return;

    const timer = setTimeout(() => {
      setHunger(100);
      setEnergy(100);
      setHappiness(0);
    }, 5000);

    return () => clearTimeout(timer);
  }, [started]);

  const startGame = (e: React.FormEvent<HTMLFormElement>): void => {
    e.preventDefault();

    const input = document.getElementById('pet-name') as HTMLInputElement;

    if (input && input.value.trim()) {
      setPetName(input.value.trim());
      setStarted(true);
    }
  };

  const performAction = useCallback((action: PetAction) => {
    switch (action) {
      case PetAction.EAT:
        setHunger((h) => clamp(h - 10));
        setEnergy((e) => clamp(e + 10));
        break;
      case PetAction.PLAY:
        setEnergy((e) => clamp(e - 10));
        setHappiness((h) => clamp(h + 10));
        break;
      case PetAction.SLEEP:
        setHunger((h) => clamp(h + 10));
        setEnergy((e) => clamp(e + 10));
        break;
    }
  }, []);

  const mood = getMood(hunger, energy, happiness);

  if (!started) {
    return (
      <form onSubmit={startGame}>
        <label htmlFor="pet-name">Name your pet</label>
        <input id="pet-name" type="text" />
        <button type="submit">Start Game</button>
      </form>
    );
  }

  return (
    <div>
      <div className="pet-name">{petName}</div>
      <div>{moodEmoji[mood]}</div>
      <div className="pet-mood">{mood}</div>

      <div className="stat">
        Hunger
        <span className="stat-value">{hunger}</span>
      </div>

      <div className="stat">
        Energy
        <span className="stat-value">{energy}</span>
      </div>

      <div className="stat">
        Happiness
        <span className="stat-value">{happiness}</span>
      </div>

      <button id="eat-action" onClick={() => performAction(PetAction.EAT)}>
        EAT
      </button>

      <button id="play-action" onClick={() => performAction(PetAction.PLAY)}>
        PLAY
      </button>

      <button id="sleep-action" onClick={() => performAction(PetAction.SLEEP)}>
        SLEEP
      </button>
    </div>
  );
};

Welcome to the forum @ajinkyasd29

If you have a question about a specific challenge as it relates to your written code for that challenge and need some help, click the Help button located on the challenge.

The Help button will create a new topic with all code you have written and include a link to the challenge also. You will still be able to ask any questions in the post before submitting it to the forum.

Happy coding

Welcome to the forum @ajinkyasd29,

There is the string enum and the numeric enum. Possible a numeric enum is expected?

Happy coding

Thanks for the tip about using a numeric enum instead of a string enum for PetMood — that was exactly the fix! Really appreciate it :folded_hands: