-2

I am writing a fairly convoluted method and encountered the situation of complex logic judgment.

Generally, I can use if/else or switch to implement multiple conditional judgments, but there will be a problem: with the increase of logic complexity, if/else and switch in the code will become more and more bloated.

Secondly, my branch coverage stats are all over the place, as Istanbul is reporting (I think erroneously) that it cannot hit some of the else branches.

What other approaches exist that could help? So far, I've come across is the use of a map, but I'm not sure how to execute code blocks within the context of one.

static filterCourseContentElementButtonEvents(
  courseContents: ICourseContent[],
  courseContentElementButtonEvent: {
    id: CourseContentElementButtonEventType;
    value: CourseContentElementButtonEventTypeValue;
  }[],
  selectedCourseContentUid: string
): {
  id: CourseContentElementButtonEventType;
  value: CourseContentElementButtonEventTypeValue;
}[] {
  if (!CourseContentElementButtonService.isPreviousButtonEventTypeAvailable(
      courseContents,
      selectedCourseContentUid
    )) {
    courseContentElementButtonEvent = CourseContentElementButtonService.deleteCourseContentElementButtonEvent(
      courseContentElementButtonEvent,
      CourseContentElementButtonEventType.PREVIOUS
    );
  }
  if (!CourseContentElementButtonService.isNextButtonEventTypeAvailable(
      courseContents,
      selectedCourseContentUid
    )) {
    courseContentElementButtonEvent = CourseContentElementButtonService.deleteCourseContentElementButtonEvent(
      courseContentElementButtonEvent,
      CourseContentElementButtonEventType.NEXT
    );
  }
  if (!CourseContentElementButtonService.isJumpButtonEventTypeAvailable(
      courseContents,
      selectedCourseContentUid
    )) {
    courseContentElementButtonEvent = CourseContentElementButtonService.deleteCourseContentElementButtonEvent(
      courseContentElementButtonEvent,
      CourseContentElementButtonEventType.JUMP
    );
  }
  if (!CourseContentElementButtonService.isSubmitButtonEventTypeAvailable(
      courseContents,
      selectedCourseContentUid
    )) {
    courseContentElementButtonEvent = CourseContentElementButtonService.deleteCourseContentElementButtonEvent(
      courseContentElementButtonEvent,
      CourseContentElementButtonEventType.SUBMIT_RESPONSE
    );
  }
  if (!CourseContentElementButtonService.isEndButtonEventTypeAvailable(
      courseContents,
      selectedCourseContentUid
    )) {
    courseContentElementButtonEvent = CourseContentElementButtonService.deleteCourseContentElementButtonEvent(
      courseContentElementButtonEvent,
      CourseContentElementButtonEventType.END
    );
  }
  return courseContentElementButtonEvent;
}
mplungjan
  • 169,008
  • 28
  • 173
  • 236
methuselah
  • 12,766
  • 47
  • 165
  • 315
  • 1
    It would help to explain what is actually supposed to be happening here. I can sort of guess by the logic but seeing as "*Istanbul is reporting (I think erroneously) that it cannot hit some of the else branches.*" you don't seem to be sure yourself, I really don't want to take a guess. – VLAZ Mar 21 '21 at 08:38
  • I meant this: https://stackoverflow.com/questions/58877215/else-path-not-taken-in-unit-testing. It's become nigh on impossible to hit the else branches within my test coverage. – methuselah Mar 21 '21 at 08:43
  • And what is supposed to be happening? – VLAZ Mar 21 '21 at 08:44
  • I would expect all the else branches to be hit in my unit test code coverage as I have added test cases for them. But in some cases, they do not hit the else branches even though the test exists. I cannot find a reason why. Seeing as the code is rather unsightly, I thought it would be better to just refactor it. – methuselah Mar 21 '21 at 08:46
  • 1
    Let me clarify: what is the current code you've shown supposed to be doing? What are the expected outcomes? – VLAZ Mar 21 '21 at 08:47
  • Sorry, let me explain. I have a set of events I want to associate with a button (courseContentElementButtonEvent). The button exists in courseContents, and the array index is identified by selectedCourseContentUid. Not all button events are required to be associated with a particular courseContent, so this method performs the steps required to filter out the unneeded ones. – methuselah Mar 21 '21 at 08:50

1 Answers1

1

Perhaps something like this (not complete of course)

const deleteEventIfNotAvaiable = (type, contents, contentUid, buttonEvent, buttonEventType) => {
  const isAvailable = CourseContentElementButtonService[`is${type}ButtonEventTypeAvailable`](
    contents, contentUid
  )
  return isAvailable ? null : CourseContentElementButtonService.deleteCourseContentElementButtonEvent(
    buttonEvent, buttonEventType[type.toUpperCase()]
  );
}

...

['Previous','Next'...].forEach(type => courseContentElementButtonEvent = deleteEventIfNotAvaiable(
    type,
    courseContents,
    selectedCourseContentUid,
    courseContentElementButtonEvent,
    CourseContentElementButtonEventType)
)
mplungjan
  • 169,008
  • 28
  • 173
  • 236