var OperatorDictionaryTests = { "lspace/rspace": function(json, key) { let parsedKey = splitKey(key); let entry = json.dictionary[key]; let epsilon = 1; document.body.insertAdjacentHTML("beforeend", `
\ lspace/rspace for "${parsedKey.characters}" (${parsedKey.form}): \ \ \  \ ${parsedKey.characters}\  \ \ \ VS \ \ \  \ ${parsedKey.characters}\  \ \ \
`); var div = document.body.lastElementChild; var mrows = div.getElementsByTagName("mrow"); function spaceBetween(element, i, j) { return element.children[j].getBoundingClientRect().left - element.children[i].getBoundingClientRect().right; } var lspace = spaceBetween(mrows[0], 0, 1); var rspace = spaceBetween(mrows[0], 1, 2); var lspaceRef = spaceBetween(mrows[1], 0, 1); var rspaceRef = spaceBetween(mrows[1], 1, 2); assert_approx_equals(lspace, lspaceRef, epsilon, `lspace (${key})`); assert_approx_equals(rspace, rspaceRef, epsilon, `rspace (${key})`); div.style.display = "none"; }, "movablelimits": function(json, key) { let parsedKey = splitKey(key); let entry = json.dictionary[key]; let epsilon = 1; var defaultValue = defaultPropertyValue(entry, "movablelimits"); document.body.insertAdjacentHTML("beforeend", `
\ movablelimits for "${parsedKey.characters}" (${parsedKey.form}): \ \ \ ${parsedKey.characters}\  \ \ \ VS \ \ \ ${parsedKey.characters}\  \ \ \
`); var div = document.body.lastElementChild; var munders = div.getElementsByTagName("munder"); munder = munders[0].getBoundingClientRect() munderRef = munders[1].getBoundingClientRect() assert_approx_equals(munder.height, munderRef.height, epsilon, `Movablelimits property for ${key} should be '${defaultValue}'`); div.style.display = "none"; }, "largeop": function(json, key) { let parsedKey = splitKey(key); let entry = json.dictionary[key]; let epsilon = 1; var defaultValue = defaultPropertyValue(entry, "largeop"); document.body.insertAdjacentHTML("beforeend", `
\ largeop for "${parsedKey.characters}" (${parsedKey.form}): \ \ ${parsedKey.characters}\ \ VS \ \ ${parsedKey.characters}\ \
`); var div = document.body.lastElementChild; var mos = div.getElementsByTagName("mo"); mo = mos[0].getBoundingClientRect() moRef = mos[1].getBoundingClientRect() assert_approx_equals(mo.height, moRef.height, epsilon, `Largeop property for ${key} should be '${defaultValue}'`); div.style.display = "none"; }, "stretchy": function(json, key) { let parsedKey = splitKey(key); let entry = json.dictionary[key]; let epsilon = 1; if (entry.horizontal) { // FIXME: Should really do a MathMLFeatureDetection to verify // support for *horizontal* stretching. var defaultValue = defaultPropertyValue(entry, "stretchy"); document.body.insertAdjacentHTML("beforeend", `
\ stretchy for "${parsedKey.characters}" (${parsedKey.form}): \ \ \   \ ${parsedKey.characters}\ \ \ VS \ \ \   \ ${parsedKey.characters}\ \ \
`); var div = document.body.lastElementChild; var mos = div.getElementsByTagName("mo"); mo = mos[0].getBoundingClientRect() moRef = mos[1].getBoundingClientRect() assert_approx_equals(mo.width, moRef.width, epsilon, `Stretchy property for ${key} should be '${defaultValue}'`); div.style.display = "none"; } else { var defaultValue = defaultPropertyValue(entry, "stretchy"); document.body.insertAdjacentHTML("beforeend", `
\ stretchy for "${parsedKey.characters}" (${parsedKey.form}): \ \ \ ${parsedKey.characters}\ \ \ \ VS \ \ \ ${parsedKey.characters}\ \ \ \
`); var div = document.body.lastElementChild; var mos = div.getElementsByTagName("mo"); mo = mos[0].getBoundingClientRect() moRef = mos[1].getBoundingClientRect() assert_approx_equals(mo.height, moRef.height, epsilon, `Stretchy property for ${key} should be '${defaultValue}'`); div.style.display = "none"; } }, "symmetric": function(json, key) { let parsedKey = splitKey(key); let entry = json.dictionary[key]; let epsilon = 1; var defaultValue = defaultPropertyValue(entry, "symmetric"); document.body.insertAdjacentHTML("beforeend", `
\ symmetric for "${parsedKey.characters}" (${parsedKey.form}): \ \ \ ${parsedKey.characters}\ \ \ \ VS \ \ \ ${parsedKey.characters}\ \ \ \
`); var div = document.body.lastElementChild; var mos = div.getElementsByTagName("mo"); mo = mos[0].getBoundingClientRect() moRef = mos[1].getBoundingClientRect() assert_approx_equals(mo.height, moRef.height, epsilon, `Symmetric property for ${key} should be '${defaultValue}'`); div.style.display = "none"; }, run: async function(json, name, fileIndex) { let has_required_feature_for_testing = await MathMLFeatureDetection[`has_operator_${name}`](); // The operator dictionary has more than one thousand of entries so the // tests are grouped in chunks so that these don't get much more // importance than other MathML tests. For easy debugging, one can set the // chunk size to 1. Also, note that the test div will remain visible for // failed tests. const entryPerChunk = 50 const filesPerProperty = 6 var counter = 0; var test; for (key in json.dictionary) { // Skip this key if it does not belong to that test file. if (counter % filesPerProperty != fileIndex) { counter++; continue; } var counterInFile = (counter - fileIndex) / filesPerProperty; if (counterInFile % entryPerChunk === 0) { // Start of a new chunk. // Complete current async tests and create new ones for the next chunk. if (test) test.done(); test = async_test(`Operator dictionary chunk ${1 + counterInFile / entryPerChunk} - ${name}`); test.step(function() { assert_true(has_required_feature_for_testing, `${name} is supported`); }); } test.step(function() { OperatorDictionaryTests[name](json, key); }); counter++; } // Complete current async test. if (test) test.done(); } };