Skip to content
Advertisement

Typescript switch/case on string not maching when it should

I have a strange behavior on a switch statement that is supposed to check for possible values of a string.

I’m trying to develop a little parser and using TDD I managed to write (and test) a function that parses a single line at a time, resulting in the expected result for all my cases.

Now I’m developing a bigger function that parses a bunch of lines at once so what it does is essentially split these lines and call the function that parses one line at a time.

The strange behaviour happens when I’m checking a value:

parseLine(terrainLine: string): Terrain | Tile[] | Adventurer {
    const [lineType, ...lineData] = terrainLine.trim().split(' - ');

    switch (lineType) {
      case 'C':
        return Terrain.parseTerrain(lineData);

      case 'T':
        return Terrain.parseTreasures(lineData);

      case 'M':
        return [Terrain.parseMountain(lineData)];

      case 'A':
        return Terrain.parseAdventurer(lineData);

      default: {
        throw new TerrainError(
          `Unable to parse terrain tile with data: "${terrainLine}"`,
        );
      }
    }
  }

This function is tested and should be working properly with strings like 'C - 3 - 4' (this input was tested and passed) but when the following function makes a call, it does not work anymore and instead it triggers the default statement:

parse(terrainString: stirng): Terrain {
  const linesToParse = terrainString
      .split('n')
      .map((_) => _.trim()) // Get rid of spaces before and after interesting data
      .filter((_) => _.length && !_.startsWith('#')); // Get rid of empty lines && comments lines

  linesToParse.forEach((line) => {
      const parsed = Terrain.parseLine(line);
      // [...]
  }  

  // [...]
}

For reference, here are the tests I use:

// This one passes
it('should parse terrain lines right', () => {
  const terrainLine = 'C - 3 - 4';
  const expectedTerrain = new Terrain(3, 4);
  const parsed = parseLine(terrainLine);

  expect(parsed).toBeInstanceOf(Terrain);
  expect(parsed).toStrictEqual(expectedTerrain);
});

// This one doesn't
it('should accept valid terrains', () => {
  const terrainString = 'C​ - 3 - 4nM​ - 1 - 0nM​ - 2 - 1nT​ - 0 - 3 - 2nT​ - 1 - 3 - 3nA​ - Lara - 1 - 1 - S - AADADAGGAn';

  expect(() => {
    Terrain.parse(terrainString);
  }).not.toThrow();
});

Advertisement

Answer

As pointed out by @VLAZ, I had an invisible character of zero width when printed in my string which was causing this bug. Simply removing this character in the first place solved the problem.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement