read-coverage.js 3.72 KB
Newer Older
lxyang committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
// import { MAGIC_KEY, MAGIC_VALUE } from './constants';
// import { parse } from 'babylon';
const traverse = require('babel-traverse')
// import * as t from 'babel-types';
const { parseSync } = require('@babel/core')
const { defaults } = require('@istanbuljs/schema')
const { MAGIC_KEY, MAGIC_VALUE } = require('./constants')

function getAst (code) {
    if (typeof code === 'object' && typeof code.type === 'string') {
        return code
    }

    if (typeof code !== 'string') {
        throw new Error('Code must be a string')
    }
    return parseSync(code, {
        babelrc: false,
        configFile: false,
        parserOpts: {
            allowAwaitOutsideFunction: true,
            allowImportExportEverywhere: true,
            allowReturnOutsideFunction: true,
            allowSuperOutsideMethod: true,
            sourceType: 'script',
            plugins: defaults.instrumenter.parserPlugins
        }
    })
}
module.exports = function readInitialCoverage (code) {
    const ast = getAst(code)
    let covScope
    traverse(ast, {
        ObjectProperty: function (path) {
            const { node } = path;
            if (!node.computed &&
                path.get('key').isIdentifier() &&
                node.key.name === MAGIC_KEY)
            {
                const magicValue = path.get('value').evaluate()
                if (!magicValue.confident || magicValue.value !== MAGIC_VALUE) {
                    return
                }
                covScope = path.scope.getFunctionParent() || path.scope.getProgramParent()
                path.stop()
            }
        }
    })
    if (!covScope) {
        return null
    }

    const result = {}
    for (const key of ['path', 'hash', 'gcv', 'coverageData']) {
        const binding = covScope.getOwnBinding(key)
        if (!binding) {
            return null
        }
        const valuePath = binding.path.get('init')
        const value = valuePath.evaluate()
        if (!value.confident) {
            return null
        }
        result[key] = value.value
    }

    delete result.coverageData[MAGIC_KEY]
    delete result.coverageData.hash

    return result
} 
// export default function readInitialCoverage (code) {
//     if (typeof code !== 'string') {
//         throw new Error('Code must be a string');
//     }

//     // Parse as leniently as possible
//     const ast = parse(code, {
//         allowImportExportEverywhere: true,
//         allowReturnOutsideFunction: true,
//         allowSuperOutsideMethod: true,
//         sourceType: "script", // I think ?
//         plugins: ["*"]
//     });

//     let covScope;
//     traverse(ast, {
//         ObjectProperty: function (path) {
//             const { node } = path;
//             if (!node.computed &&
//                 t.isIdentifier(node.key) &&
//                 node.key.name === MAGIC_KEY)
//             {
//                 const magicValue = path.get('value').evaluate();
//                 if (!magicValue.confident || magicValue.value !== MAGIC_VALUE) {
//                     return;
//                 }
//                 covScope = path.scope.getFunctionParent();
//                 path.stop();
//             }
//         }
//     });

//     if (!covScope) {
//         return null;
//     }

//     const result = {};

//     for (const key of ['path', 'hash', 'gcv', 'coverageData']) {
//         const binding = covScope.getOwnBinding(key);
//         if (!binding) {
//             return null;
//         }
//         const valuePath = binding.path.get('init');
//         const value = valuePath.evaluate();
//         if (!value.confident) {
//             return null;
//         }
//         result[key] = value.value;
//     }

//     delete result.coverageData[MAGIC_KEY];
    
//     return result;
// }