first commit
Some checks failed
Types tests / Test (lts/*) (push) Has been cancelled
Lint / Lint (lts/*) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CI / Test (20) (push) Has been cancelled
CI / Test (22) (push) Has been cancelled
CI / Test (24) (push) Has been cancelled
Some checks failed
Types tests / Test (lts/*) (push) Has been cancelled
Lint / Lint (lts/*) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CI / Test (20) (push) Has been cancelled
CI / Test (22) (push) Has been cancelled
CI / Test (24) (push) Has been cancelled
This commit is contained in:
36
test/font/README.md
Normal file
36
test/font/README.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Font tests
|
||||
|
||||
The font tests check if PDF.js can read font data correctly. For validation
|
||||
the `ttx` tool (from the Python `fonttools` library) is used that can convert
|
||||
font data to an XML format that we can easily use for assertions in the tests.
|
||||
In the font tests we let PDF.js read font data and pass the PDF.js-interpreted
|
||||
font data through `ttx` to check its correctness. The font tests are successful
|
||||
if PDF.js can successfully read the font data and `ttx` can successfully read
|
||||
the PDF.js-interpreted font data back, proving that PDF.js does not apply any
|
||||
transformations that break the font data.
|
||||
|
||||
## Running the font tests
|
||||
|
||||
The font tests are run on GitHub Actions using the workflow defined in
|
||||
`.github/workflows/font_tests.yml`, but it is also possible to run the font
|
||||
tests locally. The current stable versions of the following dependencies are
|
||||
required to be installed on the system:
|
||||
|
||||
- Python 3
|
||||
- `fonttools` (see https://pypi.org/project/fonttools and https://github.com/fonttools/fonttools)
|
||||
|
||||
The recommended way of installing `fonttools` is using `pip` in a virtual
|
||||
environment because it avoids having to do a system-wide installation and
|
||||
therefore improves isolation, but any other way of installing `fonttools`
|
||||
that makes `ttx` available in the `PATH` environment variable also works.
|
||||
|
||||
Using the virtual environment approach the font tests can be run locally by
|
||||
creating and sourcing a virtual environment with `fonttools` installed in
|
||||
it before running the font tests:
|
||||
|
||||
```
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
pip install fonttools
|
||||
npx gulp fonttest
|
||||
```
|
||||
18
test/font/font_core_spec.js
Normal file
18
test/font/font_core_spec.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import { decodeFontData, ttx, verifyTtxOutput } from "./fontutils.js";
|
||||
|
||||
describe("font1", function () {
|
||||
const font1_1 = decodeFontData(
|
||||
// eslint-disable-next-line max-len
|
||||
"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"
|
||||
);
|
||||
|
||||
describe("test harness testing", function () {
|
||||
it("returns output", async function () {
|
||||
const output = await ttx(font1_1);
|
||||
|
||||
verifyTtxOutput(output);
|
||||
expect(/<ttFont /.test(output)).toEqual(true);
|
||||
expect(/<\/ttFont>/.test(output)).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
45
test/font/font_fpgm_spec.js
Normal file
45
test/font/font_fpgm_spec.js
Normal file
File diff suppressed because one or more lines are too long
71
test/font/font_os2_spec.js
Normal file
71
test/font/font_os2_spec.js
Normal file
File diff suppressed because one or more lines are too long
93
test/font/font_post_spec.js
Normal file
93
test/font/font_post_spec.js
Normal file
File diff suppressed because one or more lines are too long
25
test/font/font_test.html
Normal file
25
test/font/font_test.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>PDF.js font tests</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="../../node_modules/jasmine-core/lib/jasmine-core/jasmine.css">
|
||||
|
||||
<script src="../../node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
|
||||
<script src="../../node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
|
||||
|
||||
<script type="importmap">
|
||||
{
|
||||
"imports": {
|
||||
"pdfjs/": "../../src/",
|
||||
"pdfjs-lib": "../../src/pdf.js",
|
||||
"pdfjs-web/": "../../web/",
|
||||
"pdfjs-test/": "../"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<script src="jasmine-boot.js" type="module"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
48
test/font/fontutils.js
Normal file
48
test/font/fontutils.js
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2013 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 { bytesToString, stringToBytes } from "../../src/shared/util.js";
|
||||
|
||||
function decodeFontData(base64) {
|
||||
const str = atob(base64);
|
||||
return stringToBytes(str);
|
||||
}
|
||||
|
||||
function encodeFontData(data) {
|
||||
const str = bytesToString(data);
|
||||
return btoa(str);
|
||||
}
|
||||
|
||||
async function ttx(data) {
|
||||
const response = await fetch("/ttx", {
|
||||
method: "POST",
|
||||
body: encodeFontData(data),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
return response.text();
|
||||
}
|
||||
|
||||
function verifyTtxOutput(output) {
|
||||
const m = /^<error>(.*?)<\/error>/.exec(output);
|
||||
if (m) {
|
||||
throw m[1];
|
||||
}
|
||||
}
|
||||
|
||||
export { decodeFontData, encodeFontData, ttx, verifyTtxOutput };
|
||||
158
test/font/jasmine-boot.js
Normal file
158
test/font/jasmine-boot.js
Normal file
@@ -0,0 +1,158 @@
|
||||
/* Copyright 2016 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.
|
||||
*/
|
||||
/*
|
||||
Copyright (c) 2008-2016 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/* globals jasmineRequire */
|
||||
|
||||
// Modified jasmine's boot.js file to load PDF.js libraries async.
|
||||
|
||||
"use strict";
|
||||
|
||||
import { TestReporter } from "../reporter.js";
|
||||
|
||||
async function initializePDFJS(callback) {
|
||||
await Promise.all(
|
||||
[
|
||||
"pdfjs-test/font/font_core_spec.js",
|
||||
"pdfjs-test/font/font_os2_spec.js",
|
||||
"pdfjs-test/font/font_post_spec.js",
|
||||
"pdfjs-test/font/font_fpgm_spec.js",
|
||||
].map(moduleName => import(moduleName)) // eslint-disable-line no-unsanitized/method
|
||||
);
|
||||
|
||||
callback();
|
||||
}
|
||||
|
||||
(function () {
|
||||
window.jasmine = jasmineRequire.core(jasmineRequire);
|
||||
|
||||
jasmineRequire.html(jasmine);
|
||||
|
||||
const env = jasmine.getEnv();
|
||||
|
||||
const jasmineInterface = jasmineRequire.interface(jasmine, env);
|
||||
extend(window, jasmineInterface);
|
||||
|
||||
// Runner Parameters
|
||||
const queryString = new jasmine.QueryString({
|
||||
getWindowLocation() {
|
||||
return window.location;
|
||||
},
|
||||
});
|
||||
|
||||
const config = {
|
||||
failFast: queryString.getParam("failFast"),
|
||||
oneFailurePerSpec: queryString.getParam("oneFailurePerSpec"),
|
||||
hideDisabled: queryString.getParam("hideDisabled"),
|
||||
};
|
||||
|
||||
const random = queryString.getParam("random");
|
||||
if (random !== undefined && random !== "") {
|
||||
config.random = random;
|
||||
}
|
||||
|
||||
const seed = queryString.getParam("seed");
|
||||
if (seed) {
|
||||
config.seed = seed;
|
||||
}
|
||||
|
||||
// Reporters
|
||||
const htmlReporter = new jasmine.HtmlReporter({
|
||||
env,
|
||||
navigateWithNewParam(key, value) {
|
||||
return queryString.navigateWithNewParam(key, value);
|
||||
},
|
||||
addToExistingQueryString(key, value) {
|
||||
return queryString.fullStringWithNewParam(key, value);
|
||||
},
|
||||
getContainer() {
|
||||
return document.body;
|
||||
},
|
||||
createElement() {
|
||||
return document.createElement(...arguments);
|
||||
},
|
||||
createTextNode() {
|
||||
return document.createTextNode(...arguments);
|
||||
},
|
||||
timer: new jasmine.Timer(),
|
||||
});
|
||||
|
||||
env.addReporter(htmlReporter);
|
||||
|
||||
if (queryString.getParam("browser")) {
|
||||
const testReporter = new TestReporter(queryString.getParam("browser"));
|
||||
env.addReporter(testReporter);
|
||||
}
|
||||
|
||||
// Filter which specs will be run by matching the start of the full name
|
||||
// against the `spec` query param.
|
||||
const specFilter = new jasmine.HtmlSpecFilter({
|
||||
filterString() {
|
||||
return queryString.getParam("spec");
|
||||
},
|
||||
});
|
||||
|
||||
config.specFilter = function (spec) {
|
||||
return specFilter.matches(spec.getFullName());
|
||||
};
|
||||
|
||||
env.configure(config);
|
||||
|
||||
// Sets longer timeout.
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000;
|
||||
|
||||
function extend(destination, source) {
|
||||
for (const property in source) {
|
||||
destination[property] = source[property];
|
||||
}
|
||||
return destination;
|
||||
}
|
||||
|
||||
function fontTestInit() {
|
||||
initializePDFJS(function () {
|
||||
htmlReporter.initialize();
|
||||
env.execute();
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
document.readyState === "interactive" ||
|
||||
document.readyState === "complete"
|
||||
) {
|
||||
fontTestInit();
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", fontTestInit, true);
|
||||
}
|
||||
})();
|
||||
71
test/font/ttxdriver.mjs
Normal file
71
test/font/ttxdriver.mjs
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2014 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 os from "os";
|
||||
import path from "path";
|
||||
import { spawn } from "child_process";
|
||||
|
||||
let ttxTaskId = Date.now();
|
||||
|
||||
function runTtx(fontPath) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const ttx = spawn("ttx", [fontPath], { stdio: "ignore" });
|
||||
ttx.on("error", () => {
|
||||
reject(
|
||||
new Error(
|
||||
"Unable to execute `ttx`; make sure the `fonttools` dependency is installed"
|
||||
)
|
||||
);
|
||||
});
|
||||
ttx.on("close", () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function translateFont(content) {
|
||||
const buffer = Buffer.from(content, "base64");
|
||||
const taskId = (ttxTaskId++).toString();
|
||||
const fontPath = path.join(os.tmpdir(), `pdfjs-font-test-${taskId}.otf`);
|
||||
const resultPath = path.join(os.tmpdir(), `pdfjs-font-test-${taskId}.ttx`);
|
||||
|
||||
// Write the font data to a temporary file on disk (because TTX only accepts
|
||||
// files as input).
|
||||
fs.writeFileSync(fontPath, buffer);
|
||||
|
||||
// Run TTX on the temporary font file.
|
||||
let ttxError;
|
||||
try {
|
||||
await runTtx(fontPath);
|
||||
} catch (error) {
|
||||
ttxError = error;
|
||||
}
|
||||
|
||||
// Remove the temporary font/result files and report on the outcome.
|
||||
fs.unlinkSync(fontPath);
|
||||
if (ttxError) {
|
||||
throw ttxError;
|
||||
}
|
||||
if (!fs.existsSync(resultPath)) {
|
||||
throw new Error("TTX did not generate output");
|
||||
}
|
||||
const xml = fs.readFileSync(resultPath);
|
||||
fs.unlinkSync(resultPath);
|
||||
return xml;
|
||||
}
|
||||
|
||||
export { translateFont };
|
||||
Reference in New Issue
Block a user