Current Dev State

This commit is contained in:
Tim Lorsbach
2025-06-23 20:13:54 +02:00
parent b4f9bb277d
commit ded50edaa2
22617 changed files with 4345095 additions and 174 deletions

View File

@ -0,0 +1,60 @@
/****************************************************************************
* Copyright 2017 EPAM Systems
*
* 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.
***************************************************************************/
/* eslint-env node */
var webdriverio = require('webdriverio');
var chromedriver = require('chromedriver');
var path = require('path');
var minimist = require('minimist');
var options = minimist(process.argv.slice(2), {
string: ['dist'],
boolean: ['headless'],
default: {
headless: implicitHeadless(),
dist: 'dist'
}
});
function implicitHeadless() {
return process.platform != 'win32' && process.platform != 'darwin' &&
!process.env.DISPLAY;
}
function startSession(session) {
// an variant of https://git.io/vQ8o7
chromedriver.start(['--url-base=wd/hub']);
var browser = webdriverio.remote({
port: 9515, // TODO: autochoose choose unused port
desiredCapabilities: {
browserName: 'chrome',
chromeOptions: options.headless ? {
// see: https://goo.gl/ypWDst
args: ['--headless', '--disable-gpu']
} : {}
}
}).init().url('about:blank');
browser.on('error', (e) => console.error(e));
let br = session(browser, path.join(__dirname, '..')) || browser; // test dir
br.end().then(() => chromedriver.stop());
}
module.exports = startSession;

View File

@ -0,0 +1,111 @@
/****************************************************************************
* Copyright 2017 EPAM Systems
*
* 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.
***************************************************************************/
/* eslint-env node */
var fs = require('fs');
var path = require('path');
var minimist = require('minimist');
var options = minimist(process.argv.slice(2), {
string: ['fixtures'],
default: {
fixtures: 'fixtures'
}
});
function collect(items, base) {
var res = [];
var structfiles = [];
for (var fn of items) {
var fpath = path.join(base || '', fn);
if (fs.statSync(fpath).isDirectory())
res = res.concat(collect(fs.readdirSync(fpath), fpath));
else if (path.extname(fn) == '.sdf')
res.push(sdfCollect(fpath));
else if (!!base && ['.mol', '.rxn'].indexOf(path.extname(fn)) != -1)
structfiles.push(fn);
}
if (structfiles.length > 0) {
res.push({
name: path.basename(base),
path: base,
type: 'folder',
files: structfiles
});
}
return res;
}
function sdfCollect(fpath) {
var data = fs.readFileSync(fpath, 'utf8');
return {
name: path.basename(fpath),
path: fpath,
type: 'sdf',
count: data.split(/\$\$\$\$/).length
};
}
function* iterate(col) {
if (col.type == 'folder') {
for (var fn of col.files) {
yield {
name: fn,
data: fs.readFileSync(path.join(col.path, fn), 'utf8')
};
}
} else {
var sdf = fs.readFileSync(col.path, 'utf8');
var re = /^\$\$\$\$\n/gm;
for (var m, i, num = 0; i = re.lastIndex, m = re.exec(sdf); num++) {
yield {
name: num,
data: sdf.slice(i, m.index)
};
}
}
}
function range(n, start) {
start = start || 0;
return Array.apply(null, {
length: n - start
}).map((_, i) => i + start);
}
function collection(collections, name) {
var col = collections.find(c => c.name == name);
return Object.assign(iterate(col), col.type == 'folder' ? {
names: () => col.files,
fixture: id => fs.readFileSync(path.join(col.path, id), 'utf8')
} : {
names: () => range(col.count - 1),
fixture: id => {
var data = fs.readFileSync(col.path, 'utf8');
return data.split(/\$\$\$\$/m, id + 1)[id - 0].trim();
}
});
}
module.exports = function (colPath) {
if (!colPath) colPath = path.join('test/', options.fixtures);
var cols = collect(Array.isArray(colPath) ? colPath : [colPath]);
return Object.assign(collection.bind(null, cols), {
names: () => cols.map(c => c.name)
});
};

View File

@ -0,0 +1,62 @@
/****************************************************************************
* Copyright 2017 EPAM Systems
*
* 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.
***************************************************************************/
/* eslint-env node */
var fs = require('fs');
var ora = require('ora');
var svgstore = require('svgstore');
var cols = require('./collections')();
var browserSession = require('./browser-session');
browserSession((browser, testDir) => {
browser = browser.url(`${testDir}/render/render-test.html`);
var sprites = svgstore({
copyAttrs: ['width', 'height', 'preserveAspectRatio']
});
for (var colname of cols.names()) {
for (var name of cols(colname).names()) {
let sampleName = `${colname}/${name}`;
let structStr = cols(colname).fixture(name);
let opts = {
sample: sampleName,
width: 600,
height: 400
};
let spinner = ora(sampleName);
browser.then(() => spinner.start());
browser = browser
.execute(function (structStr, opts) {
window.renderTest(structStr, opts);
}, structStr, opts)
.waitForExist('#canvas-ketcher')
.getHTML('#canvas-ketcher', false).then(svg => {
// console.info(sampleName, svg.replace(/.*(viewBox=".+?").*/, "$1"));
sprites.add(sampleName, svg);
spinner.succeed();
});
}
}
return browser.then(() => {
// TODO should it be cmd arg?
fs.writeFileSync('test/fixtures/fixtures.svg', sprites);
});
});

View File

@ -0,0 +1,34 @@
/****************************************************************************
* Copyright 2017 EPAM Systems
*
* 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 fs = require('fs');
const path = require('path');
const xpath = require('xpath');
const DOMParser = require('xmldom').DOMParser;
const XMLSerializer = require('xmldom').XMLSerializer;
let libStr = fs.readFileSync(path.join(__dirname, '../fixtures/fixtures.svg')).toString();
let library = new DOMParser().parseFromString(libStr);
function libSymbol(sampleName) {
let xsym = xpath.evaluate(`//*[@id='${sampleName}']`, library, // ids with '/' are absolutely valid, see https://epa.ms/SGNMm
null, xpath.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
let symbol = xsym.singleNodeValue;
return new XMLSerializer().serializeToString(symbol);
}
module.exports = libSymbol;

View File

@ -0,0 +1,138 @@
/****************************************************************************
* Copyright 2017 EPAM Systems
*
* 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.
***************************************************************************/
'use strict';
const defaultCmpOptions = {
stripSpaces: false,
skipCompare: [],
eps: 0.00011
};
const numberPattern = /-?\d+[\.,]?\d*/g;
function epsEqu(x, y, eps) {
eps = eps || Number.EPSILON * Math.max(Math.abs(x), Math.abs(y));
return Math.abs(x - y) <= eps;
}
function arraysEquals(sArray, rArray, eqFunc) {
return sArray === rArray ||
(
sArray.length === rArray.length &&
sArray.every((elem, index) => eqFunc ? eqFunc(elem, rArray[index]) : elem === rArray[index])
);
}
function extractNumbers(source) {
const matches = source.match(numberPattern);
return {
numbers: matches ? matches.map(parseFloat) : [],
characters: source.replace(numberPattern, '').split(/\s+/)
};
}
function compareFile(source, dest, options) {
const sourceStr = source.split(/\r?\n+/);
const destStr = dest.split(/\r?\n+/);
for (var i = 0; i < sourceStr.length; i++) {
if (options.stripSpaces) {
sourceStr[i] = sourceStr[i].trim();
destStr[i] = destStr[i].trim();
}
const sDataSplitted = extractNumbers(sourceStr[i]);
const rDataSplitted = extractNumbers(destStr[i]);
const numberEquals = arraysEquals(sDataSplitted.numbers, rDataSplitted.numbers, (x, y) => epsEqu(x, y, options.eps));
const characterEquals = arraysEquals(sDataSplitted.characters, rDataSplitted.characters);
if (!numberEquals || !characterEquals)
throw new Error(`\nsource: '${sourceStr[i]}'\ndest: '${destStr[i]}'`);
}
return true;
}
function compareRaw(source, dest, options) {
const sDataMols = source.split('M END');
const rDataMols = dest.split('M END');
let newSdata, newRdata;
if (sDataMols.length !== rDataMols.length)
throw new Error(`\nCount of content blocks are not equal: source = ${sDataMols.length}, dest = ${rDataMols.length}`);
options = Object.assign({}, defaultCmpOptions, options);
for (let i = 0; i < sDataMols.length - 1; i++) {
const sV2000DataIndex = sDataMols[i].indexOf('V2000\n');
const sV3000DataIndex = sDataMols[i].indexOf('V3000\n');
const rV2000DataIndex = rDataMols[i].indexOf('V2000\n');
const rV3000DataIndex = rDataMols[i].indexOf('V3000\n');
newSdata = sDataMols[i].substring(6 + (sV3000DataIndex === -1 ? sV2000DataIndex : sV3000DataIndex));
newRdata = rDataMols[i].substring(6 + (rV3000DataIndex === -1 ? rV2000DataIndex : rV3000DataIndex));
if (!compareFile(newSdata, newRdata, options))
return false;
}
return true;
}
function compareObjects(source, dest, options, parentKey) {
if (typeof source !== typeof dest)
throw new Error(`\ntypes not equal: type ${typeof source} of ${source} vs type ${typeof dest} of ${dest} in ${parentKey}`);
if (typeof source !== 'object')
return source === dest;
return Object.keys(source)
.filter(prop => !options.skipCompare.includes(prop))
.every(key => {
if (dest[key] === undefined)
throw new Error(`\nDest object has no key ${key}`);
if (!compareObjects(source[key], dest[key], options, key))
throw new Error(`\nsource: '${source[key]}'\ndest: '${dest[key]}' in ${key}`);
return true;
});
}
function unicodeLiteral(str) {
function fixedHex(number, length) {
let str = number.toString(16).toUpperCase();
while (str.length < length)
str = "0" + str;
return str;
}
let result = "";
for (var i = 0; i < str.length; ++i) {
if (str.charCodeAt(i) > 126 || str.charCodeAt(i) < 32)
result += "\\u" + fixedHex(str.charCodeAt(i), 4);
else
result += str[i];
}
return result;
}
module.exports = {
raw: compareRaw,
objects: compareObjects,
unicodeLiteral: unicodeLiteral
};