mirror of
https://github.com/Smaug123/KaTeX
synced 2025-10-07 04:08:43 +00:00
Move test helpers into common modules (#1318)
* Move test helpers into common modules * helpers.js gets all the helper functions * setup.js gets the common Jest setup (serializer, expect extensions) * Exclude test from coverage testing * @ylemkimon's comments: parsing -> building, settings || defaultSettings * Default argument for settings * Fix lint errors * @ylemklemon's comment: use buildAndSetResult * Use template literals
This commit is contained in:
@@ -87,6 +87,10 @@
|
|||||||
"nomnom": "^1.8.1"
|
"nomnom": "^1.8.1"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
|
"collectCoverageFrom": [
|
||||||
|
"src/**/*.js",
|
||||||
|
"contrib/**/*.js"
|
||||||
|
],
|
||||||
"setupTestFrameworkScriptFile": "<rootDir>/test/setup.js",
|
"setupTestFrameworkScriptFile": "<rootDir>/test/setup.js",
|
||||||
"snapshotSerializers": [
|
"snapshotSerializers": [
|
||||||
"jest-serializer-html"
|
"jest-serializer-html"
|
||||||
|
@@ -32,7 +32,16 @@ exports[`A parser that does not throw on unsupported commands should build katex
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`A parser that does not throw on unsupported commands should properly escape LaTeX in errors 1`] = `"<span class=\\"katex-error\\" title=\\"ParseError: KaTeX parse error: Expected group after '^' at position 2: 2^̲&"<>\\" style=\\"color:#933\\">2^&"<></span>"`;
|
exports[`A parser that does not throw on unsupported commands should properly escape LaTeX in errors 1`] = `
|
||||||
|
|
||||||
|
<span class="katex-error"
|
||||||
|
title="ParseError: KaTeX parse error: Expected group after '^' at position 2: 2^̲&"<>"
|
||||||
|
style="color:#933"
|
||||||
|
>
|
||||||
|
2^&"<>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`An implicit group parser within optional groups should work style commands \\sqrt[\\textstyle 3]{x} 1`] = `
|
exports[`An implicit group parser within optional groups should work style commands \\sqrt[\\textstyle 3]{x} 1`] = `
|
||||||
[
|
[
|
||||||
|
@@ -1,59 +1,7 @@
|
|||||||
/* global beforeEach: false */
|
|
||||||
/* global expect: false */
|
/* global expect: false */
|
||||||
/* global it: false */
|
/* global it: false */
|
||||||
/* global describe: false */
|
/* global describe: false */
|
||||||
|
|
||||||
import parseTree from "../src/parseTree";
|
|
||||||
import Settings from "../src/Settings";
|
|
||||||
|
|
||||||
const defaultSettings = new Settings({});
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
const prefix = "KaTeX parse error: ";
|
|
||||||
|
|
||||||
expect.extend({
|
|
||||||
toFailWithParseError: function(actual, expected) {
|
|
||||||
try {
|
|
||||||
parseTree(actual, defaultSettings);
|
|
||||||
return {
|
|
||||||
pass: false,
|
|
||||||
message: () => "'" + actual + "' parsed without error",
|
|
||||||
};
|
|
||||||
} catch (e) {
|
|
||||||
if (expected === undefined) {
|
|
||||||
return {
|
|
||||||
pass: true,
|
|
||||||
message: () => "'" + actual + "' parsed with error",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const msg = e.message;
|
|
||||||
const exp = prefix + expected;
|
|
||||||
if (msg === exp) {
|
|
||||||
return {
|
|
||||||
pass: true,
|
|
||||||
message: () => "'" + actual + "'" +
|
|
||||||
" parsed with error '" + expected + "'",
|
|
||||||
};
|
|
||||||
} else if (msg.slice(0, 19) === prefix) {
|
|
||||||
return {
|
|
||||||
pass: false,
|
|
||||||
message: () => "'" + actual + "'" +
|
|
||||||
" parsed with error '" + msg.slice(19) +
|
|
||||||
"' but expected '" + expected + "'",
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
pass: false,
|
|
||||||
message: () => "'" + actual + "'" +
|
|
||||||
" caused error '" + msg +
|
|
||||||
"' but expected '" + exp + "'",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("Parser:", function() {
|
describe("Parser:", function() {
|
||||||
|
|
||||||
describe("#handleInfixNodes", function() {
|
describe("#handleInfixNodes", function() {
|
||||||
|
97
test/helpers.js
Normal file
97
test/helpers.js
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
/* global expect: false */
|
||||||
|
|
||||||
|
import katex from "../katex";
|
||||||
|
import ParseError from "../src/ParseError";
|
||||||
|
import parseTree from "../src/parseTree";
|
||||||
|
import Settings from "../src/Settings";
|
||||||
|
|
||||||
|
export const defaultSettings = new Settings({
|
||||||
|
strict: false, // deal with warnings only when desired
|
||||||
|
});
|
||||||
|
export const strictSettings = new Settings({strict: true});
|
||||||
|
|
||||||
|
export const _getBuilt = function(expr, settings = defaultSettings) {
|
||||||
|
const rootNode = katex.__renderToDomTree(expr, settings);
|
||||||
|
|
||||||
|
if (rootNode.classes.indexOf('katex-error') >= 0) {
|
||||||
|
return rootNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// grab the root node of the HTML rendering
|
||||||
|
const builtHTML = rootNode.children[1];
|
||||||
|
|
||||||
|
// combine the non-strut children of all base spans
|
||||||
|
const children = [];
|
||||||
|
for (let i = 0; i < builtHTML.children.length; i++) {
|
||||||
|
children.push(...builtHTML.children[i].children.filter(
|
||||||
|
(node) => node.classes.indexOf("strut") < 0));
|
||||||
|
}
|
||||||
|
return children;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the root node of the rendered HTML.
|
||||||
|
* @param expr
|
||||||
|
* @param settings
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
export const getBuilt = function(expr, settings = defaultSettings) {
|
||||||
|
expect(expr).toBuild(settings);
|
||||||
|
return _getBuilt(expr, settings);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the root node of the parse tree.
|
||||||
|
* @param expr
|
||||||
|
* @param settings
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
export const getParsed = function(expr, settings = defaultSettings) {
|
||||||
|
expect(expr).toParse(settings);
|
||||||
|
return parseTree(expr, settings);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const stripPositions = function(expr) {
|
||||||
|
if (typeof expr !== "object" || expr === null) {
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
if (expr.loc && expr.loc.lexer && typeof expr.loc.start === "number") {
|
||||||
|
delete expr.loc;
|
||||||
|
}
|
||||||
|
Object.keys(expr).forEach(function(key) {
|
||||||
|
stripPositions(expr[key]);
|
||||||
|
});
|
||||||
|
return expr;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const parseAndSetResult = function(expr, result,
|
||||||
|
settings = defaultSettings) {
|
||||||
|
try {
|
||||||
|
return parseTree(expr, settings);
|
||||||
|
} catch (e) {
|
||||||
|
result.pass = false;
|
||||||
|
if (e instanceof ParseError) {
|
||||||
|
result.message = () =>
|
||||||
|
`'${expr}' failed parsing with error: ${e.message}`;
|
||||||
|
} else {
|
||||||
|
result.message = () =>
|
||||||
|
`'${expr}' failed parsing with unknown error: ${e.message}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const buildAndSetResult = function(expr, result,
|
||||||
|
settings = defaultSettings) {
|
||||||
|
try {
|
||||||
|
return _getBuilt(expr, settings);
|
||||||
|
} catch (e) {
|
||||||
|
result.pass = false;
|
||||||
|
if (e instanceof ParseError) {
|
||||||
|
result.message = () =>
|
||||||
|
`'${expr}' failed building with error: ${e.message}`;
|
||||||
|
} else {
|
||||||
|
result.message = () =>
|
||||||
|
`'${expr}' failed building with unknown error: ${e.message}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
@@ -1,290 +1,26 @@
|
|||||||
/* eslint max-len:0 */
|
/* eslint max-len:0 */
|
||||||
/* global beforeEach: false */
|
|
||||||
/* global expect: false */
|
/* global expect: false */
|
||||||
/* global it: false */
|
/* global it: false */
|
||||||
/* global describe: false */
|
/* global describe: false */
|
||||||
import stringify from 'json-stable-stringify';
|
|
||||||
|
|
||||||
import buildMathML from "../src/buildMathML";
|
import buildMathML from "../src/buildMathML";
|
||||||
import buildTree from "../src/buildTree";
|
import buildTree from "../src/buildTree";
|
||||||
import katex from "../katex";
|
import katex from "../katex";
|
||||||
import ParseError from "../src/ParseError";
|
|
||||||
import parseTree from "../src/parseTree";
|
import parseTree from "../src/parseTree";
|
||||||
import Options from "../src/Options";
|
import Options from "../src/Options";
|
||||||
import Settings from "../src/Settings";
|
import Settings from "../src/Settings";
|
||||||
import Style from "../src/Style";
|
import Style from "../src/Style";
|
||||||
|
import {
|
||||||
|
defaultSettings,
|
||||||
|
_getBuilt, getBuilt, getParsed, stripPositions,
|
||||||
|
} from "./helpers";
|
||||||
|
|
||||||
const typeFirstCompare = (a, b) => {
|
|
||||||
if (a.key === 'type') {
|
|
||||||
return -1;
|
|
||||||
} else if (b.key === 'type') {
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return a.key < b.key ? -1 : 1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const serializer = {
|
|
||||||
print(val) {
|
|
||||||
return stringify(val, {cmp: typeFirstCompare, space: ' '});
|
|
||||||
},
|
|
||||||
test() {
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
expect.addSnapshotSerializer(serializer);
|
|
||||||
|
|
||||||
const defaultSettings = new Settings({
|
|
||||||
strict: false, // deal with warnings only when desired
|
|
||||||
});
|
|
||||||
const defaultOptions = new Options({
|
const defaultOptions = new Options({
|
||||||
style: Style.TEXT,
|
style: Style.TEXT,
|
||||||
size: 5,
|
size: 5,
|
||||||
maxSize: Infinity,
|
maxSize: Infinity,
|
||||||
});
|
});
|
||||||
|
|
||||||
const _getBuilt = function(expr, settings) {
|
|
||||||
const usedSettings = settings ? settings : defaultSettings;
|
|
||||||
const rootNode = katex.__renderToDomTree(expr, usedSettings);
|
|
||||||
|
|
||||||
if (rootNode.classes.indexOf('katex-error') >= 0) {
|
|
||||||
return rootNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// grab the root node of the HTML rendering
|
|
||||||
const builtHTML = rootNode.children[1];
|
|
||||||
|
|
||||||
// combine the non-strut children of all base spans
|
|
||||||
const children = [];
|
|
||||||
for (let i = 0; i < builtHTML.children.length; i++) {
|
|
||||||
children.push(...builtHTML.children[i].children.filter(
|
|
||||||
(node) => node.classes.indexOf("strut") < 0));
|
|
||||||
}
|
|
||||||
return children;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the root node of the rendered HTML.
|
|
||||||
* @param expr
|
|
||||||
* @param settings
|
|
||||||
* @returns {Object}
|
|
||||||
*/
|
|
||||||
const getBuilt = function(expr, settings) {
|
|
||||||
const usedSettings = settings ? settings : defaultSettings;
|
|
||||||
expect(expr).toBuild(usedSettings);
|
|
||||||
return _getBuilt(expr, settings);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the root node of the parse tree.
|
|
||||||
* @param expr
|
|
||||||
* @param settings
|
|
||||||
* @returns {Object}
|
|
||||||
*/
|
|
||||||
const getParsed = function(expr, settings) {
|
|
||||||
const usedSettings = settings ? settings : defaultSettings;
|
|
||||||
|
|
||||||
expect(expr).toParse(usedSettings);
|
|
||||||
return parseTree(expr, usedSettings);
|
|
||||||
};
|
|
||||||
|
|
||||||
const stripPositions = function(expr) {
|
|
||||||
if (typeof expr !== "object" || expr === null) {
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
if (expr.loc && expr.loc.lexer && typeof expr.loc.start === "number") {
|
|
||||||
delete expr.loc;
|
|
||||||
}
|
|
||||||
Object.keys(expr).forEach(function(key) {
|
|
||||||
stripPositions(expr[key]);
|
|
||||||
});
|
|
||||||
return expr;
|
|
||||||
};
|
|
||||||
|
|
||||||
const parseAndSetResult = function(expr, result, settings) {
|
|
||||||
try {
|
|
||||||
return parseTree(expr, settings || defaultSettings);
|
|
||||||
} catch (e) {
|
|
||||||
result.pass = false;
|
|
||||||
if (e instanceof ParseError) {
|
|
||||||
result.message = () => "'" + expr + "' failed " +
|
|
||||||
"parsing with error: " + e.message;
|
|
||||||
} else {
|
|
||||||
result.message = () => "'" + expr + "' failed " +
|
|
||||||
"parsing with unknown error: " + e.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const buildAndSetResult = function(expr, result, settings) {
|
|
||||||
try {
|
|
||||||
return _getBuilt(expr, settings || defaultSettings);
|
|
||||||
} catch (e) {
|
|
||||||
result.pass = false;
|
|
||||||
if (e instanceof ParseError) {
|
|
||||||
result.message = () => "'" + expr + "' failed " +
|
|
||||||
"parsing with error: " + e.message;
|
|
||||||
} else {
|
|
||||||
result.message = () => "'" + expr + "' failed " +
|
|
||||||
"parsing with unknown error: " + e.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
expect.extend({
|
|
||||||
toParse: function(actual, settings) {
|
|
||||||
const usedSettings = settings ? settings : defaultSettings;
|
|
||||||
|
|
||||||
const result = {
|
|
||||||
pass: true,
|
|
||||||
message: () => "'" + actual + "' succeeded parsing",
|
|
||||||
};
|
|
||||||
parseAndSetResult(actual, result, usedSettings);
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
toNotParse: function(actual, settings) {
|
|
||||||
const usedSettings = settings ? settings : defaultSettings;
|
|
||||||
|
|
||||||
const result = {
|
|
||||||
pass: false,
|
|
||||||
message: () => "Expected '" + actual + "' to fail " +
|
|
||||||
"parsing, but it succeeded",
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
parseTree(actual, usedSettings);
|
|
||||||
} catch (e) {
|
|
||||||
if (e instanceof ParseError) {
|
|
||||||
result.pass = true;
|
|
||||||
result.message = () => "'" + actual + "' correctly " +
|
|
||||||
"didn't parse with error: " + e.message;
|
|
||||||
} else {
|
|
||||||
result.message = () => "'" + actual + "' failed " +
|
|
||||||
"parsing with unknown error: " + e.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
toBuild: function(actual, settings) {
|
|
||||||
const usedSettings = settings ? settings : defaultSettings;
|
|
||||||
|
|
||||||
const result = {
|
|
||||||
pass: true,
|
|
||||||
message: () => "'" + actual + "' succeeded in building",
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(actual).toParse(usedSettings);
|
|
||||||
|
|
||||||
try {
|
|
||||||
_getBuilt(actual, usedSettings);
|
|
||||||
} catch (e) {
|
|
||||||
result.pass = false;
|
|
||||||
if (e instanceof ParseError) {
|
|
||||||
result.message = () => "'" + actual + "' failed to " +
|
|
||||||
"build with error: " + e.message;
|
|
||||||
} else {
|
|
||||||
result.message = () => "'" + actual + "' failed " +
|
|
||||||
"building with unknown error: " + e.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
toNotBuild: function(actual, settings) {
|
|
||||||
const usedSettings = settings ? settings : defaultSettings;
|
|
||||||
|
|
||||||
const result = {
|
|
||||||
pass: false,
|
|
||||||
message: () => "Expected '" + actual + "' to fail " +
|
|
||||||
"building, but it succeeded",
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
_getBuilt(actual, usedSettings);
|
|
||||||
} catch (e) {
|
|
||||||
if (e instanceof ParseError) {
|
|
||||||
result.pass = true;
|
|
||||||
result.message = () => "'" + actual + "' correctly " +
|
|
||||||
"didn't build with error: " + e.message;
|
|
||||||
} else {
|
|
||||||
result.message = () => "'" + actual + "' failed " +
|
|
||||||
"building with unknown error: " + e.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
toParseLike: function(actual, expected, settings) {
|
|
||||||
const usedSettings = settings ? settings : defaultSettings;
|
|
||||||
|
|
||||||
const result = {
|
|
||||||
pass: true,
|
|
||||||
message: () => "Parse trees of '" + actual +
|
|
||||||
"' and '" + expected + "' are equivalent",
|
|
||||||
};
|
|
||||||
|
|
||||||
const actualTree = parseAndSetResult(actual, result,
|
|
||||||
usedSettings);
|
|
||||||
if (!actualTree) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
const expectedTree = parseAndSetResult(expected, result,
|
|
||||||
usedSettings);
|
|
||||||
if (!expectedTree) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
stripPositions(actualTree);
|
|
||||||
stripPositions(expectedTree);
|
|
||||||
|
|
||||||
if (JSON.stringify(actualTree) !== JSON.stringify(expectedTree)) {
|
|
||||||
result.pass = false;
|
|
||||||
result.message = () => "Parse trees of '" + actual +
|
|
||||||
"' and '" + expected + "' are not equivalent";
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
toBuildLike: function(actual, expected, settings) {
|
|
||||||
const usedSettings = settings ? settings : defaultSettings;
|
|
||||||
|
|
||||||
const result = {
|
|
||||||
pass: true,
|
|
||||||
message: () => "Build trees of '" + actual +
|
|
||||||
"' and '" + expected + "' are equivalent",
|
|
||||||
};
|
|
||||||
|
|
||||||
const actualTree = buildAndSetResult(actual, result,
|
|
||||||
usedSettings);
|
|
||||||
if (!actualTree) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
const expectedTree = buildAndSetResult(expected, result,
|
|
||||||
usedSettings);
|
|
||||||
if (!expectedTree) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
stripPositions(actualTree);
|
|
||||||
stripPositions(expectedTree);
|
|
||||||
|
|
||||||
if (JSON.stringify(actualTree) !== JSON.stringify(expectedTree)) {
|
|
||||||
result.pass = false;
|
|
||||||
result.message = () => "Parse trees of '" + actual +
|
|
||||||
"' and '" + expected + "' are not equivalent";
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("A parser", function() {
|
describe("A parser", function() {
|
||||||
it("should not fail on an empty string", function() {
|
it("should not fail on an empty string", function() {
|
||||||
expect("").toParse();
|
expect("").toParse();
|
||||||
|
199
test/setup.js
199
test/setup.js
@@ -2,21 +2,206 @@
|
|||||||
/* global expect: false */
|
/* global expect: false */
|
||||||
|
|
||||||
import katex from "../katex";
|
import katex from "../katex";
|
||||||
import Settings from "../src/Settings";
|
import ParseError from "../src/ParseError";
|
||||||
|
import parseTree from "../src/parseTree";
|
||||||
import Warning from "./Warning";
|
import Warning from "./Warning";
|
||||||
|
import stringify from 'json-stable-stringify';
|
||||||
|
import {
|
||||||
|
defaultSettings,
|
||||||
|
_getBuilt, buildAndSetResult, parseAndSetResult, stripPositions,
|
||||||
|
} from "./helpers";
|
||||||
|
|
||||||
|
// Serializer support
|
||||||
|
|
||||||
|
const typeFirstCompare = (a, b) => {
|
||||||
|
if (a.key === 'type') {
|
||||||
|
return -1;
|
||||||
|
} else if (b.key === 'type') {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return a.key < b.key ? -1 : 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const serializer = {
|
||||||
|
print(val) {
|
||||||
|
return stringify(val, {cmp: typeFirstCompare, space: ' '});
|
||||||
|
},
|
||||||
|
test(val) {
|
||||||
|
// Leave strings (e.g. XML) to other serializers
|
||||||
|
return typeof val !== "string";
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
expect.addSnapshotSerializer(serializer);
|
||||||
|
|
||||||
|
// Turn warnings into errors
|
||||||
|
|
||||||
global.console.warn = jest.fn((warning) => {
|
global.console.warn = jest.fn((warning) => {
|
||||||
throw new Warning(warning);
|
throw new Warning(warning);
|
||||||
});
|
});
|
||||||
|
|
||||||
const defaultSettings = new Settings({
|
// Expect extensions
|
||||||
strict: false, // enable dealing with warnings only when needed
|
|
||||||
});
|
|
||||||
|
|
||||||
expect.extend({
|
expect.extend({
|
||||||
toWarn: function(actual, settings) {
|
toParse: function(actual, settings = defaultSettings) {
|
||||||
const usedSettings = settings ? settings : defaultSettings;
|
const result = {
|
||||||
|
pass: true,
|
||||||
|
message: () => `'${actual}' succeeded parsing`,
|
||||||
|
};
|
||||||
|
parseAndSetResult(actual, result, settings);
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
toNotParse: function(actual, settings = defaultSettings) {
|
||||||
|
const result = {
|
||||||
|
pass: false,
|
||||||
|
message: () =>
|
||||||
|
`Expected '${actual}' to fail parsing, but it succeeded`,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
parseTree(actual, settings);
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof ParseError) {
|
||||||
|
result.pass = true;
|
||||||
|
result.message = () => `'${actual}' correctly didn't parse ` +
|
||||||
|
`with error: ${e.message}`;
|
||||||
|
} else {
|
||||||
|
result.message = () => `'${actual}' failed parsing ` +
|
||||||
|
`with unknown error: ${e.message}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
toFailWithParseError: function(actual, expected) {
|
||||||
|
const prefix = "KaTeX parse error: ";
|
||||||
|
try {
|
||||||
|
parseTree(actual, defaultSettings);
|
||||||
|
return {
|
||||||
|
pass: false,
|
||||||
|
message: () => `'${actual}' parsed without error`,
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
if (expected === undefined) {
|
||||||
|
return {
|
||||||
|
pass: true,
|
||||||
|
message: () => `'${actual}' parsed with error`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const msg = e.message;
|
||||||
|
const exp = prefix + expected;
|
||||||
|
if (msg === exp) {
|
||||||
|
return {
|
||||||
|
pass: true,
|
||||||
|
message: () =>
|
||||||
|
`'${actual}' parsed with expected error '${expected}'`,
|
||||||
|
};
|
||||||
|
} else if (msg.slice(0, 19) === prefix) {
|
||||||
|
return {
|
||||||
|
pass: false,
|
||||||
|
message: () => `'${actual}' parsed with error ` +
|
||||||
|
`'${msg.slice(19)}' but expected '${expected}'`,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
pass: false,
|
||||||
|
message: () => `'${actual}' caused error '${msg}' ` +
|
||||||
|
`but expected '${exp}'`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
toBuild: function(actual, settings = defaultSettings) {
|
||||||
|
const result = {
|
||||||
|
pass: true,
|
||||||
|
message: () => `'${actual}' succeeded in building`,
|
||||||
|
};
|
||||||
|
buildAndSetResult(actual, result, settings);
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
toNotBuild: function(actual, settings = defaultSettings) {
|
||||||
|
const result = {
|
||||||
|
pass: false,
|
||||||
|
message: () =>
|
||||||
|
`Expected '${actual}' to fail building, but it succeeded`,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
_getBuilt(actual, settings);
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof ParseError) {
|
||||||
|
result.pass = true;
|
||||||
|
result.message = () => `'${actual}' correctly ` +
|
||||||
|
`didn't build with error: ${e.message}`;
|
||||||
|
} else {
|
||||||
|
result.message = () => `'${actual}' failed ` +
|
||||||
|
`building with unknown error: ${e.message}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
toParseLike: function(actual, expected, settings = defaultSettings) {
|
||||||
|
const result = {
|
||||||
|
pass: true,
|
||||||
|
message: () =>
|
||||||
|
`Parse trees of '${actual}' and '${expected}' are equivalent`,
|
||||||
|
};
|
||||||
|
|
||||||
|
const actualTree = parseAndSetResult(actual, result, settings);
|
||||||
|
if (!actualTree) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
const expectedTree = parseAndSetResult(expected, result, settings);
|
||||||
|
if (!expectedTree) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
stripPositions(actualTree);
|
||||||
|
stripPositions(expectedTree);
|
||||||
|
|
||||||
|
if (JSON.stringify(actualTree) !== JSON.stringify(expectedTree)) {
|
||||||
|
result.pass = false;
|
||||||
|
result.message = () => `Parse trees of '${actual}' and ` +
|
||||||
|
`'${expected}' are not equivalent`;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
toBuildLike: function(actual, expected, settings = defaultSettings) {
|
||||||
|
const result = {
|
||||||
|
pass: true,
|
||||||
|
message: () =>
|
||||||
|
`Build trees of '${actual}' and '${expected}' are equivalent`,
|
||||||
|
};
|
||||||
|
|
||||||
|
const actualTree = buildAndSetResult(actual, result, settings);
|
||||||
|
if (!actualTree) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
const expectedTree = buildAndSetResult(expected, result, settings);
|
||||||
|
if (!expectedTree) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
stripPositions(actualTree);
|
||||||
|
stripPositions(expectedTree);
|
||||||
|
|
||||||
|
if (JSON.stringify(actualTree) !== JSON.stringify(expectedTree)) {
|
||||||
|
result.pass = false;
|
||||||
|
result.message = () => `Build trees of '${actual}' and ` +
|
||||||
|
`'${expected}' are not equivalent`;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
toWarn: function(actual, settings = defaultSettings) {
|
||||||
const result = {
|
const result = {
|
||||||
pass: false,
|
pass: false,
|
||||||
message: () =>
|
message: () =>
|
||||||
@@ -24,7 +209,7 @@ expect.extend({
|
|||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
katex.__renderToDomTree(actual, usedSettings);
|
katex.__renderToDomTree(actual, settings);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof Warning) {
|
if (e instanceof Warning) {
|
||||||
result.pass = true;
|
result.pass = true;
|
||||||
|
@@ -1,75 +1,12 @@
|
|||||||
/* eslint max-len:0 */
|
/* eslint max-len:0 */
|
||||||
/* global beforeEach: false */
|
|
||||||
/* global expect: false */
|
/* global expect: false */
|
||||||
/* global it: false */
|
/* global it: false */
|
||||||
/* global describe: false */
|
/* global describe: false */
|
||||||
import ParseError from "../src/ParseError";
|
|
||||||
import parseTree from "../src/parseTree";
|
|
||||||
import Settings from "../src/Settings";
|
import Settings from "../src/Settings";
|
||||||
import {scriptFromCodepoint, supportedCodepoint} from "../src/unicodeScripts";
|
import {scriptFromCodepoint, supportedCodepoint} from "../src/unicodeScripts";
|
||||||
|
import {strictSettings} from "./helpers";
|
||||||
const defaultSettings = new Settings({
|
|
||||||
strict: false, // deal with warnings only when desired
|
|
||||||
});
|
|
||||||
const strictSettings = new Settings({strict: true});
|
|
||||||
|
|
||||||
const parseAndSetResult = function(expr, result, settings) {
|
|
||||||
try {
|
|
||||||
return parseTree(expr, settings || defaultSettings);
|
|
||||||
} catch (e) {
|
|
||||||
result.pass = false;
|
|
||||||
if (e instanceof ParseError) {
|
|
||||||
result.message = () => "'" + expr + "' failed " +
|
|
||||||
"parsing with error: " + e.message;
|
|
||||||
} else {
|
|
||||||
result.message = () => "'" + expr + "' failed " +
|
|
||||||
"parsing with unknown error: " + e.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
describe("unicode", function() {
|
describe("unicode", function() {
|
||||||
beforeEach(function() {
|
|
||||||
expect.extend({
|
|
||||||
|
|
||||||
toParse: function(actual, settings) {
|
|
||||||
const usedSettings = settings ? settings : defaultSettings;
|
|
||||||
|
|
||||||
const result = {
|
|
||||||
pass: true,
|
|
||||||
message: () => "'" + actual + "' succeeded parsing",
|
|
||||||
};
|
|
||||||
parseAndSetResult(actual, result, usedSettings);
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
toNotParse: function(actual, settings) {
|
|
||||||
const usedSettings = settings ? settings : defaultSettings;
|
|
||||||
|
|
||||||
const result = {
|
|
||||||
pass: false,
|
|
||||||
message: () => "Expected '" + actual + "' to fail " +
|
|
||||||
"parsing, but it succeeded",
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
parseTree(actual, usedSettings);
|
|
||||||
} catch (e) {
|
|
||||||
if (e instanceof ParseError) {
|
|
||||||
result.pass = true;
|
|
||||||
result.message = () => "'" + actual + "' correctly " +
|
|
||||||
"didn't parse with error: " + e.message;
|
|
||||||
} else {
|
|
||||||
result.message = () => "'" + actual + "' failed " +
|
|
||||||
"parsing with unknown error: " + e.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should parse Latin-1 inside \\text{}", function() {
|
it("should parse Latin-1 inside \\text{}", function() {
|
||||||
expect('\\text{ÀÁÂÃÄÅÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåèéêëìíîïñòóôõöùúûüýÿ' +
|
expect('\\text{ÀÁÂÃÄÅÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåèéêëìíîïñòóôõöùúûüýÿ' +
|
||||||
'ÆÇÐØÞßæçðøþ}').toParse();
|
'ÆÇÐØÞßæçðøþ}').toParse();
|
||||||
|
Reference in New Issue
Block a user