Update disabled test after move of interface method desugaring

Bug: b/197494749
Change-Id: I1a3f75239cd044651253cd2cd6c5d12de6aea0a6
diff --git a/src/test/java/com/android/tools/r8/desugaring/interfacemethods/InvokeSuperInDefaultInterfaceMethodToNonImmediateInterfaceTest.java b/src/test/java/com/android/tools/r8/desugaring/interfacemethods/InvokeSuperInDefaultInterfaceMethodToNonImmediateInterfaceTest.java
index f4fec42..d743010 100644
--- a/src/test/java/com/android/tools/r8/desugaring/interfacemethods/InvokeSuperInDefaultInterfaceMethodToNonImmediateInterfaceTest.java
+++ b/src/test/java/com/android/tools/r8/desugaring/interfacemethods/InvokeSuperInDefaultInterfaceMethodToNonImmediateInterfaceTest.java
@@ -7,117 +7,132 @@
 import static org.junit.Assert.assertEquals;
 
 import com.android.tools.r8.TestBase;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.ToolHelper.DexVm.Version;
-import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.smali.SmaliBuilder;
+import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.StringUtils;
 import com.google.common.collect.ImmutableList;
-import org.junit.Ignore;
+import java.io.IOException;
+import java.util.List;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
+import org.objectweb.asm.Opcodes;
 
 @RunWith(Parameterized.class)
 public class InvokeSuperInDefaultInterfaceMethodToNonImmediateInterfaceTest extends TestBase {
 
+  private final TestParameters parameters;
   private final boolean includeInterfaceMethodOnJ;
 
-  @Parameterized.Parameters(name = "Include interface method on J: {0}")
-  public static Boolean[] data() {
-    return BooleanUtils.values();
+  // Note that the expected output is independent of the presence of J.m().
+  private static final String EXPECTED = StringUtils.lines("I.m()", "JImpl.m()");
+
+  @Parameterized.Parameters(name = "{0}, J.m(): {1}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        TestParameters.builder()
+            .withCfRuntimes()
+            .enableApiLevelsForCf()
+            .withDexRuntimes()
+            .withApiLevel(AndroidApiLevel.B)
+            .build(),
+        BooleanUtils.values());
   }
 
   public InvokeSuperInDefaultInterfaceMethodToNonImmediateInterfaceTest(
-      boolean includeInterfaceMethodOnJ) {
+      TestParameters parameters, boolean includeInterfaceMethodOnJ) {
+    this.parameters = parameters;
     this.includeInterfaceMethodOnJ = includeInterfaceMethodOnJ;
   }
 
   @Test
-  @Ignore("b/197494749 and b/120130831")
-  // TODO(b/197494749): Update this test now that desugaring is moved up. In particular this must
-  //  be rewritten with CF based transformers as R8 does not support interface desugaring on DEX.
-  // TODO(b/120130831): With the move of desugaring this issue should be resolved. The bug indicates
-  //  that a workaround for issues related to the IR implementation can now be reverted.
-  public void test() throws Exception {
-    // Note that the expected output is independent of the presence of J.m().
-    String expectedOutput = StringUtils.lines("I.m()", "JImpl.m()");
-
-    byte[] dex = buildProgramDexFileData();
-    if (ToolHelper.getDexVm().getVersion().isNewerThan(Version.V6_0_1)) {
-      AndroidApp app =
-          AndroidApp.builder()
-              .addDexProgramData(buildProgramDexFileData(), Origin.unknown())
-              .build();
-      assertEquals(expectedOutput, runOnArt(app, "TestClass"));
-    }
-
-    testForR8(Backend.DEX)
-        .addProgramDexFileData(dex)
-        .addKeepMainRule("TestClass")
-        .setMinApi(AndroidApiLevel.M)
-        .run("TestClass")
-        .assertSuccessWithOutput(expectedOutput);
+  public void testJvm() throws Exception {
+    // The rewritten input is invalid on JVM.
+    parameters.assumeJvmTestParameters();
+    testForJvm(parameters)
+        .addProgramClasses(getClasses())
+        .addProgramClassFileData(getTransformedClasses())
+        .run(parameters.getRuntime(), TestClass.class)
+        .assertFailureWithErrorThatThrows(VerifyError.class);
   }
 
-  // Using Smali instead of Jasmin because interfaces are broken in Jasmin.
-  private byte[] buildProgramDexFileData() throws Exception {
-    SmaliBuilder smaliBuilder = new SmaliBuilder();
-    smaliBuilder.setMinApi(AndroidApiLevel.N);
+  @Test
+  public void testD8() throws Exception {
+    // Notice that desugaring will map out of the invalid invoke.
+    testForD8(parameters.getBackend())
+        .addProgramClasses(getClasses())
+        .addProgramClassFileData(getTransformedClasses())
+        .setMinApi(parameters)
+        .run(parameters.getRuntime(), TestClass.class)
+        .assertSuccessWithOutput(EXPECTED);
+  }
 
-    smaliBuilder.addClass("TestClass");
+  @Test
+  public void testR8() throws Exception {
+    // Notice that desugaring will map out of the invalid invoke.
+    testForR8(parameters.getBackend())
+        .addProgramClasses(getClasses())
+        .addProgramClassFileData(getTransformedClasses())
+        .addKeepMainRule(TestClass.class)
+        .setMinApi(parameters)
+        .run(parameters.getRuntime(), TestClass.class)
+        .assertSuccessWithOutput(EXPECTED);
+  }
 
-    // public void main(String[] args) { new JImpl().m(); }
-    smaliBuilder.addMainMethod(
-        1,
-        "new-instance v0, LJImpl;",
-        "invoke-direct {v0}, LJImpl;-><init>()V",
-        "invoke-virtual {v0}, LJImpl;->m()V",
-        "return-void");
+  private List<Class<?>> getClasses() {
+    return ImmutableList.of(TestClass.class, I.class);
+  }
 
-    smaliBuilder.addInterface("I");
+  private List<byte[]> getTransformedClasses() throws IOException {
+    return ImmutableList.of(
+        transformer(JImpl.class)
+            .transformMethodInsnInMethod(
+                "m",
+                (opcode, owner, name, descriptor, isInterface, visitor) -> {
+                  if (opcode == Opcodes.INVOKESPECIAL) {
+                    assertEquals(owner, binaryName(J.class));
+                    owner = binaryName(I.class);
+                  }
+                  visitor.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
+                })
+            .transform(),
+        transformer(J.class)
+            .removeMethods(
+                (access, name, descriptor, signature, exceptions) ->
+                    !includeInterfaceMethodOnJ && name.equals("m"))
+            .transform());
+  }
 
-    // default void m() { System.out.println("In I.m()"); }
-    smaliBuilder.addInstanceMethod(
-        "void",
-        "m",
-        2,
-        "sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
-        "const-string v1, \"I.m()\"",
-        "invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V",
-        "return-void");
+  static class TestClass {
 
-    smaliBuilder.addInterface("J", "java.lang.Object", ImmutableList.of("I"));
-    if (includeInterfaceMethodOnJ) {
-      smaliBuilder.addInstanceMethod(
-          "void",
-          "m",
-          2,
-          "invoke-super {p0}, LI;->m()V",
-          "sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
-          "const-string v1, \"J.m()\"",
-          "invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V",
-          "return-void");
+    public static void main(String[] args) {
+      new JImpl().m();
     }
+  }
 
-    smaliBuilder.addClass("JImpl", "java.lang.Object", ImmutableList.of("J"));
-    smaliBuilder.addDefaultConstructor();
+  interface I {
 
-    // default void m() { I.super.m(); System.out.println("In JImpl.m()"); }
-    smaliBuilder.addInstanceMethod(
-        "void",
-        "m",
-        2,
-        // Note: invoke-super instruction to the non-immediate interface I.
-        "invoke-super {p0}, LI;->m()V",
-        "sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
-        "const-string v1, \"JImpl.m()\"",
-        "invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V",
-        "return-void");
+    default void m() {
+      System.out.println("I.m()");
+    }
+  }
 
-    return smaliBuilder.compile();
+  interface J extends I {
+
+    @Override
+    default void m() {
+      I.super.m();
+      System.out.println("J.m()");
+    }
+  }
+
+  static class JImpl implements J {
+
+    @Override
+    public void m() {
+      J.super.m(); // Will be rewritten to non-immediate interface: I.super.m();
+      System.out.println("JImpl.m()");
+    }
   }
 }