[gjs/wip/ptomato/develop: 11/11] coverage: Stop using cache



commit 3214ab52e666d91ec81ba214e7d853d01e587dfe
Author: Philip Chimento <philip chimento gmail com>
Date:   Fri Sep 29 18:15:44 2017 -0700

    coverage: Stop using cache
    
    Now that we don't have to do quite so much analysis of JS scripts' ASTs,
    it's quite feasible to do the whole coverage thing without caching. A
    test run with coverage doesn't take very much longer than a test run
    without.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=788166

 gjs-srcs.mk                        |    1 -
 gjs/coverage-internal.h            |   68 ---
 gjs/coverage.cpp                   |  403 +-----------------
 installed-tests/js/testCoverage.js |   70 ---
 modules/_bootstrap/coverage.js     |   74 +---
 test/gjs-test-coverage.cpp         |  868 +-----------------------------------
 6 files changed, 13 insertions(+), 1471 deletions(-)
---
diff --git a/gjs-srcs.mk b/gjs-srcs.mk
index 36f29a7..1c61c60 100644
--- a/gjs-srcs.mk
+++ b/gjs-srcs.mk
@@ -52,7 +52,6 @@ gjs_srcs =                            \
        gjs/byteArray.h                 \
        gjs/context.cpp                 \
        gjs/context-private.h           \
-       gjs/coverage-internal.h         \
        gjs/coverage.cpp                \
        gjs/engine.cpp                  \
        gjs/engine.h                    \
diff --git a/gjs/coverage.cpp b/gjs/coverage.cpp
index d7b6d49..c9659e7 100644
--- a/gjs/coverage.cpp
+++ b/gjs/coverage.cpp
@@ -23,13 +23,11 @@
  * Authored By: Sam Spilsbury <sam endlessm com>
  */
 
-#include <sys/stat.h>
 #include <gio/gio.h>
 
 #include <gjs/context.h>
 
 #include "coverage.h"
-#include "coverage-internal.h"
 #include "global.h"
 #include "importer.h"
 #include "jsapi-util-args.h"
@@ -45,9 +43,6 @@ typedef struct {
     JS::Heap<JSObject *> coverage_statistics;
 
     GFile *output_dir;
-    GFile *cache;
-    /* tells whether priv->cache == NULL means no cache, or not specified */
-    bool cache_specified;
 } GjsCoveragePrivate;
 
 G_DEFINE_TYPE_WITH_PRIVATE(GjsCoverage,
@@ -58,7 +53,6 @@ enum {
     PROP_0,
     PROP_PREFIXES,
     PROP_CONTEXT,
-    PROP_CACHE,
     PROP_OUTPUT_DIRECTORY,
     PROP_N
 };
@@ -891,164 +885,6 @@ get_covered_files(GjsCoverage *coverage)
     return NULL;
 }
 
-bool
-gjs_get_file_mtime(GFile    *file,
-                   GTimeVal *mtime)
-{
-    GError *error = NULL;
-    GFileInfo *info = g_file_query_info(file,
-                                        "time::modified,time::modified-usec",
-                                        G_FILE_QUERY_INFO_NONE,
-                                        NULL,
-                                        &error);
-
-    if (!info) {
-        char *path = get_file_identifier(file);
-        g_warning("Failed to get modification time of %s, "
-                  "falling back to checksum method for caching. Reason was: %s",
-                  path, error->message);
-        g_clear_object(&info);
-        return false;
-    }
-
-    g_file_info_get_modification_time(info, mtime);
-    g_clear_object(&info);
-
-    /* For some URI types, eg, resources, the operation getting
-     * the mtime might succeed, but by default zero is returned.
-     *
-     * Check if that is the case for both tv_sec and tv_usec and if
-     * so return false. */
-    return !(mtime->tv_sec == 0 && mtime->tv_usec == 0);
-}
-
-static GBytes *
-read_all_bytes_from_file(GFile *file)
-{
-    /* We have to use g_file_query_exists here since
-     * g_file_test(path, G_FILE_TEST_EXISTS) is implemented in terms
-     * of access(), which doesn't work with resource paths. */
-    if (!g_file_query_exists(file, NULL))
-        return NULL;
-
-    gsize len = 0;
-    gchar *data = NULL;
-
-    GError *error = NULL;
-
-    if (!g_file_load_contents(file,
-                              NULL,
-                              &data,
-                              &len,
-                              NULL,
-                              &error)) {
-        char *path = get_file_identifier(file);
-        g_critical("Unable to read bytes from: %s, reason was: %s\n",
-                   path, error->message);
-        g_clear_error(&error);
-        g_free(path);
-        return NULL;
-    }
-
-    return g_bytes_new_take(data, len);
-}
-
-gchar *
-gjs_get_file_checksum(GFile *file)
-{
-    GBytes *data = read_all_bytes_from_file(file);
-
-    if (!data)
-        return NULL;
-
-    gchar *checksum = g_compute_checksum_for_bytes(G_CHECKSUM_SHA512, data);
-
-    g_bytes_unref(data);
-    return checksum;
-}
-
-GBytes *
-gjs_serialize_statistics(GjsCoverage *coverage)
-{
-    GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(coverage);
-    JSContext *js_context = (JSContext *) gjs_context_get_native_context(priv->context);
-
-    JSAutoRequest ar(js_context);
-    JSAutoCompartment ac(js_context, priv->coverage_statistics);
-    JS::RootedObject rooted_priv(js_context, priv->coverage_statistics);
-    JS::RootedValue string_value_return(js_context);
-
-    if (!JS_CallFunctionName(js_context, rooted_priv, "stringify",
-                             JS::HandleValueArray::empty(),
-                             &string_value_return)) {
-        gjs_log_exception(js_context);
-        return NULL;
-    }
-
-    if (!string_value_return.isString())
-        return NULL;
-
-    /* Free'd by g_bytes_new_take */
-    GjsAutoJSChar statistics_as_json_string(js_context);
-
-    if (!gjs_string_to_utf8(js_context,
-                            string_value_return.get(),
-                            &statistics_as_json_string)) {
-        gjs_log_exception(js_context);
-        return NULL;
-    }
-
-    int json_string_len = strlen(statistics_as_json_string);
-    auto json_bytes =
-        reinterpret_cast<uint8_t*>(statistics_as_json_string.copy());
-
-    return g_bytes_new_take(json_bytes,
-                            json_string_len);
-}
-
-static JSString *
-gjs_deserialize_cache_to_object_for_compartment(JSContext        *context,
-                                                JS::HandleObject global_object,
-                                                GBytes           *cache_data)
-{
-    JSAutoRequest ar(context);
-    JSAutoCompartment ac(context,
-                         JS_GetGlobalForObject(context,
-                                               global_object));
-
-    gsize len = 0;
-    auto string = static_cast<const char *>(g_bytes_get_data(cache_data, &len));
-
-    return JS_NewStringCopyN(context, string, len);
-}
-
-JSString *
-gjs_deserialize_cache_to_object(GjsCoverage *coverage,
-                                GBytes      *cache_data)
-{
-    /* Deserialize into an object with the following structure:
-     *
-     * object = {
-     *     'filename': {
-     *         contents: (file contents),
-     *         nLines: (number of lines in file),
-     *         branches: Array for n_branches of {
-     *             point: branch_point,
-     *             exits: Number[nLines + 1]
-     *         }
-     *     }
-     * }
-     */
-
-    GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(coverage);
-    JSContext *context = (JSContext *) gjs_context_get_native_context(priv->context);
-    JSAutoRequest ar(context);
-    JSAutoCompartment ac(context, priv->coverage_statistics);
-    JS::RootedObject global_object(context,
-                                   JS_GetGlobalForObject(context, priv->coverage_statistics));
-    return gjs_deserialize_cache_to_object_for_compartment(context, global_object, cache_data);
-}
-
 static GArray *
 gjs_fetch_statistics_from_js(GjsCoverage *coverage,
                              gchar       **coverage_files)
@@ -1082,64 +918,6 @@ gjs_fetch_statistics_from_js(GjsCoverage *coverage,
     return file_statistics_array;
 }
 
-bool
-gjs_write_cache_file(GFile  *file,
-                     GBytes *cache)
-{
-    gsize cache_len = 0;
-    char *cache_data = (char *) g_bytes_get_data(cache, &cache_len);
-    GError *error = NULL;
-
-    if (!g_file_replace_contents(file,
-                                 cache_data,
-                                 cache_len,
-                                 NULL,
-                                 false,
-                                 G_FILE_CREATE_NONE,
-                                 NULL,
-                                 NULL,
-                                 &error)) {
-        char *path = get_file_identifier(file);
-        g_warning("Failed to write all bytes to %s, reason was: %s\n",
-                  path, error->message);
-        g_warning("Will remove this file to prevent inconsistent cache "
-                  "reads next time.");
-        g_clear_error(&error);
-        if (!g_file_delete(file, NULL, &error)) {
-            g_assert(error != NULL);
-            g_critical("Deleting %s failed because %s! You will need to "
-                       "delete it manually before running the coverage "
-                       "mode again.", path, error->message);
-            g_clear_error(&error);
-        }
-        g_free(path);
-
-        return false;
-    }
-
-    return true;
-}
-
-static bool
-coverage_statistics_has_stale_cache(GjsCoverage *coverage)
-{
-    GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(coverage);
-    JSContext          *js_context = (JSContext *) gjs_context_get_native_context(priv->context);
-
-    JSAutoRequest ar(js_context);
-    JSAutoCompartment ac(js_context, priv->coverage_statistics);
-    JS::RootedObject rooted_priv(js_context, priv->coverage_statistics);
-    JS::RootedValue stale_cache_value(js_context);
-    if (!JS_CallFunctionName(js_context, rooted_priv, "staleCache",
-                             JS::HandleValueArray::empty(),
-                             &stale_cache_value)) {
-        gjs_log_exception(js_context);
-        g_error("Failed to call into javascript to get stale cache value. This is a bug");
-    }
-
-    return stale_cache_value.toBoolean();
-}
-
 static unsigned int _suppressed_coverage_messages_count = 0;
 
 /**
@@ -1204,15 +982,6 @@ gjs_coverage_write_statistics(GjsCoverage *coverage)
 
     g_strfreev(executed_coverage_files);
 
-    const bool has_cache_path = priv->cache != NULL;
-    const bool cache_is_stale = coverage_statistics_has_stale_cache(coverage);
-
-    if (has_cache_path && cache_is_stale) {
-        GBytes *cache_data = gjs_serialize_statistics(coverage);
-        gjs_write_cache_file(priv->cache, cache_data);
-        g_bytes_unref(cache_data);
-    }
-
     char *output_file_path = g_file_get_path(priv->output_dir);
     g_message("Wrote coverage statistics to %s", output_file_path);
     if (_suppressed_coverage_messages_count) {
@@ -1292,67 +1061,6 @@ get_file_from_call_args_filename(JSContext    *context,
 }
 
 static bool
-coverage_get_file_modification_time(JSContext *context,
-                                    unsigned  argc,
-                                    JS::Value *vp)
-{
-    JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
-    GTimeVal mtime;
-    bool ret = false;
-    GFile *file = get_file_from_call_args_filename(context, args);
-
-    if (!file)
-        return false;
-
-    if (gjs_get_file_mtime(file, &mtime)) {
-        JS::AutoValueArray<2> mtime_values_array(context);
-        mtime_values_array[0].setInt32(mtime.tv_sec);
-        mtime_values_array[1].setInt32(mtime.tv_usec);
-        JS::RootedObject array_obj(context,
-            JS_NewArrayObject(context, mtime_values_array));
-        if (!array_obj)
-            goto out;
-        args.rval().setObject(*array_obj);
-    } else {
-        args.rval().setNull();
-    }
-
-    ret = true;
-
-out:
-    g_object_unref(file);
-    return ret;
-}
-
-static bool
-coverage_get_file_checksum(JSContext *context,
-                           unsigned  argc,
-                           JS::Value *vp)
-{
-    JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
-    GFile *file = get_file_from_call_args_filename(context, args);
-
-    if (!file)
-        return false;
-
-    char *checksum = gjs_get_file_checksum(file);
-
-    if (!checksum) {
-        char *filename = get_file_identifier(file);
-        gjs_throw(context, "Failed to read %s and get its checksum", filename);
-        g_free(filename);
-        g_object_unref(file);
-        return false;
-    }
-
-    args.rval().setString(JS_NewStringCopyZ(context, checksum));
-
-    g_object_unref(file);
-    g_free(checksum);
-    return true;
-}
-
-static bool
 coverage_get_file_contents(JSContext *context,
                            unsigned   argc,
                            JS::Value *vp)
@@ -1393,8 +1101,6 @@ coverage_get_file_contents(JSContext *context,
 static JSFunctionSpec coverage_funcs[] = {
     JS_FS("log", coverage_log, 1, GJS_MODULE_PROP_FLAGS),
     JS_FS("getFileContents", coverage_get_file_contents, 1, GJS_MODULE_PROP_FLAGS),
-    JS_FS("getFileModificationTime", coverage_get_file_modification_time, 1, GJS_MODULE_PROP_FLAGS),
-    JS_FS("getFileChecksum", coverage_get_file_checksum, 1, GJS_MODULE_PROP_FLAGS),
     JS_FS_END
 };
 
@@ -1408,59 +1114,10 @@ coverage_statistics_tracer(JSTracer *trc, void *data)
                               "coverage_statistics");
 }
 
-/* This function is mainly used in the tests in order to fiddle with
- * the internals of the coverage statisics collector on the coverage
- * compartment side */
-bool
-gjs_run_script_in_coverage_compartment(GjsCoverage *coverage,
-                                       const char  *script)
-{
-    GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(coverage);
-    JSContext          *js_context = (JSContext *) gjs_context_get_native_context(priv->context);
-    JSAutoCompartment ac(js_context, priv->coverage_statistics);
-    JSAutoRequest ar(js_context);
-
-    JS::CompileOptions options(js_context);
-    options.setUTF8(true);
-
-    JS::RootedValue rval(js_context);
-    if (!JS::Evaluate(js_context, options, script, strlen(script), &rval)) {
-        gjs_log_exception(js_context);
-        g_warning("Failed to evaluate <coverage_modifier>");
-        return false;
-    }
-
-    return true;
-}
-
-bool
-gjs_inject_value_into_coverage_compartment(GjsCoverage     *coverage,
-                                           JS::HandleValue  value,
-                                           const char      *property)
-{
-    GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(coverage);
-
-    JSContext     *js_context = (JSContext *) gjs_context_get_native_context(priv->context);
-    JSAutoRequest ar(js_context);
-    JSAutoCompartment ac(js_context, priv->coverage_statistics);
-
-    JS::RootedObject coverage_global_scope(js_context,
-                                           JS_GetGlobalForObject(js_context, priv->coverage_statistics));
-
-    if (!JS_SetProperty(js_context, coverage_global_scope, property,
-                        value)) {
-        g_warning("Failed to set property %s to requested value", property);
-        return false;
-    }
-
-    return true;
-}
-
 static bool
 bootstrap_coverage(GjsCoverage *coverage)
 {
     GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(coverage);
-    GBytes             *cache_bytes = NULL;
 
     JSContext *context = (JSContext *) gjs_context_get_native_context(priv->context);
     JSAutoRequest ar(context);
@@ -1493,28 +1150,11 @@ bootstrap_coverage(GjsCoverage *coverage)
                                          &coverage_statistics_constructor))
             return false;
 
-        /* Create value for holding the cache. This will be undefined if
-         * the cache does not exist, otherwise it will be an object set
-         * to the value of the cache */
-        JS::RootedValue cache_value(context);
-
-        if (priv->cache)
-            cache_bytes = read_all_bytes_from_file(priv->cache);
-
-        if (cache_bytes) {
-            JSString *cache_object = gjs_deserialize_cache_to_object_for_compartment(context,
-                                                                                     debugger_compartment,
-                                                                                     cache_bytes);
-            cache_value.setString(cache_object);
-            g_bytes_unref(cache_bytes);
-        }
-
         /* Now create the array to pass the desired prefixes over */
         JSObject *prefixes = gjs_build_string_array(context, -1, priv->prefixes);
 
-        JS::AutoValueArray<2> coverage_statistics_constructor_args(context);
+        JS::AutoValueArray<1> coverage_statistics_constructor_args(context);
         coverage_statistics_constructor_args[0].setObject(*prefixes);
-        coverage_statistics_constructor_args[1].set(cache_value);
 
         JSObject *coverage_statistics = JS_New(context,
                                                coverage_statistics_constructor,
@@ -1543,11 +1183,6 @@ gjs_coverage_constructed(GObject *object)
     GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(coverage);
     new (&priv->coverage_statistics) JS::Heap<JSObject *>();
 
-    if (!priv->cache_specified) {
-        g_message("Cache path was not given, picking default one");
-        priv->cache = g_file_new_for_path(".internal-gjs-coverage-cache");
-    }
-
     if (!bootstrap_coverage(coverage)) {
         JSContext *context = static_cast<JSContext *>(gjs_context_get_native_context(priv->context));
         JSAutoCompartment compartment(context, gjs_get_import_global(context));
@@ -1571,11 +1206,6 @@ gjs_coverage_set_property(GObject      *object,
     case PROP_CONTEXT:
         priv->context = GJS_CONTEXT(g_value_dup_object(value));
         break;
-    case PROP_CACHE:
-        priv->cache_specified = true;
-        /* g_value_dup_object() adds a reference if not NULL */
-        priv->cache = static_cast<GFile *>(g_value_dup_object(value));
-        break;
     case PROP_OUTPUT_DIRECTORY:
         priv->output_dir = G_FILE(g_value_dup_object(value));
         break;
@@ -1634,7 +1264,6 @@ gjs_coverage_finalize (GObject *object)
 
     g_strfreev(priv->prefixes);
     g_clear_object(&priv->output_dir);
-    g_clear_object(&priv->cache);
     priv->coverage_statistics.~Heap();
 
     G_OBJECT_CLASS(gjs_coverage_parent_class)->finalize(object);
@@ -1660,11 +1289,6 @@ gjs_coverage_class_init (GjsCoverageClass *klass)
                                                    "A context to gather coverage stats for",
                                                    GJS_TYPE_CONTEXT,
                                                    (GParamFlags) (G_PARAM_CONSTRUCT_ONLY | 
G_PARAM_WRITABLE));
-    properties[PROP_CACHE] = g_param_spec_object("cache",
-                                                 "Cache",
-                                                 "File containing a cache to preload ASTs from",
-                                                 G_TYPE_FILE,
-                                                 (GParamFlags) (G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
     properties[PROP_OUTPUT_DIRECTORY] =
         g_param_spec_object("output-directory", "Output directory",
                             "Directory handle at which to output coverage statistics",
@@ -1708,28 +1332,3 @@ gjs_coverage_new (const char * const *prefixes,
 
     return coverage;
 }
-
-GjsCoverage *
-gjs_coverage_new_internal_with_cache(const char * const *coverage_prefixes,
-                                     GjsContext         *context,
-                                     GFile              *output_dir,
-                                     GFile              *cache)
-{
-    GjsCoverage *coverage =
-        GJS_COVERAGE(g_object_new(GJS_TYPE_COVERAGE,
-                                  "prefixes", coverage_prefixes,
-                                  "context", context,
-                                  "cache", cache,
-                                  "output-directory", output_dir,
-                                  NULL));
-
-    return coverage;
-}
-
-GjsCoverage *
-gjs_coverage_new_internal_without_cache(const char * const *prefixes,
-                                        GjsContext         *cx,
-                                        GFile              *output_dir)
-{
-    return gjs_coverage_new_internal_with_cache(prefixes, cx, output_dir, NULL);
-}
diff --git a/installed-tests/js/testCoverage.js b/installed-tests/js/testCoverage.js
index 2d5389d..ed3b801 100644
--- a/installed-tests/js/testCoverage.js
+++ b/installed-tests/js/testCoverage.js
@@ -358,10 +358,6 @@ describe('Coverage statistics container', function () {
     beforeEach(function () {
         Coverage.getFileContents =
             jasmine.createSpy('getFileContents').and.callFake(f => MockFiles[f]);
-        Coverage.getFileChecksum =
-            jasmine.createSpy('getFileChecksum').and.returnValue('abcd');
-        Coverage.getFileModificationTime =
-            jasmine.createSpy('getFileModificationTime').and.returnValue([1, 2]);
         container = new Coverage.CoverageStatisticsContainer(MockFilenames);
     });
 
@@ -384,70 +380,4 @@ describe('Coverage statistics container', function () {
     it('ignores a file in angle brackets (our convention for programmatic scripts)', function () {
         expect(() => container.fetchStatistics('<script>')).not.toThrow();
     });
-
-    const MockCache = '{ \
-        "filename": { \
-            "mtime": [1, 2], \
-            "checksum": null, \
-            "branches": [ \
-                { \
-                    "point": 4, \
-                    "exits": [5] \
-                } \
-            ] \
-        } \
-    }';
-
-    describe('with cache', function () {
-        let container;
-        beforeEach(function () {
-            spyOn(Coverage, '_analyzeBranchInfoFromReflection').and.callThrough();
-            container = new Coverage.CoverageStatisticsContainer(MockFilenames,
-                                                                 MockCache);
-        });
-
-        it('fetches counters from cache', function () {
-            container.fetchStatistics('filename');
-            expect(Coverage._analyzeBranchInfoFromReflection).not.toHaveBeenCalled();
-        });
-
-        it('fetches counters from reflection if missed', function () {
-            container.fetchStatistics('uncached');
-            expect(Coverage._analyzeBranchInfoFromReflection).toHaveBeenCalled();
-        });
-
-        it('cache is not stale if all hit', function () {
-            container.fetchStatistics('filename');
-            expect(container.staleCache()).toBeFalsy();
-        });
-
-        it('cache is stale if missed', function () {
-            container.fetchStatistics('uncached');
-            expect(container.staleCache()).toBeTruthy();
-        });
-    });
-
-    describe('coverage counters from cache', function () {
-        let container, statistics;
-        let containerWithNoCaching, statisticsWithNoCaching;
-        beforeEach(function () {
-            container = new Coverage.CoverageStatisticsContainer(MockFilenames,
-                                                                 MockCache);
-            statistics = container.fetchStatistics('filename');
-
-            containerWithNoCaching = new Coverage.CoverageStatisticsContainer(MockFilenames);
-            statisticsWithNoCaching = containerWithNoCaching.fetchStatistics('filename');
-        });
-
-        it('have same branch exits as reflection', function () {
-            /* Branch starts on line 4 */
-            expect(statisticsWithNoCaching[4].exits[0].line)
-                .toEqual(statistics[4].exits[0].line);
-        });
-
-        it('have same branch points as reflection', function () {
-            expect(statisticsWithNoCaching[4].point)
-                .toEqual(statistics[4].point);
-        });
-    });
 });
diff --git a/modules/_bootstrap/coverage.js b/modules/_bootstrap/coverage.js
index cb6b7ab..87588f4 100644
--- a/modules/_bootstrap/coverage.js
+++ b/modules/_bootstrap/coverage.js
@@ -458,32 +458,6 @@ function _convertFunctionCountersToArray(functionCounters) {
     return arrayReturn;
 }
 
-/* Looks up filename in cache and fetches branch info
- * directly from the cache */
-function _fetchBranchInfoFromCache(filename, cache) {
-    if (!cache)
-        return null;
-
-    if (Object.keys(cache).indexOf(filename) !== -1) {
-        let cache_for_file = cache[filename];
-
-        if (cache_for_file.mtime) {
-             let mtime = getFileModificationTime(filename);
-             if (mtime[0] != cache[filename].mtime[0] ||
-                 mtime[1] != cache[filename].mtime[1])
-                 return null;
-        } else {
-            let checksum = getFileChecksum(filename);
-            if (checksum != cache[filename].checksum)
-                return null;
-        }
-
-        return cache_for_file.branches;
-    }
-
-    return null;
-}
-
 function _analyzeBranchInfoFromReflection(filename, contents) {
     // Shebang is illegal character sequence to JS parser
     if (contents.startsWith('#!'))
@@ -494,22 +468,15 @@ function _analyzeBranchInfoFromReflection(filename, contents) {
 }
 
 var CoverageStatisticsContainer = class {
-    constructor(prefixes, cache) {
+    constructor(prefixes) {
         /* Copy the files array, so that it can be re-used in the tests */
-        this._cachedASTs = cache ? JSON.parse(cache) : null;
         this._coveredFiles = new Map();
-        this._cacheMisses = 0;
     }
 
     _createStatisticsFor(filename) {
         let contents = getFileContents(filename);
         let nLines = _getNumberOfLinesForScript(contents);
-
-        let info = _fetchBranchInfoFromCache(filename, this._cachedASTs);
-        if (info === null) {
-            this._cacheMisses++;
-            info = _analyzeBranchInfoFromReflection(filename, contents);
-        }
+        let info = _analyzeBranchInfoFromReflection(filename, contents);
 
         if (info === null)
             throw new Error('Failed to parse and reflect file ' + filename);
@@ -531,27 +498,6 @@ var CoverageStatisticsContainer = class {
         return info;
     }
 
-    stringify() {
-        let cache_data = {};
-        for (let [filename, branchCounters] of this._coveredFiles) {
-            // Filter out undefined lines, since the index represents the
-            // current line number on the file (see _incrementLineCounters())
-            let branches = branchCounters.filter(c => c !== undefined)
-            .map(({point, exits}) => ({
-                point,
-                exits: exits.map(({line}) => line),
-            }));
-
-            let mtime = getFileModificationTime(filename);
-            cache_data[filename] = {
-                mtime,
-                checksum: mtime === null ? getFileChecksum(filename) : null,
-                branches,
-            };
-        }
-        return JSON.stringify(cache_data);
-    }
-
     getCoveredFiles() {
         return [...this._coveredFiles.keys()];
     }
@@ -560,10 +506,6 @@ var CoverageStatisticsContainer = class {
         return this._ensureStatisticsFor(filename);
     }
 
-    staleCache() {
-        return this._cacheMisses > 0;
-    }
-
     deleteStatistics(filename) {
         this._coveredFiles.delete(filename);
     }
@@ -575,8 +517,8 @@ var CoverageStatisticsContainer = class {
  * It isn't possible to unit test this class because it depends on running
  * Debugger which in turn depends on objects injected in from another compartment */
 var CoverageStatistics = class {
-    constructor(prefixes, cache) {
-        let container = new CoverageStatisticsContainer(prefixes, cache);
+    constructor(prefixes) {
+        let container = new CoverageStatisticsContainer(prefixes);
         this.container = container;
 
         /* 'debuggee' comes from the invocation from
@@ -631,14 +573,6 @@ var CoverageStatistics = class {
         return this.container.getCoveredFiles();
     }
 
-    staleCache() {
-        return this.container.staleCache();
-    }
-
-    stringify() {
-        return this.container.stringify();
-    }
-
     getExecutedLinesFor(filename) {
         let scripts = this._findScriptsForFilename(filename);
         let counters = [];
diff --git a/test/gjs-test-coverage.cpp b/test/gjs-test-coverage.cpp
index f898ca0..abe3886 100644
--- a/test/gjs-test-coverage.cpp
+++ b/test/gjs-test-coverage.cpp
@@ -29,18 +29,11 @@
 #include <stdio.h>
 #include <unistd.h>
 
-#include <sys/types.h>
-#include <fcntl.h>
-#include <ftw.h>
-
 #include <glib.h>
 #include <gio/gio.h>
-#include <gio/gunixoutputstream.h>
 #include <gjs/gjs.h>
 
 #include "gjs/coverage.h"
-#include "gjs/coverage-internal.h"
-
 #include "gjs-test-utils.h"
 
 typedef struct _GjsCoverageFixture {
@@ -123,9 +116,8 @@ gjs_coverage_fixture_set_up(gpointer      fixture_data,
     };
 
     fixture->context = gjs_context_new_with_search_path((char **) search_paths);
-    fixture->coverage =
-        gjs_coverage_new_internal_without_cache(coverage_paths, fixture->context,
-                                                fixture->lcov_output_dir);
+    fixture->coverage = gjs_coverage_new(coverage_paths, fixture->context,
+                                         fixture->lcov_output_dir);
 
     replace_file(fixture->tmp_js_script, js_script);
     g_free(tmp_output_dir_name);
@@ -303,44 +295,6 @@ coverage_data_matches_values_for_key(const char            *data,
     return false;
 }
 
-/* A simple wrapper around gjs_coverage_new */
-static GjsCoverage *
-create_coverage_for_script(GjsContext *context,
-                           GFile      *script,
-                           GFile      *output_dir)
-{
-    char *script_path = get_script_identifier(script);
-    char *coverage_scripts[] = {
-        script_path,
-        NULL
-    };
-
-    GjsCoverage *retval =
-        gjs_coverage_new_internal_without_cache(coverage_scripts, context,
-                                                output_dir);
-    g_free(script_path);
-    return retval;
-}
-
-static GjsCoverage *
-create_coverage_for_script_and_cache(GjsContext *context,
-                                     GFile      *cache,
-                                     GFile      *script,
-                                     GFile      *output_dir)
-{
-    char *script_path = get_script_identifier(script);
-    char *coverage_scripts[] = {
-        script_path,
-        NULL
-    };
-
-    GjsCoverage *retval =
-        gjs_coverage_new_internal_with_cache(coverage_scripts, context,
-                                             output_dir, cache);
-    g_free(script_path);
-    return retval;
-}
-
 static void
 test_covered_file_is_duplicated_into_output_if_resource(gpointer      fixture_data,
                                                         gconstpointer user_data)
@@ -362,10 +316,8 @@ test_covered_file_is_duplicated_into_output_if_resource(gpointer      fixture_da
     };
 
     fixture->context = gjs_context_new_with_search_path(search_paths);
-    fixture->coverage =
-        gjs_coverage_new_internal_without_cache(coverage_scripts,
-                                                fixture->context,
-                                                fixture->lcov_output_dir);
+    fixture->coverage = gjs_coverage_new(coverage_scripts, fixture->context,
+                                         fixture->lcov_output_dir);
 
     gjs_context_eval_file(fixture->context,
                           mock_resource_filename,
@@ -508,10 +460,8 @@ test_expected_entry_not_written_for_nonexistent_file(gpointer      fixture_data,
     };
 
     g_object_unref(fixture->coverage);
-    fixture->coverage =
-        gjs_coverage_new_internal_without_cache(coverage_paths,
-                                                fixture->context,
-                                                fixture->lcov_output_dir);
+    fixture->coverage = gjs_coverage_new(coverage_paths, fixture->context,
+                                         fixture->lcov_output_dir);
 
     /* Temporarily disable fatal mask and silence warnings */
     GLogLevelFlags old_flags = g_log_set_always_fatal((GLogLevelFlags) G_LOG_LEVEL_ERROR);
@@ -1268,9 +1218,8 @@ gjs_coverage_multiple_source_files_to_single_output_fixture_set_up(gpointer fixt
 
     fixture->base_fixture.context = gjs_context_new_with_search_path(search_paths);
     fixture->base_fixture.coverage =
-        gjs_coverage_new_internal_without_cache(coverage_paths,
-                                                fixture->base_fixture.context,
-                                                fixture->base_fixture.lcov_output_dir);
+        gjs_coverage_new(coverage_paths, fixture->base_fixture.context,
+                         fixture->base_fixture.lcov_output_dir);
 
     g_free(output_path);
     g_free(first_js_script_path);
@@ -1429,671 +1378,6 @@ test_correct_line_coverage_data_written_for_both_source_file_sectons(gpointer
     g_free(coverage_data_contents);
 }
 
-static GString *
-append_tuples_to_array_in_object_notation(GString    *string,
-                                          const char  *tuple_contents_strv)
-{
-    char *original_ptr = (char *) tuple_contents_strv;
-    char *expected_tuple_contents = NULL;
-    while ((expected_tuple_contents = strsep((char **) &tuple_contents_strv, ";")) != NULL) {
-       if (!strlen(expected_tuple_contents))
-           continue;
-
-       if (expected_tuple_contents != original_ptr)
-           g_string_append_printf(string, ",");
-        g_string_append_printf(string, "{%s}", expected_tuple_contents);
-    }
-
-    return string;
-}
-
-static GString *
-format_expected_cache_object_notation(const char *mtimes,
-                                      const char *hash,
-                                      GFile      *script,
-                                      const char *expected_branches)
-{
-    char *script_name = get_script_identifier(script);
-    GString *string = g_string_new("");
-    g_string_append_printf(string,
-                           "{\"%s\":{\"mtime\":%s,\"checksum\":%s,\"branches\":[",
-                           script_name,
-                           mtimes,
-                           hash);
-    g_free(script_name);
-    append_tuples_to_array_in_object_notation(string, expected_branches);
-    g_string_append_printf(string, "]}}");
-    return string;
-}
-
-typedef struct _GjsCoverageCacheObjectNotationTestTableData {
-    const char *test_name;
-    const char *script;
-    const char *uri;
-    const char *expected_branches;
-} GjsCoverageCacheObjectNotationTableTestData;
-
-static GBytes *
-serialize_ast_to_bytes(GjsCoverage *coverage,
-                       const char **coverage_paths)
-{
-    return gjs_serialize_statistics(coverage);
-}
-
-static char *
-serialize_ast_to_object_notation(GjsCoverage *coverage,
-                                 const char **coverage_paths)
-{
-    /* Unfortunately, we need to pass in this paramater here since
-     * the len parameter is not allow-none.
-     *
-     * The caller doesn't need to know about the length of the
-     * data since it is only used for strcmp and the data is
-     * NUL-terminated anyway. */
-    gsize len = 0;
-    return (char *)g_bytes_unref_to_data(serialize_ast_to_bytes(coverage, coverage_paths),
-                                         &len);
-}
-
-static char *
-eval_file_for_ast_in_object_notation(GjsContext  *context,
-                                     GjsCoverage *coverage,
-                                     GFile       *script)
-{
-    bool success = eval_script(context, script);
-    g_assert_true(success);
-
-    char *filename = g_file_get_path(script);
-    const gchar *coverage_paths[] = {
-        filename,
-        NULL
-    };
-
-    char *retval = serialize_ast_to_object_notation(coverage, coverage_paths);
-    g_free(filename);
-    return retval;
-}
-
-static void
-test_coverage_cache_data_in_expected_format(gpointer      fixture_data,
-                                            gconstpointer user_data)
-{
-    GjsCoverageFixture *fixture = (GjsCoverageFixture *) fixture_data;
-    GjsCoverageCacheObjectNotationTableTestData *table_data = (GjsCoverageCacheObjectNotationTableTestData 
*) user_data;
-
-    replace_file(fixture->tmp_js_script, table_data->script);
-    char *cache_in_object_notation = eval_file_for_ast_in_object_notation(fixture->context,
-                                                                          fixture->coverage,
-                                                                          fixture->tmp_js_script);
-    g_assert(cache_in_object_notation != NULL);
-
-    GTimeVal mtime;
-    bool successfully_got_mtime = gjs_get_file_mtime(fixture->tmp_js_script, &mtime);
-    g_assert_true(successfully_got_mtime);
-
-    char *mtime_string = g_strdup_printf("[%li,%li]", mtime.tv_sec, mtime.tv_usec);
-    GString *expected_cache_object_notation = format_expected_cache_object_notation(mtime_string,
-                                                                                    "null",
-                                                                                    fixture->tmp_js_script,
-                                                                                    
table_data->expected_branches);
-
-    g_assert_cmpstr(cache_in_object_notation, ==, expected_cache_object_notation->str);
-
-    g_string_free(expected_cache_object_notation, true);
-    g_free(cache_in_object_notation);
-    g_free(mtime_string);
-}
-
-static void
-test_coverage_cache_data_in_expected_format_resource(gpointer      fixture_data,
-                                                     gconstpointer user_data)
-{
-    GjsCoverageFixture *fixture = (GjsCoverageFixture *) fixture_data;
-    GjsCoverageCacheObjectNotationTableTestData *table_data = (GjsCoverageCacheObjectNotationTableTestData 
*) user_data;
-
-    GFile *resource = g_file_new_for_uri(table_data->uri);
-
-    char *hash_string_no_quotes = gjs_get_file_checksum(resource);
-
-    char *hash_string = g_strdup_printf("\"%s\"", hash_string_no_quotes);
-    g_free(hash_string_no_quotes);
-
-    GString *expected_cache_object_notation = format_expected_cache_object_notation("null",
-                                                                                    hash_string,
-                                                                                    resource,
-                                                                                    
table_data->expected_branches);
-
-    g_clear_object(&fixture->coverage);
-    fixture->coverage = create_coverage_for_script(fixture->context, resource,
-                                                   fixture->tmp_output_dir);
-    char *cache_in_object_notation = eval_file_for_ast_in_object_notation(fixture->context,
-                                                                          fixture->coverage,
-                                                                          resource);
-    g_object_unref(resource);
-
-    g_assert_cmpstr(cache_in_object_notation, ==, expected_cache_object_notation->str);
-
-    g_string_free(expected_cache_object_notation, true);
-    g_free(cache_in_object_notation);
-    g_free(hash_string);
-}
-
-static char *
-generate_coverage_compartment_verify_script(GFile      *coverage_script,
-                                            const char *user_script)
-{
-    char *coverage_script_filename = g_file_get_path(coverage_script);
-    char *retval =
-        g_strdup_printf("const covered_script_filename = '%s';\n"
-                        "function assertEquals(lhs, rhs) {\n"
-                        "    if (lhs !== rhs)\n"
-                        "        throw new Error('Assertion failure');\n"
-                        "}\n"
-                        "function assertArrayEquals(lhs, rhs) {\n"
-                        "    assertEquals(lhs.length, rhs.length);\n"
-                        "    for (let i = 0; i < lhs.length; i++)\n"
-                        "        assertEquals(lhs[i], rhs[i]);\n"
-                        "}\n"
-                        "\n"
-                        "%s", coverage_script_filename, user_script);
-    g_free(coverage_script_filename);
-    return retval;
-}
-
-static void
-test_coverage_cache_as_js_object_has_branches_prop(void       *fixture_data,
-                                                   const void *unused)
-{
-    auto fixture = static_cast<GjsCoverageFixture *>(fixture_data);
-    const char *script =
-        "let i = 0;\n"
-        "if (i) {\n"
-        "    i = 1;\n"
-        "} else {\n"
-        "    i = 2;\n"
-        "}\n";
-
-    replace_file(fixture->tmp_js_script, script);
-    eval_script(fixture->context, fixture->tmp_js_script);
-
-    char *script_filename = g_file_get_path(fixture->tmp_js_script);
-    const gchar *coverage_paths[] = {
-        script_filename,
-        NULL
-    };
-
-    GBytes *cache = serialize_ast_to_bytes(fixture->coverage, coverage_paths);
-    auto cx = static_cast<JSContext *>(gjs_context_get_native_context(fixture->context));
-    JS::RootedValue cache_result_value(cx,
-        JS::StringValue(gjs_deserialize_cache_to_object(fixture->coverage, cache)));
-    gjs_inject_value_into_coverage_compartment(fixture->coverage,
-                                               cache_result_value,
-                                               "coverage_cache");
-
-    const char *verify_script =
-        "assertEquals(2, JSON.parse(coverage_cache)[covered_script_filename].branches[0].point);\n"
-        "assertArrayEquals([3, 5], 
JSON.parse(coverage_cache)[covered_script_filename].branches[0].exits);\n";
-    char *verify_script_complete = generate_coverage_compartment_verify_script(fixture->tmp_js_script,
-                                                                               verify_script);
-    gjs_run_script_in_coverage_compartment(fixture->coverage,
-                                           verify_script_complete);
-    g_free(verify_script_complete);
-    g_free(script_filename);
-    g_bytes_unref(cache);
-}
-
-typedef struct _GjsCoverageCacheEqualResultsTableTestData {
-    const char *test_name;
-    const char *script;
-} GjsCoverageCacheEqualResultsTableTestData;
-
-
-static GFile *
-get_coverage_tmp_cache(void)
-{
-    GFileIOStream *stream;
-    GError *error = NULL;
-    GFile *cache_file = g_file_new_tmp("gjs-coverage-cache-XXXXXX", &stream, &error);
-    g_assert_no_error(error);
-    g_assert_nonnull(cache_file);
-    g_object_unref(stream);
-
-    return cache_file;
-}
-
-static GFile *
-write_cache_to_temporary_file(GBytes *cache)
-{
-    GFile *temporary_file = get_coverage_tmp_cache();
-
-    if (!gjs_write_cache_file(temporary_file, cache)) {
-        g_object_unref(temporary_file);
-        return NULL;
-    }
-
-    return temporary_file;
-}
-
-static GFile *
-serialize_ast_to_cache_in_temporary_file(GjsCoverage *coverage,
-                                         const char  **coverage_paths)
-{
-    GBytes   *cache = serialize_ast_to_bytes(coverage, coverage_paths);
-    GFile *cache_file = write_cache_to_temporary_file(cache);
-
-    g_bytes_unref(cache);
-
-    return cache_file;
-}
-
-static void
-test_coverage_cache_equal_results_to_reflect_parse(gpointer      fixture_data,
-                                                   gconstpointer user_data)
-{
-    GjsCoverageFixture *fixture = (GjsCoverageFixture *) fixture_data;
-    GjsCoverageCacheEqualResultsTableTestData *equal_results_data = 
(GjsCoverageCacheEqualResultsTableTestData *) user_data;
-
-    replace_file(fixture->tmp_js_script, equal_results_data->script);
-
-    char *tmp_js_script_filename = g_file_get_path(fixture->tmp_js_script);
-    const gchar *coverage_paths[] = {
-        tmp_js_script_filename,
-        NULL
-    };
-
-    char *coverage_data_contents_no_cache =
-        eval_script_and_get_coverage_data(fixture->context,
-                                          fixture->coverage,
-                                          fixture->tmp_js_script,
-                                          fixture->lcov_output,
-                                          NULL);
-    GFile *cache_file = serialize_ast_to_cache_in_temporary_file(fixture->coverage,
-                                                                 coverage_paths);
-    g_assert_nonnull(cache_file);
-
-    g_clear_object(&fixture->coverage);
-    fixture->coverage = create_coverage_for_script_and_cache(fixture->context,
-                                                             cache_file,
-                                                             fixture->tmp_js_script,
-                                                             fixture->lcov_output_dir);
-    g_object_unref(cache_file);
-
-    /* Overwrite tracefile with nothing and start over */
-    replace_file(fixture->lcov_output, "");
-
-    char *coverage_data_contents_cached =
-        eval_script_and_get_coverage_data(fixture->context,
-                                          fixture->coverage,
-                                          fixture->tmp_js_script,
-                                          fixture->lcov_output,
-                                          NULL);
-
-    g_assert_cmpstr(coverage_data_contents_cached, ==, coverage_data_contents_no_cache);
-
-    g_free(coverage_data_contents_cached);
-    g_free(coverage_data_contents_no_cache);
-    g_free(tmp_js_script_filename);
-}
-
-static GFile *
-eval_file_for_tmp_ast_cache(GjsContext  *context,
-                            GjsCoverage *coverage,
-                            GFile       *script)
-{
-    bool success = eval_script(context, script);
-    g_assert_true(success);
-
-    char *filename = g_file_get_path(script);
-    const gchar *coverage_paths[] = {
-        filename,
-        NULL
-    };
-
-    GFile *retval = serialize_ast_to_cache_in_temporary_file(coverage,
-                                                             coverage_paths);
-    g_free(filename);
-    return retval;
-}
-
-static void
-rewind_file_mtime(GFile *file)
-{
-    GjsAutoUnref<GFileInfo> info = g_file_query_info(file,
-                                                     G_FILE_ATTRIBUTE_TIME_MODIFIED,
-                                                     G_FILE_QUERY_INFO_NONE,
-                                                     nullptr, nullptr);
-    g_assert_nonnull(info);
-
-    GTimeVal mtime;
-    g_file_info_get_modification_time(info, &mtime);
-
-    g_assert_cmpint(mtime.tv_sec, >, 0);
-    mtime.tv_sec--;
-    g_file_info_set_modification_time(info, &mtime);
-
-    gboolean ok = g_file_set_attributes_from_info(file, info,
-                                                  G_FILE_QUERY_INFO_NONE,
-                                                  nullptr, nullptr);
-    g_assert_true(ok);
-}
-
-/* Effectively, the results should be what we expect even though
- * we overwrote the original script after getting coverage and
- * fetching the cache */
-static void
-test_coverage_cache_invalidation(gpointer      fixture_data,
-                                 gconstpointer user_data)
-{
-    GjsCoverageFixture *fixture = (GjsCoverageFixture *) fixture_data;
-
-    GFile *cache_file = eval_file_for_tmp_ast_cache(fixture->context,
-                                                    fixture->coverage,
-                                                    fixture->tmp_js_script);
-
-    rewind_file_mtime(cache_file);
-
-    /* Overwrite tracefile with nothing */
-    replace_file(fixture->lcov_output, "");
-
-    /* Write a new script into the temporary js file, which will be
-     * completely different to the original script that was there */
-    replace_file(fixture->tmp_js_script,
-                 "let i = 0;\n"
-                 "let j = 0;\n");
-
-    g_clear_object(&fixture->coverage);
-    fixture->coverage = create_coverage_for_script_and_cache(fixture->context,
-                                                             cache_file,
-                                                             fixture->tmp_js_script,
-                                                             fixture->lcov_output_dir);
-    g_object_unref(cache_file);
-
-    gsize coverage_data_len = 0;
-    char *coverage_data_contents =
-        eval_script_and_get_coverage_data(fixture->context,
-                                          fixture->coverage,
-                                          fixture->tmp_js_script,
-                                          fixture->lcov_output,
-                                          &coverage_data_len);
-
-    LineCountIsMoreThanData matchers[] =
-    {
-        {
-            1,
-            0
-        },
-        {
-            2,
-            0
-        }
-    };
-
-    char *script_output_path = get_output_path_for_script_on_disk(fixture->tmp_js_script,
-                                                                  fixture->lcov_output_dir);
-
-    ExpectedSourceFileCoverageData expected[] = {
-        {
-            script_output_path,
-            matchers,
-            2,
-            '2',
-            '2'
-        }
-    };
-
-    const gsize expected_len = G_N_ELEMENTS(expected);
-    const char *record = line_starting_with(coverage_data_contents, "SF:");
-    g_assert_nonnull(record);
-    g_assert(check_coverage_data_for_source_file(expected, expected_len, record));
-
-    g_free(script_output_path);
-    g_free(coverage_data_contents);
-}
-
-static void
-unload_resource(GResource *resource)
-{
-    g_resources_unregister(resource);
-    g_resource_unref(resource);
-}
-
-static GResource *
-load_resource_from_builddir(const char *name)
-{
-    char *resource_path = g_build_filename(GJS_TOP_BUILDDIR,
-                                           name,
-                                           NULL);
-
-    GError    *error = NULL;
-    GResource *resource = g_resource_load(resource_path,
-                                          &error);
-
-    g_assert_no_error(error);
-    g_resources_register(resource);
-
-    g_free(resource_path);
-
-    return resource;
-}
-
-/* Load first resource, then unload and load second resource. Both have
- * the same path, but different contents */
-static void
-test_coverage_cache_invalidation_resource(gpointer      fixture_data,
-                                          gconstpointer user_data)
-{
-    GjsCoverageFixture *fixture = (GjsCoverageFixture *) fixture_data;
-
-    GFile *mock_resource = g_file_new_for_uri("resource:///org/gnome/gjs/mock/cache/resource.js");
-
-    /* Load the resource archive and register it */
-    GResource *first_resource = load_resource_from_builddir("mock-cache-invalidation-before.gresource");
-
-    g_clear_object(&fixture->coverage);
-    fixture->coverage = create_coverage_for_script(fixture->context,
-                                                   mock_resource,
-                                                   fixture->lcov_output_dir);
-
-    GFile *cache_file = eval_file_for_tmp_ast_cache(fixture->context,
-                                                    fixture->coverage,
-                                                    mock_resource);
-
-    /* Load the "after" resource, but have the exact same coverage paths */
-    unload_resource(first_resource);
-    GResource *second_resource = load_resource_from_builddir("mock-cache-invalidation-after.gresource");
-
-    /* Overwrite tracefile with nothing */
-    replace_file(fixture->lcov_output, "");
-
-    g_clear_object(&fixture->coverage);
-    fixture->coverage = create_coverage_for_script_and_cache(fixture->context,
-                                                             cache_file,
-                                                             mock_resource,
-                                                             fixture->lcov_output_dir);
-    g_object_unref(cache_file);
-
-    char *coverage_data_contents =
-        eval_script_and_get_coverage_data(fixture->context, fixture->coverage,
-                                          mock_resource, fixture->lcov_output,
-                                          NULL);
-
-    /* Don't need this anymore */
-    g_object_unref(mock_resource);
-    unload_resource(second_resource);
-
-    /* Now assert that the coverage file has executable lines in
-     * the places that we expect them to be */
-    LineCountIsMoreThanData matchers[] = {
-        {
-            1,
-            0
-        },
-        {
-            2,
-            0
-        }
-    };
-
-    GFile *output_script =
-        g_file_resolve_relative_path(fixture->lcov_output_dir,
-                                     "org/gnome/gjs/mock/cache/resource.js");
-    char *script_output_path = g_file_get_path(output_script);
-    g_object_unref(output_script);
-
-    ExpectedSourceFileCoverageData expected[] = {
-        {
-            script_output_path,
-            matchers,
-            2,
-            '2',
-            '2'
-        }
-    };
-
-    const gsize expected_len = G_N_ELEMENTS(expected);
-    const char *record = line_starting_with(coverage_data_contents, "SF:");
-    g_assert(check_coverage_data_for_source_file(expected, expected_len, record));
-
-    g_free(script_output_path);
-    g_free(coverage_data_contents);
-}
-
-static void
-test_coverage_cache_file_written_when_no_cache_exists(gpointer      fixture_data,
-                                                      gconstpointer user_data)
-{
-    GjsCoverageFixture *fixture = (GjsCoverageFixture *) fixture_data;
-    GFile *cache_file = get_coverage_tmp_cache();
-
-    g_clear_object(&fixture->coverage);
-    fixture->coverage = create_coverage_for_script_and_cache(fixture->context,
-                                                             cache_file,
-                                                             fixture->tmp_js_script,
-                                                             fixture->lcov_output_dir);
-
-    /* We need to execute the script now in order for a cache entry
-     * to be created, since unexecuted scripts are not counted as
-     * part of the coverage report. */
-    bool success = eval_script(fixture->context, fixture->tmp_js_script);
-    g_assert_true(success);
-
-    gjs_coverage_write_statistics(fixture->coverage);
-
-    g_assert_true(g_file_query_exists(cache_file, NULL));
-    g_object_unref(cache_file);
-}
-
-static GTimeVal
-eval_script_for_cache_mtime(GjsContext  *context,
-                            GjsCoverage *coverage,
-                            GFile       *cache_file,
-                            GFile       *script)
-{
-    bool success = eval_script(context, script);
-    g_assert_true(success);
-
-    gjs_coverage_write_statistics(coverage);
-
-    GTimeVal mtime;
-    bool successfully_got_mtime = gjs_get_file_mtime(cache_file, &mtime);
-    g_assert_true(successfully_got_mtime);
-
-    return mtime;
-}
-
-static void
-test_coverage_cache_updated_when_cache_stale(gpointer      fixture_data,
-                                             gconstpointer user_data)
-{
-    GjsCoverageFixture *fixture = (GjsCoverageFixture *) fixture_data;
-
-    GFile *cache_file = get_coverage_tmp_cache();
-    g_clear_object(&fixture->coverage);
-    fixture->coverage = create_coverage_for_script_and_cache(fixture->context,
-                                                             cache_file,
-                                                             fixture->tmp_js_script,
-                                                             fixture->lcov_output_dir);
-
-    GTimeVal first_cache_mtime = eval_script_for_cache_mtime(fixture->context,
-                                                             fixture->coverage,
-                                                             cache_file,
-                                                             fixture->tmp_js_script);
-
-    rewind_file_mtime(cache_file);
-
-    /* Write a new script into the temporary js file, which will be
-     * completely different to the original script that was there */
-    replace_file(fixture->tmp_js_script,
-                 "let i = 0;\n"
-                 "let j = 0;\n");
-
-    /* Re-create coverage object, covering new script */
-    g_clear_object(&fixture->coverage);
-    fixture->coverage = create_coverage_for_script_and_cache(fixture->context,
-                                                             cache_file,
-                                                             fixture->tmp_js_script,
-                                                             fixture->lcov_output_dir);
-
-
-    /* Run the script again, which will cause an attempt
-     * to look up the AST data. Upon writing the statistics
-     * again, the cache should have been missed some of the time
-     * so the second mtime will be greater than the first */
-    GTimeVal second_cache_mtime = eval_script_for_cache_mtime(fixture->context,
-                                                              fixture->coverage,
-                                                              cache_file,
-                                                              fixture->tmp_js_script);
-
-
-    const bool seconds_different = (first_cache_mtime.tv_sec != second_cache_mtime.tv_sec);
-    const bool microseconds_different = (first_cache_mtime.tv_usec != second_cache_mtime.tv_usec);
-
-    g_assert_true(seconds_different || microseconds_different);
-
-    g_object_unref(cache_file);
-}
-
-static void
-test_coverage_cache_not_updated_on_full_hits(gpointer      fixture_data,
-                                             gconstpointer user_data)
-{
-    GjsCoverageFixture *fixture = (GjsCoverageFixture *) fixture_data;
-
-    GFile *cache_file = get_coverage_tmp_cache();
-    g_clear_object(&fixture->coverage);
-    fixture->coverage = create_coverage_for_script_and_cache(fixture->context,
-                                                             cache_file,
-                                                             fixture->tmp_js_script,
-                                                             fixture->lcov_output_dir);
-
-    GTimeVal first_cache_mtime = eval_script_for_cache_mtime(fixture->context,
-                                                             fixture->coverage,
-                                                             cache_file,
-                                                             fixture->tmp_js_script);
-
-    /* Re-create coverage object, covering same script */
-    g_clear_object(&fixture->coverage);
-    fixture->coverage = create_coverage_for_script_and_cache(fixture->context,
-                                                             cache_file,
-                                                             fixture->tmp_js_script,
-                                                             fixture->lcov_output_dir);
-
-
-    /* Run the script again, which will cause an attempt
-     * to look up the AST data. Upon writing the statistics
-     * again, the cache should have been hit of the time
-     * so the second mtime will be the same as the first */
-    GTimeVal second_cache_mtime = eval_script_for_cache_mtime(fixture->context,
-                                                              fixture->coverage,
-                                                              cache_file,
-                                                              fixture->tmp_js_script);
-
-    g_assert_cmpint(first_cache_mtime.tv_sec, ==, second_cache_mtime.tv_sec);
-    g_assert_cmpint(first_cache_mtime.tv_usec, ==, second_cache_mtime.tv_usec);
-
-    g_object_unref(cache_file);
-}
-
 typedef struct _FixturedTest {
     gsize            fixture_size;
     GTestFixtureFunc set_up;
@@ -2114,41 +1398,6 @@ add_test_for_fixture(const char      *name,
                       fixture->tear_down);
 }
 
-/* All table driven tests must be binary compatible with at
- * least this header */
-typedef struct _TestTableDataHeader {
-    const char *test_name;
-} TestTableDataHeader;
-
-static void
-add_table_driven_test_for_fixture(const char                *name,
-                                  FixturedTest              *fixture,
-                                  GTestFixtureFunc          test_func,
-                                  gsize                     table_entry_size,
-                                  gsize                     n_table_entries,
-                                  const TestTableDataHeader *test_table)
-{
-    const char  *test_table_ptr = (const char *)test_table;
-    gsize test_table_index;
-
-    for (test_table_index = 0;
-         test_table_index < n_table_entries;
-         ++test_table_index, test_table_ptr += table_entry_size) {
-        const TestTableDataHeader *header =
-            reinterpret_cast<const TestTableDataHeader *>(test_table_ptr);
-        gchar *test_name_for_table_index = g_strdup_printf("%s/%s",
-                                                           name,
-                                                           header->test_name);
-        g_test_add_vtable(test_name_for_table_index,
-                          fixture->fixture_size,
-                          test_table_ptr,
-                          fixture->set_up,
-                          test_func,
-                          fixture->tear_down);
-        g_free(test_name_for_table_index);
-    }
-}
-
 void gjs_test_add_tests_for_coverage()
 {
     FixturedTest coverage_fixture = {
@@ -2256,105 +1505,4 @@ void gjs_test_add_tests_for_coverage()
                          &coverage_for_multiple_files_to_single_output_fixture,
                          test_correct_line_coverage_data_written_for_both_source_file_sectons,
                          NULL);
-
-    /* This must be static, because g_test_add_vtable does not copy it */
-    static GjsCoverageCacheObjectNotationTableTestData data_in_expected_format_table[] = {
-        {
-            "simple_executable_lines",
-            "let i = 0;\n",
-            "resource://org/gnome/gjs/mock/test/gjs-test-coverage/cache_notation/simple_executable_lines.js",
-            ""
-        },
-        {
-            "simple_branch",
-            "let i = 0;\n"
-            "if (i) {\n"
-            "    i = 1;\n"
-            "} else {\n"
-            "    i = 2;\n"
-            "}\n",
-            "resource://org/gnome/gjs/mock/test/gjs-test-coverage/cache_notation/simple_branch.js",
-            "\"point\":2,\"exits\":[3,5]"
-        },
-        {
-            "simple_function",
-            "function f() {\n"
-            "}\n",
-            "resource://org/gnome/gjs/mock/test/gjs-test-coverage/cache_notation/simple_function.js",
-            ""
-        }
-    };
-
-    add_table_driven_test_for_fixture("/gjs/coverage/cache/data_format",
-                                      &coverage_fixture,
-                                      test_coverage_cache_data_in_expected_format,
-                                      sizeof(GjsCoverageCacheObjectNotationTableTestData),
-                                      G_N_ELEMENTS(data_in_expected_format_table),
-                                      (const TestTableDataHeader *) data_in_expected_format_table);
-
-    add_table_driven_test_for_fixture("/gjs/coverage/cache/data_format_resource",
-                                      &coverage_fixture,
-                                      test_coverage_cache_data_in_expected_format_resource,
-                                      sizeof(GjsCoverageCacheObjectNotationTableTestData),
-                                      G_N_ELEMENTS(data_in_expected_format_table),
-                                      (const TestTableDataHeader *) data_in_expected_format_table);
-
-    add_test_for_fixture("/gjs/coverage/cache/object_branches_prop",
-                         &coverage_fixture,
-                         test_coverage_cache_as_js_object_has_branches_prop,
-                         NULL);
-
-    static GjsCoverageCacheEqualResultsTableTestData equal_results_table[] = {
-        {
-            "simple_executable_lines",
-            "let i = 0;\n"
-            "let j = 1;\n"
-        },
-        {
-            "simple_branch",
-            "let i = 0;\n"
-            "if (i) {\n"
-            "    i = 1;\n"
-            "} else {\n"
-            "    i = 2;\n"
-            "}\n"
-        },
-        {
-            "simple_function",
-            "function f() {\n"
-            "}\n"
-        }
-    };
-
-    add_table_driven_test_for_fixture("/gjs/coverage/cache/equal/executable_lines",
-                                      &coverage_fixture,
-                                      test_coverage_cache_equal_results_to_reflect_parse,
-                                      sizeof(GjsCoverageCacheEqualResultsTableTestData),
-                                      G_N_ELEMENTS(equal_results_table),
-                                      (const TestTableDataHeader *) equal_results_table);
-
-    add_test_for_fixture("/gjs/coverage/cache/invalidation",
-                         &coverage_fixture,
-                         test_coverage_cache_invalidation,
-                         NULL);
-
-    add_test_for_fixture("/gjs/coverage/cache/invalidation_resource",
-                         &coverage_fixture,
-                         test_coverage_cache_invalidation_resource,
-                         NULL);
-
-    add_test_for_fixture("/gjs/coverage/cache/file_written",
-                         &coverage_fixture,
-                         test_coverage_cache_file_written_when_no_cache_exists,
-                         NULL);
-
-    add_test_for_fixture("/gjs/coverage/cache/no_update_on_full_hits",
-                         &coverage_fixture,
-                         test_coverage_cache_not_updated_on_full_hits,
-                         NULL);
-
-    add_test_for_fixture("/gjs/coverage/cache/update_on_misses",
-                         &coverage_fixture,
-                         test_coverage_cache_updated_when_cache_stale,
-                         NULL);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]