I encountered an unusual issue with a switch
statement designed to handle different values of a string.
While working on a parser and utilizing TDD, I successfully created and tested a function that parses individual lines accurately for all scenarios.
My current task involves developing a larger function capable of parsing multiple lines at once. This new function essentially divides the input into separate lines and then calls the single-line parsing function.
The problem arises during value checking:
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}"`,
);
}
}
}
Although this function is thoroughly tested and functions correctly with strings like 'C - 3 - 4'
, it encounters issues when invoked by the following function, triggering the default
case instead:
parse(terrainString: stirng): Terrain {
const linesToParse = terrainString
.split('\n')
.map((_) => _.trim()) // Remove leading and trailing spaces
.filter((_) => _.length && !_.startsWith('#')); // Exclude empty and comment lines
linesToParse.forEach((line) => {
const parsed = Terrain.parseLine(line);
// [...]
}
// [...]
}
Here are the test cases for reference:
// Successful test
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);
});
// Unsuccessful test
it('should accept valid terrains', () => {
const terrainString = 'C - 3 - 4\nM - 1 - 0\nM - 2 - 1\nT - 0 - 3 - 2\nT - 1 - 3 - 3\nA - Lara - 1 - 1 - S - AADADAGGA\n';
expect(() => {
Terrain.parse(terrainString);
}).not.toThrow();
});