diff --git a/packages/xod-cli/package.json b/packages/xod-cli/package.json index 2df17040..f984669d 100644 --- a/packages/xod-cli/package.json +++ b/packages/xod-cli/package.json @@ -20,6 +20,7 @@ "dependencies": { "cli-color": "^1.1.0", "docopt": "^0.6.2", + "fs-extra": "^4.0.2", "hm-def": "^0.3.2", "inquirer": "^3.2.0", "ramda": "^0.24.1", @@ -31,12 +32,13 @@ "xod-fs": "^0.19.4", "xod-func-tools": "^0.19.2", "xod-pm": "^0.19.4", - "xod-project": "^0.19.4" + "xod-project": "^0.19.4", + "xod-pm": "^0.19.4", + "xod-tabtest": "^0.19.2" }, "devDependencies": { "chai": "^4.1.2", "child-process-promise": "^2.2.1", - "cpx": "^1.5.0", - "fs-extra": "^4.0.2" + "cpx": "^1.5.0" } } diff --git a/packages/xod-cli/src/xodc-tabtest.js b/packages/xod-cli/src/xodc-tabtest.js new file mode 100644 index 00000000..83fc6ad9 --- /dev/null +++ b/packages/xod-cli/src/xodc-tabtest.js @@ -0,0 +1,95 @@ +// xodc tabtest [--workspace=] +import path from 'path'; +import os from 'os'; +import * as R from 'ramda'; +import fs from 'fs-extra'; +import childProcess from 'child_process'; + +import { foldEither, allPromises } from 'xod-func-tools'; +import { loadProject } from 'xod-fs'; +import * as Tabtest from 'xod-tabtest'; +import * as msg from './messageUtils'; +import { getWorkspacePath } from './utils'; + +const bundledWorkspace = path.resolve(__dirname, '..'); +const tabtestWorkspace = path.resolve( + __dirname, + '..', + '..', + 'xod-tabtest', + 'workspace' +); + +const tabtestSources = path.resolve( + __dirname, + '..', + '..', + 'xod-tabtest', + 'cpp' +); + +const catch2Sources = path.resolve( + __dirname, + '..', + '..', + '..', + 'vendor', + 'catch2' +); + +const showErrorAndExit = err => { + msg.error(err); + process.exit(1); +}; + +const spawn = (cmd, args, opts) => + new Promise((resolve, reject) => { + childProcess.spawn(cmd, args, opts).on('exit', code => { + if (code === 0) { + resolve(); + } else { + reject(new Error(`${cmd} exited with code ${code}`)); + } + }); + }); + +const tapProgress = note => R.tap(() => msg.notice(note)); + +export default (input, patchPath, program) => { + const workspaces = [ + getWorkspacePath(program.workspace), + tabtestWorkspace, + bundledWorkspace, + ]; + + const outDir = path.join(os.tmpdir(), 'xod-tabtest'); + const childProcessOpts = { + stdio: 'inherit', + shell: true, + cwd: outDir, + }; + + const saveOutFile = ([filename, content]) => + fs.outputFile(path.join(outDir, filename), content); + + msg.notice(`Preparing test directory: ${outDir} ...`); + + fs + .ensureDir(outDir) + .then(tapProgress('Loading project...')) + .then(() => loadProject(workspaces, input)) + .then(tapProgress('Generating C++ code...')) + .then(project => Tabtest.generateSuite(project, patchPath)) + .then(foldEither(err => showErrorAndExit(err), R.identity)) + .then(R.toPairs) + .then(tapProgress('Saving files...')) + .then(R.map(saveOutFile)) + .then(R.append(fs.copy(tabtestSources, outDir))) + .then(R.append(fs.copy(catch2Sources, outDir))) + .then(allPromises) + .then(tapProgress('Compiling...')) + .then(() => spawn('make', [], childProcessOpts)) + .then(tapProgress('Testing...')) + .then(() => spawn('make', ['test'], childProcessOpts)) + .catch(showErrorAndExit); +}; diff --git a/packages/xod-cli/src/xodc.js b/packages/xod-cli/src/xodc.js index 9c644c58..4914f59a 100644 --- a/packages/xod-cli/src/xodc.js +++ b/packages/xod-cli/src/xodc.js @@ -9,6 +9,7 @@ import pack from './xodc-pack'; import publish from './xodc-publish'; import transpile from './xodc-transpile'; import unpack from './xodc-unpack'; +import tabtest from './xodc-tabtest'; const PM_SWAGGER_URL = 'https://pm.xod.io/swagger'; @@ -29,6 +30,7 @@ Usage: xodc transpile [--output=] [--workspace=] xodc publish [--swagger=] [--orgname=] [] xodc install [--swagger=] [--workspace=] + xodc tabtest [--workspace=] Commands: pack Pack project directory into xodball. @@ -36,6 +38,7 @@ Commands: transpile Transpile project into device runtime. publish Publish a new library version. install Install the library into workspace. + tabtest Run tabular tests. Options: --output= Write result of transpilation into file. @@ -61,6 +64,10 @@ const programs = { ), install: o => install(o['--swagger'] || PM_SWAGGER_URL, o[''], o['--workspace']), + tabtest: o => + tabtest(o[''], o[''], { + workspace: o['--workspace'], + }), }; // Running command