fork from https://github.com/mozilla/pdf.js.git
This commit is contained in:
40
external/ccov/coverage_format.mjs
vendored
Normal file
40
external/ccov/coverage_format.mjs
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/* Copyright 2026 Mozilla Foundation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
const COVERAGE_FORMAT_TO_REPORTER = {
|
||||
info: "lcovonly",
|
||||
html: "html",
|
||||
json: "json",
|
||||
text: "text",
|
||||
cobertura: "cobertura",
|
||||
clover: "clover",
|
||||
};
|
||||
|
||||
function parseCoverageFormats(str) {
|
||||
const formats = new Set();
|
||||
for (const fmt of (str ?? "").split(",")) {
|
||||
const name = fmt.trim();
|
||||
if (name && COVERAGE_FORMAT_TO_REPORTER[name]) {
|
||||
formats.add(name);
|
||||
} else if (name) {
|
||||
console.warn(
|
||||
`### Unknown coverage format "${name}", valid values: ${Object.keys(COVERAGE_FORMAT_TO_REPORTER).join(", ")}`
|
||||
);
|
||||
}
|
||||
}
|
||||
return formats.size > 0 ? formats : new Set(["info"]);
|
||||
}
|
||||
|
||||
export { COVERAGE_FORMAT_TO_REPORTER, parseCoverageFormats };
|
||||
110
external/ccov/coverage_search.mjs
vendored
Normal file
110
external/ccov/coverage_search.mjs
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
/* Copyright 2026 Mozilla Foundation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import fs from "fs";
|
||||
import { parseArgs } from "node:util";
|
||||
import path from "path";
|
||||
|
||||
const __dirname = import.meta.dirname;
|
||||
const PROJECT_ROOT = path.join(__dirname, "../..");
|
||||
|
||||
const { values } = parseArgs({
|
||||
args: process.argv.slice(2),
|
||||
options: {
|
||||
code: { type: "string" },
|
||||
"coverage-dir": { type: "string", default: "build/coverage" },
|
||||
help: { type: "boolean", short: "h", default: false },
|
||||
},
|
||||
});
|
||||
|
||||
if (values.help || !values.code) {
|
||||
console.log(
|
||||
"Usage: coverage_search.mjs --code=<file>::<line|function> [--coverage-dir=<path>]\n\n" +
|
||||
" --code Source file and line number or function name to search for.\n" +
|
||||
" Examples:\n" +
|
||||
" --code=canvas.js::205\n" +
|
||||
" --code=canvas.js::drawImageAtIntegerCoords\n" +
|
||||
" --coverage-dir Coverage directory containing per-test-index.json [build/coverage]\n\n" +
|
||||
"Prints to stdout the IDs of tests whose coverage includes the given line or\n" +
|
||||
"function (one ID per line).\n" +
|
||||
"Run browsertest with --coverage-per-test first to generate the index."
|
||||
);
|
||||
process.exit(values.help ? 0 : 1);
|
||||
}
|
||||
|
||||
const sep = values.code.indexOf("::");
|
||||
if (sep === -1) {
|
||||
console.error(
|
||||
"Error: --code must be in format 'file.js::line_or_function', e.g. canvas.js::205"
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const fileName = values.code.slice(0, sep);
|
||||
const location = values.code.slice(sep + 2);
|
||||
const isLine = /^\d+$/.test(location);
|
||||
const lineNum = isLine ? parseInt(location, 10) : null;
|
||||
const funcName = isLine ? null : location;
|
||||
|
||||
const coverageDir = path.isAbsolute(values["coverage-dir"])
|
||||
? values["coverage-dir"]
|
||||
: path.join(PROJECT_ROOT, values["coverage-dir"]);
|
||||
|
||||
const indexPath = path.join(coverageDir, "per-test-index.json");
|
||||
if (!fs.existsSync(indexPath)) {
|
||||
console.error(`Error: index file not found: ${indexPath}`);
|
||||
console.error("Run browsertest with --coverage-per-test first.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const { ids, files } = JSON.parse(fs.readFileSync(indexPath, "utf8"));
|
||||
|
||||
// Find the file entry whose path matches fileName.
|
||||
let fileEntry = null;
|
||||
for (const [filePath, entry] of Object.entries(files)) {
|
||||
if (
|
||||
filePath === fileName ||
|
||||
filePath.endsWith(`/${fileName}`) ||
|
||||
filePath.endsWith(`\\${fileName}`)
|
||||
) {
|
||||
fileEntry = entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fileEntry) {
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
let testIndices = null;
|
||||
|
||||
if (lineNum !== null) {
|
||||
// Direct line lookup.
|
||||
testIndices = fileEntry.l?.[lineNum];
|
||||
|
||||
// If no hit, check whether lineNum is a function declaration start and
|
||||
// redirect to that function's coverage.
|
||||
if (!testIndices && fileEntry.fstarts?.[lineNum]) {
|
||||
testIndices = fileEntry.f?.[fileEntry.fstarts[lineNum]];
|
||||
}
|
||||
} else {
|
||||
testIndices = fileEntry.f?.[funcName];
|
||||
}
|
||||
|
||||
if (testIndices) {
|
||||
for (const idx of testIndices) {
|
||||
console.log(ids[idx]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user