Skip to content

Commit

Permalink
use file handlers in test
Browse files Browse the repository at this point in the history
metelkin committed Sep 10, 2024
1 parent 2a35d07 commit af2976c
Showing 11 changed files with 173 additions and 21 deletions.
10 changes: 7 additions & 3 deletions bin/heta-build.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env node
const { Command } = require('commander');
const program = new Command();
const fs = require('fs');
const fs = require('fs-extra');
const path = require('path');
const { Builder } = require('../src');
const YAML = require('js-yaml'); // https://www.npmjs.com/package/js-yaml
@@ -115,8 +115,12 @@ async function main() {
process.exit(2); // BRAKE
}

let builder = new Builder(declaration, targetDir);
builder.run();
let builder = new Builder(
declaration,
targetDir,
fs.readFileSync,
fs.outputFileSync
).run();

return builder;
}
149 changes: 149 additions & 0 deletions src/builder/index-online.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
function build(inputDict, settings) { // modules, exports
let coreDirname = '/';
/*
constructor()
*/

// create container and logger
let c = new Container();

/*
c.logger.addTransport((level, msg, opt, levelNum) => { // temporal solution, all logs to console
console.log(`{heta-compiler} [${level}]\t${msg}`);
});
*/
let minLogLevel = settings.options?.logLevel || 'info';
let minLevelNum = levels.indexOf(minLogLevel);
c.logger.addTransport((level, msg, opt, levelNum) => {
let value = `\n[${level}]\t${msg}`;
if (levelNum >= minLevelNum) {
postMessage({action: 'console', value: value});
}
});

// file paths
let _coreDirname = path.resolve(coreDirname);
let _distDirname = path.resolve(coreDirname, settings.options.distDir);
let _metaDirname = path.resolve(coreDirname, settings.options.metaDir);
let _logPath = path.resolve(coreDirname, settings.options.logPath);

c.logger.info(`Heta builder of version ${hetaCompilerPackage.version} initialized in directory "${_coreDirname}"`);
if (settings.id) c.logger.info(`Platform id: "${settings.id}"`);

/*
run()
*/
let outputDict = {}; // {<filepath>: <Buffer>}
c.logger.info(`Compilation of module "${settings.importModule.source}" of type "${settings.importModule.type}"...`);

// 1. Parsing
let ms = new ModuleSystem(c.logger, (filename) => {
let arrayBuffer = inputDict[filename]; // Uint8Array
if (!arrayBuffer) {
throw new HetaLevelError(`Module ${filename} is not found.`);
}
let buffer = Buffer.from(arrayBuffer); // Buffer

return buffer;
});
let sourceFilepath = path.resolve(_coreDirname, settings.importModule.source);
let sourceType = settings.importModule.type;
ms.addModuleDeep(sourceFilepath, sourceType, settings.importModule);

// 2. Modules integration
if (settings.options.debug) {
Object.getOwnPropertyNames(ms.moduleCollection).forEach((name) => {
let relPath = path.relative(_coreDirname, name + '.json');
let absPath = path.join(_metaDirname, relPath);
let str = JSON.stringify(ms.moduleCollection[name], null, 2);
outputDict[absPath] = Buffer.from(str, 'utf-8');
c.logger.info(`Meta file was saved to ${absPath}`);
});
}
let qArr = ms.integrate();

// 3. Translation
c.loadMany(qArr, false);

// 4. Binding
c.logger.info('Setting references in elements, total length ' + c.length);
c.knitMany();

// 5. Circular start_ and ode_
c.logger.info('Checking for circular references in Records.');
c.checkCircRecord();

// 6. check circ UnitDef
c.checkCircUnitDef();


// === STOP if errors ===
if (!c.logger.hasErrors) {

// 7. Units checking
if (settings.options.unitsCheck) {
c.logger.info('Checking unit\'s consistency.');
c.checkUnits();
} else {
c.logger.warn('Units checking skipped. To turn it on set "unitsCheck: true" in declaration.');
}

// 8. Terms checking
c.logger.info('Checking unit\'s terms.');
c.checkTerms();

// 9. Exports
// save
if (settings.options.skipExport) {
c.logger.warn('Exporting skipped as stated in declaration.');
} else if (settings.options.juliaOnly) {
c.logger.warn('"Julia only" mode');
//this.exportJuliaOnly();
// create export without putting it to exportStorage
let Julia = this.container.classes['Julia'];
let exportItem = new Julia({
format: 'Julia',
filepath: '_julia'
});

_makeAndSave(exportItem, _distDirname, outputDict);
} else {
//this.exportMany();
let exportElements = [...c.exportStorage].map((x) => x[1]);
c.logger.info(`Start exporting to files, total: ${exportElements.length}.`);

exportElements.forEach((exportItem) => _makeAndSave(exportItem, _distDirname, outputDict));
}
} else {
c.logger.warn('Units checking and export were skipped because of errors in compilation.');
}

// 10. save logs if required
let hetaErrors = c.hetaErrors();
let createLog = settings.options.logMode === 'always'
|| (settings.options.logMode === 'error' && hetaErrors.length > 0);
if (createLog) {
switch (settings.options.logFormat) {
case 'json':
var logs = JSON.stringify(c.defaultLogs, null, 2);
break;
default:
logs = c.defaultLogs
.filter(x => x.levelNum >= minLevelNum)
.map(x => `[${x.level}]\t${x.msg}`)
.join('\n');
}

//fs.outputFileSync(_logPath, logs);
outputDict[_logPath] = Buffer.from(logs, 'utf-8'); // Buffer
c.logger.info(`All logs was saved to file: "${_logPath}"`);
}

if (!c.logger.hasErrors) {
postMessage({action: 'finished', dict: outputDict});
} else {
postMessage({action: 'stop', dict: outputDict});
}

return c;
}
7 changes: 4 additions & 3 deletions src/builder/index.js
Original file line number Diff line number Diff line change
@@ -41,8 +41,8 @@ class Builder {
constructor(
declaration = {},
coreDirname = '.',
fileReadHandler = (fn) => fs.readFileSync(fn), // return text
fileWriteHandler = (fn, text) => fs.outputFileSync(fn, text) // return undefined
fileReadHandler = (fn) => { throw new Error('File read is not set for Builder'); }, // return text
fileWriteHandler = (fn, text) => { throw new Error('File write is not set for Builder'); } // return undefined
) {
// create container
this.container = new Container();
@@ -197,7 +197,8 @@ class Builder {
this.fileWriteHandler(this._logPath, logs);
this.logger.info(`All logs was saved to file: "${this._logPath}"`);
}
return;

return this;
}

/**
3 changes: 2 additions & 1 deletion test/builder/index.js
Original file line number Diff line number Diff line change
@@ -2,11 +2,12 @@
const { Builder } = require('../../src/builder');
const declaration = require('./test-platform');
const { expect } = require('chai');
const fs = require('fs-extra');

describe('Test Builder.', () => {
let b;
it('Create Builder object and run.', () => {
b = new Builder(declaration, __dirname);
b = new Builder(declaration, __dirname, fs.readFileSync, () => {});
b.run();
});
});
4 changes: 2 additions & 2 deletions test/cases/0.js
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ use(chaiXml);
const { load } = require('js-yaml');
const fs = require('fs-extra');
const { slvParse } = require('slv-utils');
const XLSX = require('xlsx');
const XLSX = require('xlsx');

const sbml_l2v4_correct = fs.readFileSync('cases/0-hello-world/master/mm_sbml_l2v4/mm.xml','utf8');
const sbml_l3v1_correct = fs.readFileSync('cases/0-hello-world/master/mm_sbml_l3v1/mm.xml','utf8');
@@ -52,7 +52,7 @@ describe('Testing "cases/0-hello-world"', () => {
{format: 'Mrgsolve', spaceFilter: '^mm$'},
{format: 'Julia', spaceFilter: '^mm$'}]
};
b = new Builder(declaration, 'cases/0-hello-world');
b = new Builder(declaration, 'cases/0-hello-world', fs.readFileSync, () => {});
});

it('Run include', () => {
4 changes: 1 addition & 3 deletions test/cases/12.js
Original file line number Diff line number Diff line change
@@ -3,9 +3,7 @@ const { Builder } = require('../../src/builder');
const { expect, use } = require('chai');
const chaiXml = require('chai-xml');
use(chaiXml);
//const { load } = require('js-yaml');
const fs = require('fs-extra');
//const { slvParse } = require('slv-utils');

const sbml_correct = fs.readFileSync('cases/12-to-sbml/master/sbml/first.xml','utf8');
const json_correct = require('../../cases/12-to-sbml/master/output.json');
@@ -25,7 +23,7 @@ describe('Testing "cases/12-to-sbml"', () => {
source: 'src/index.heta'
}
};
b = new Builder(declaration, 'cases/12-to-sbml');
b = new Builder(declaration, 'cases/12-to-sbml', fs.readFileSync, () => {});
//console.log(b);
});

3 changes: 2 additions & 1 deletion test/cases/14.js
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@

const { Builder } = require('../../src');
const { expect, use } = require('chai');
const fs = require('fs-extra');

const json_correct = require('../../cases/14-sbml-module/master/output.json');

@@ -22,7 +23,7 @@ describe('Case #14: testing SBML module with units', () => {
export: [
{format: 'JSON'}
]
}, 'cases/14-sbml-module');
}, 'cases/14-sbml-module', fs.readFileSync, () => {});
b.run();
expect(b.container.logger).to.have.property('hasErrors').false;
});
2 changes: 1 addition & 1 deletion test/cases/6.js
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ describe('Testing "cases/6-import"', () => {
{format: 'SBML', spaceFilter: 'model'},
]
};
b = new Builder(declaration, 'cases/6-import');
b = new Builder(declaration, 'cases/6-import', fs.readFileSync, () => {});
//console.log(b);
});

2 changes: 1 addition & 1 deletion test/cases/7.tmp.js
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ describe('Testing "cases/7-importNS"', () => {
source: 'src/index.heta'
}
};
b = new Builder(declaration, 'cases/7-importNS');
b = new Builder(declaration, 'cases/7-importNS', fs.readFileSync, () => {});
//console.log(b);
});

3 changes: 0 additions & 3 deletions test/module-system/index.js
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@ const { expect } = require('chai');
const ModuleSystem = require('../../src/module-system');
const { Logger } = require('../../src/logger');
const path = require('path');
//const { writeFileSync } = require('fs');
const expected = require('./expected');
const noImportOutput = require('./no-include');
const fs = require('fs');
@@ -26,15 +25,13 @@ describe('Run normal ModuleSystem.', () => {
let ms = new ModuleSystem(logger, (filename) => fs.readFileSync(filename));
let filepath = path.join(__dirname, './normal-a.heta');
let mdl = ms.addModuleDeep(filepath, 'heta', {});
//writeFileSync('res0-new.json', JSON.stringify(ms, null, 2));

expect(mdl).to.be.with.a('Array').lengthOf(3);

expect(Object.keys(ms.moduleCollection)).to.have.property('length', 5);
expect(Object.keys(ms.graph.map)).to.have.property('length', 5);

let arr = ms.integrate();
//writeFileSync('res-new.json', JSON.stringify(arr, null, 2));
expect(arr).to.be.deep.equal(expected);
});
});
7 changes: 4 additions & 3 deletions test/module-xlsx/index.js
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ const { expect } = require('chai');
const { Builder } = require('../../src/builder');
const outputNameless = require('./output-nameless');
const outputOne = require('./output-one');
const fs = require('fs-extra');

describe('Integral test of correct xlsx module', () => {
it('Create platform for single XLSX sheet.', () => {
@@ -18,7 +19,7 @@ describe('Integral test of correct xlsx module', () => {
omitRows: 2
}
};
let b = new Builder(declaration, __dirname);
let b = new Builder(declaration, __dirname, fs.readFileSync, () => {});
b.run();
let resultNameless = b.container.namespaceStorage.get('nameless').toQArr(true);
expect(resultNameless).to.be.deep.equal(outputNameless);
@@ -38,7 +39,7 @@ describe('Integral test of correct xlsx module', () => {
sheet: 1
}
};
let b = new Builder(declaration, __dirname);
let b = new Builder(declaration, __dirname, fs.readFileSync, () => {});
b.run();
let resultNameless = b.container.namespaceStorage.get('nameless').toQArr(true);
expect(resultNameless).to.be.deep.equal(outputNameless);
@@ -56,7 +57,7 @@ describe('Integral test of correct xlsx module', () => {
sheet: 9
}
};
let b = new Builder(declaration, __dirname);
let b = new Builder(declaration, __dirname, fs.readFileSync, () => {});

b.run();
expect(b.container.hetaErrors()).to.be.lengthOf(1);

0 comments on commit af2976c

Please sign in to comment.