1

I have a specific case here where I have a React button that has a class defined by an enum, the button selects the correct class through a switch statement, testing each member of the enum. This is hardcoded and this component works fine (code below).

import * as React from 'react';
import './SquareButton.css';

export interface Props {
    buttonType: ButtonType;
    style?: object;
}

const SquareButton = ({ buttonType, style }: Props) => {

    var className = "";
    switch (buttonType) {
        case ButtonType.Hamburger:
            className = "zmdi zmdi-menu zmdi-hc-2x";
            break;
        case ButtonType.Clock:
            className = "zmdi zmdi-time zmdi-hc-2x";
            break;
        case ButtonType.Wifi:
            className = "zmdi zmdi-network-wifi zmdi-hc-2x";
            break;
        default:
            break;
    }

    return (
        <div className="squareButton" style={style} >
            <i className={className} />
        </div>
    )
}

export enum ButtonType {
    Wifi,
    Hamburger,
    Clock
}

export default SquareButton;

The issue I'm having is in testing this component, as this list of enum ButtonType is likely to grow I want to be able to loop through each button type without having to write individual tests or adding new ones each time there's a new button. Example test below.

for (var i = 0; i < Object.keys(ButtonType).length / 2; i++) {
    test(ButtonType[i] + 'square button icon class must contain zmdi', () => {
        const button = Enzyme.shallow(<SquareButton buttonType={i as ButtonType} />)
        expect(button.find('div').find('i').hasClass("zmdi")).toEqual(true);
    });
}

This successfully loops though each member in the enum but I can't figure out how to get the specific enum instance in the loop to pass to the component. Passing i as ButtonType still only passes an int value and the default in the switch is hit. I've tried lots of variations/string conversions etc but nothing I've tried works (the tests work if I hardcode an (e.g.) ButtonType.Wifi value).

How can I get a specific enum member from an integer value?

2
  • Does stackoverflow.com/questions/39372804/… help? Commented Sep 11, 2018 at 16:18
  • Unfortunately not, "item" in that case just returns a string, the same as if I tried ButtonType[i] on each loop Commented Sep 11, 2018 at 16:27

1 Answer 1

1

In this case i integer is already desired value, ButtonType.Hamburger === 0, etc.

The problem with iterating through enum is that enum values aren't necessarily numbers, and it's unnecessary that half of enum keys are numeric indexes.

enum A {
        B,
        C,
        D = 'D'
}

results in these keys:

["0", "1", "B", "C", "D"]

A fail-safe way would be:

for (const enumKey of Object.keys(ButtonType).filter(key => isNaN(+key))) {
  const enumVal = ButtonType[enumKey] as ButtonType;

  test(`ButtonType.${enumKey} square button icon class must contain zmdi`, () => {
    const button = Enzyme.shallow(<SquareButton buttonType={enumVal} />)
    ...
  })
}

Since it's preferable to also test classes that are specific to ButtonType like zmdi-menu, there should also be respective tests, so generic tests with iteration may be unneeded.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.