@Test
public void prepareStatementToDonateSwitchWithBreakAndDefaultKept() throws Exception {

  // Checks that 'case', 'default' and 'break' occurring in a switch are kept if the whole
  // switch statement is donated.
  final DonateDeadCodeTransformation dlc = getDummyTransformationObject();
  final TranslationUnit donor = ParseHelper.parse("#version 310 es\n"
      + "void main() {\n"
      + "  switch (0) {\n"
      + "    case 0:\n"
      + "      1;\n"
      + "      break;\n"
      + "    default:\n"
      + "      2;\n"
      + "  }\n"
      + "}\n");
  final TranslationUnit reference = ParseHelper.parse("#version 310 es\n"
      + "void main() {\n"
      + "  ;\n"
      + "  switch (0) {\n"
      + "    case 1:\n"
      + "      1;\n"
      + "    default:\n"
      + "      2;\n"
      + "  }\n"
      + "}\n");
  for (IInjectionPoint injectionPoint : new InjectionPoints(reference, new RandomWrapper(0),
      item -> true).getAllInjectionPoints()) {
    final Stmt toDonate = donor.getMainFunction().getBody().getStmt(0).clone();
    assert toDonate instanceof SwitchStmt;
    final DonationContext dc = new DonationContext(toDonate, new HashMap<>(),
        new ArrayList<>(), donor.getMainFunction());
    final Stmt donated = dlc.prepareStatementToDonate(injectionPoint, dc,
        TransformationProbabilities.DEFAULT_PROBABILITIES, new RandomWrapper(0),
        ShadingLanguageVersion.ESSL_310);
    // Check that the donated statement contains exactly one each of 'break', 'case' and
    // 'default'.
    new StandardVisitor() {
      private boolean foundBreak = false;
      private boolean foundCase = false;
      private boolean foundDefault = false;
      @Override
      public void visitBreakStmt(BreakStmt breakStmt) {
        assertFalse(foundBreak);
        foundBreak = true;
      }
      @Override
      public void visitExprCaseLabel(ExprCaseLabel exprCaseLabel) {
        assertFalse(foundCase);
        foundCase = true;
      }
      @Override
      public void visitDefaultCaseLabel(DefaultCaseLabel defaultCaseLabel) {
        assertFalse(foundDefault);
        foundDefault = true;
      }
      private void check(Stmt stmt) {
        visit(stmt);
        assertTrue(foundBreak);
        assertTrue(foundCase);
        assertTrue(foundDefault);
      }
    };
  }
}