Skip to content

Allowing to ask from console #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 88 additions & 60 deletions src/test.js
Original file line number Diff line number Diff line change
@@ -1,87 +1,115 @@
const fs = require('fs')
const path = require('path')
const chalk = require("chalk")
const shell = require('shelljs')
const transformer = require.resolve('./utils/babelTransformer')
const { TestingError } = require('learnpack/plugin')
const { getPrompts } = require("./utils");
const fs = require("fs");
const path = require("path");
const chalk = require("chalk");
const shell = require("shelljs");
const transformer = require.resolve("./utils/babelTransformer");
const { TestingError } = require("learnpack/plugin");

let nodeModulesPath = path.dirname(require.resolve('jest'))
nodeModulesPath = nodeModulesPath.substr(0,nodeModulesPath.indexOf("node_modules")) + "node_modules/"
let nodeModulesPath = path.dirname(require.resolve("jest"));
nodeModulesPath =
nodeModulesPath.substr(0, nodeModulesPath.indexOf("node_modules")) +
"node_modules/";

module.exports = {
validate: async function({ exercise, configuration }){

if (!shell.which('jest')) {
console.log(nodeModulesPath);

module.exports = {
validate: async function ({ exercise, configuration }) {
if (!shell.which("jest")) {
const packageName = "jest@24.8.0";
throw TestingError(`🚫 You need to have ${packageName} installed to run test the exercises, run $ npm i ${packageName} -g`);
throw TestingError(
`🚫 You need to have ${packageName} installed to run test the exercises, run $ npm i ${packageName} -g`
);
}

return true
return true;
},
run: async ({ exercise, socket, configuration }) => {

let jestConfig = {
verbose: true,
moduleDirectories: [nodeModulesPath],
transform: {
"^.+\\.js?$": transformer
"^.+\\.js?$": transformer,
},
globalSetup: path.resolve(__dirname, './utils/prepend.test.js')
}
};

const getEntry = () => {

let testsPath = exercise.files.map(f => f.path).find(f => f.includes('test.js') || f.includes('tests.js'));
if (!fs.existsSync(testsPath)) throw TestingError(`🚫 No test script found on the exercise files`);

let testsPath = exercise.files
.map((f) => f.path)
.find((f) => f.includes("test.js") || f.includes("tests.js"));
if (!fs.existsSync(testsPath))
throw TestingError(`🚫 No test script found on the exercise files`);

return testsPath;
}
};

const getCommands = async function(){
const getCommands = async function () {
jestConfig.reporters = [
[
__dirname + "/utils/reporter.js",
{
reportPath: `${configuration.dirPath}/reports/${exercise.slug}.json`,
},
],
];

const appPath = exercise.files.map(f => './'+f.path).find(f => f.includes(exercise.entry || 'app.js'));
let answers = []
if(appPath){
const content = fs.readFileSync(appPath, "utf8");
const promptsValues = getPrompts(content);
answers = (promptsValues.length === 0) ? [] : await socket.ask(promptsValues);
}

jestConfig.reporters = [[ __dirname+'/utils/reporter.js', { reportPath: `${configuration.dirPath}/reports/${exercise.slug}.json` }]];
return `jest --config '${JSON.stringify({ ...jestConfig, globals: { __stdin: answers }, testRegex: getEntry() })}' --colors`
}
return `jest --config '${JSON.stringify({
...jestConfig,
testRegex: getEntry(),
})}' --colors`;
};

const getStdout = (rawStdout) => {
let _stdout = [];
if (fs.existsSync(`${configuration.dirPath}/reports/${exercise.slug}.json`)){
const _text = fs.readFileSync(`${configuration.dirPath}/reports/${exercise.slug}.json`);
if (
fs.existsSync(`${configuration.dirPath}/reports/${exercise.slug}.json`)
) {
const _text = fs.readFileSync(
`${configuration.dirPath}/reports/${exercise.slug}.json`
);
const errors = JSON.parse(_text);

_stdout = errors.testResults.map(r => r.message);

if(errors.failed.length > 0){
msg = `\n\n ${'Your code must to comply with the following tests:'.red} \n\n${[...new Set(errors.failed)].map((e,i) => ` ${e.status !== 'failed' ? chalk.green.bold('✓ (done)') : chalk.red.bold('x (fail)')} ${i}. ${chalk.white(e.title)}`).join('\n')} \n\n`;

_stdout = errors.testResults.map((r) => r.message);

if (errors.failed.length > 0) {
msg = `\n\n ${
"Your code must to comply with the following tests:".red
} \n\n${[...new Set(errors.failed)]
.map(
(e, i) =>
` ${
e.status !== "failed"
? chalk.green.bold("✓ (done)")
: chalk.red.bold("x (fail)")
} ${i}. ${chalk.white(e.title)}`
)
.join("\n")} \n\n`;
_stdout.push(msg);
}
}
else throw TestingError("Could not find the error report for "+exercise.slug);
return _stdout
}
} else
throw TestingError(
"Could not find the error report for " + exercise.slug
);
return _stdout;
};

let commands = await getCommands()
let commands = await getCommands();

if(!Array.isArray(commands)) commands = [commands]
let stdout, stderr, code = [null, null, null]
for(let cycle = 0; cycle < commands.length; cycle++){
let resp = shell.exec(commands[cycle], { silent: true })
stdout = resp.stdout
code = resp.code
stderr = resp.stderr
if(code != 0) break
if (!Array.isArray(commands)) commands = [commands];
let stdout,
stderr,
code = [null, null, null];
for (let cycle = 0; cycle < commands.length; cycle++) {
let resp = shell.exec(commands[cycle], { silent: true });
stdout = resp.stdout;
code = resp.code;
stderr = resp.stderr;
if (code != 0) break;
}

if(code != 0) throw TestingError(getStdout(stdout || stderr).join())
else return stdout && stdout.length > 0 ? stdout : chalk.green("✔ All tests have passed")
}
}
if (code != 0) throw TestingError(getStdout(stdout || stderr).join());
else
return stdout && stdout.length > 0
? stdout
: chalk.green("✔ All tests have passed");
},
};
26 changes: 21 additions & 5 deletions src/utils/index.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
const acorn = require("acorn")
const walk = require("acorn-walk")
const acorn = require("acorn");
const walk = require("acorn-walk");
const readline = require("readline");

const getPrompts = (content) => {
const inputs = [];

walk.full(acorn.parse(content, { ecmaVersion: 2020 }), (node) => {
if (node.type === "CallExpression") {
if (node.callee.name === "prompt") {
inputs.push(node.arguments.map((a) => a.value))
inputs.push(node.arguments.map((a) => a.value));
}
}
});

return inputs.flat()
return inputs.flat();
};

module.exports = { getPrompts }
// Used to ask by console
const askInCommandLine = async (question) => {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});

return new Promise((resolve, reject) => {
rl.question(`${question} `, (line) => {
resolve(line);
rl.close();
});
});
};

module.exports = { getPrompts, askInCommandLine };
20 changes: 0 additions & 20 deletions src/utils/prepend.test.js

This file was deleted.