private void assertRewritten(String golden, String input, final boolean passes) throws Exception {
    mq.getMessages().clear();

    CssSchema cssSchema = CssSchema.getDefaultCss21Schema(mq);
    HtmlSchema htmlSchema = HtmlSchema.getDefault(mq);

    Pipeline<Jobs> pipeline =
        new Pipeline<Jobs>() {
          @Override
          public boolean applyStage(Stage<? super Jobs> stage, Jobs jobs) {
            boolean result = super.applyStage(stage, jobs);
            return passes ? result : true; // continue on failure
          }
        };
    pipeline.getStages().add(new OpenTemplateStage());
    pipeline.getStages().add(new ValidateCssStage(cssSchema, htmlSchema));
    pipeline.getStages().add(new ConsolidateCodeStage());

    ParseTreeNode node = js(fromString(input));
    PluginMeta meta = new PluginMeta();
    Jobs jobs = new Jobs(mc, mq, meta);
    jobs.getJobs().add(new Job(AncestorChain.instance(node)));

    assertTrue(pipeline.apply(jobs));
    assertEquals("" + jobs.getMessageQueue().getMessages(), passes, jobs.hasNoErrors());
    assertEquals("" + jobs.getJobs(), 1, jobs.getJobs().size());

    ParseTreeNode bare =
        stripBoilerPlate(jobs.getJobs().get(0).getRoot().cast(ParseTreeNode.class).node);
    assertEquals(golden, render(bare));
  }
  private void runCajoled(String js, Object golden, String context) throws Exception {
    Block uncajoledModuleBody = js(fromString(js));
    System.err.println("\n\nblock\n=====\n" + uncajoledModuleBody.toStringDeep(1));

    PluginMeta meta = new PluginMeta();
    meta.setDebugMode(true);

    Jobs jobs = new Jobs(mc, mq, meta);
    jobs.getJobs().add(new Job(AncestorChain.instance(uncajoledModuleBody)));

    Pipeline<Jobs> pipeline = new Pipeline<Jobs>();
    pipeline.getStages().add(new ConsolidateCodeStage());
    pipeline.getStages().add(new ValidateJavascriptStage(new TestBuildInfo()));
    pipeline.getStages().add(new InferFilePositionsStage());
    pipeline.getStages().add(new DebuggingSymbolsStage());
    if (!pipeline.apply(jobs)) {
      StringBuilder sb = new StringBuilder();
      for (Message msg : mq.getMessages()) {
        if (0 == sb.length()) {
          sb.append('\n');
        }
        sb.append(msg.getMessageLevel()).append(": ");
        msg.format(mc, sb);
      }
      fail(sb.toString());
    }

    CajoledModule cajoledModule = jobs.getJobs().get(0).getRoot().cast(CajoledModule.class).node;

    try {
      String cajoledText = String.format(context, render(cajoledModule));
      Object actual =
          RhinoTestBed.runJs(
              new RhinoTestBed.Input(getClass(), "/js/json_sans_eval/json_sans_eval.js"),
              new RhinoTestBed.Input(getClass(), "../console-stubs.js"),
              new RhinoTestBed.Input(getClass(), "/com/google/caja/cajita.js"),
              new RhinoTestBed.Input(getClass(), "/com/google/caja/log-to-console.js"),
              new RhinoTestBed.Input(getClass(), "/com/google/caja/cajita-debugmode.js"),
              new RhinoTestBed.Input(cajoledText, getName()));
      assertEquals(golden, actual);
    } catch (Exception ex) {
      System.err.println(render(cajoledModule));
      throw ex;
    } catch (Error ex) {
      System.err.println(render(cajoledModule));
      throw ex;
    }
  }