/*
 * Copyright 2012 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.dev.js.client;

import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.storage.client.Storage;

import java.util.HashMap;
import java.util.Map;

/**
 * Tests coverage instrumentation.
 */
public class CoverageTest extends GWTTestCase {
  @SuppressWarnings("DoubleBraceInitialization")
  private static final Map<String, Double> EXPECTED_COVERAGE = new HashMap<String, Double>() { {
      put("25", 1.0);
      put("26", 1.0);
      put("27", 1.0);
      put("29", 1.0);
      put("31", 0.0);
      put("33", 1.0);
  }};

  @Override
  public String getModuleName() {
    return "com.google.gwt.dev.js.CoverageTestModule";
  }

  /*
   * Trigger the onbeforeunload handler. It would be nice to do this by refreshing the page or
   * something, but that causes the test to fail.
   */
  private static native void fireOnBeforeUnloadEvent() /*-{
    for (var i = 0; i < $wnd.frames.length; i++) {
      if (typeof $wnd.frames[i].onbeforeunload === 'function') {
        $wnd.frames[i].onbeforeunload();
      }
    }
  }-*/;

  public void testCoverageDataIsFlushedToLocalStorageOnBeforeUnload() {
    Storage localStorage = Storage.getLocalStorageIfSupported();
    assertNotNull("Test browser does not support localStorage", localStorage);
    // No coverage initially
    assertNull("Found unexpected initial coverage", localStorage.getItem("gwt_coverage"));

    CoverageTestModule.method();

    // Trigger the onbeforeunload handler to flush the coverage information to localStorage.
    fireOnBeforeUnloadEvent();
    String coverageAsJson = localStorage.getItem("gwt_coverage");
    assertNotNull("No coverage data found", coverageAsJson);
    JSONObject coverage = JSONParser.parseStrict(coverageAsJson).isObject();
    assertNotNull("Coverage data was not valid JSON", coverage);

    JSONObject fileCoverage =
        coverage.get("com/google/gwt/dev/js/client/CoverageTestModule.java").isObject();
    assertNotNull(fileCoverage);
    for (Map.Entry<String, Double> lineCoverage : EXPECTED_COVERAGE.entrySet()) {
      assertTrue(fileCoverage.containsKey(lineCoverage.getKey()));
      JSONNumber value = fileCoverage.get(lineCoverage.getKey()).isNumber();
      assertNotNull(value);
      assertEquals(lineCoverage.getValue(), value.doubleValue(), 0.0001);
    }
  }
}
