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