new command check to compare two values or to compare a value to the result of a command - command call now returns the value of the last statement
This commit is contained in:
112
src/commands.hxx
112
src/commands.hxx
@@ -111,7 +111,8 @@ class Command: public QObject {
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||
}
|
||||
protected:
|
||||
void runScript(std::shared_ptr<Script> script,
|
||||
bool runScript(Command* parentCommand,
|
||||
std::shared_ptr<Script> script,
|
||||
Script* parent, QWebFrame* frame,
|
||||
QStringList vars = QStringList(),
|
||||
QStringList args = QStringList());
|
||||
@@ -469,12 +470,13 @@ class Script: public QObject {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
void run(QWebFrame* frame) {
|
||||
run(frame, _testsuites, targetdir(), _screenshots, _maxretries);
|
||||
}
|
||||
void run(QWebFrame* frame, std::shared_ptr<xml::Node> testsuites,
|
||||
bool run(QWebFrame* frame) {
|
||||
return run(frame, _testsuites, targetdir(), _screenshots, _maxretries);
|
||||
}
|
||||
bool run(QWebFrame* frame, std::shared_ptr<xml::Node> testsuites,
|
||||
QString td = QString(), bool screenshots = true,
|
||||
int maxretries = 0) {
|
||||
bool res(true);
|
||||
_testsuites = testsuites;
|
||||
_timeout = 20; // defaults to 20s
|
||||
_ignoreSignalsUntil.clear();
|
||||
@@ -502,7 +504,7 @@ class Script: public QObject {
|
||||
if (!_ignores.size() || (*cmd)->tag()=="label") { // not ignored
|
||||
_timer.start(_timeout*1000);
|
||||
try {
|
||||
if (!(*cmd)->execute(this, frame)) {
|
||||
if (!(res=(*cmd)->execute(this, frame))) {
|
||||
_timer.stop();
|
||||
if (!back) retries = 0; else --back;
|
||||
testcase<<(xml::String("system-out") =
|
||||
@@ -608,6 +610,7 @@ class Script: public QObject {
|
||||
}
|
||||
removeSignals(frame);
|
||||
if (!_signals.empty()) throw UnhandledSignals(_signals);
|
||||
return res;
|
||||
}
|
||||
QString& cout() {
|
||||
return _cout;
|
||||
@@ -718,6 +721,10 @@ class Script: public QObject {
|
||||
}
|
||||
return txt;
|
||||
}
|
||||
QString result() {
|
||||
if (_script.size()) return (*_script.rbegin())->result();
|
||||
return QString();
|
||||
}
|
||||
void addSignals(QWebFrame* frame) {
|
||||
connect(dynamic_cast<NetworkAccessManager*>
|
||||
(frame->page()->networkAccessManager()),
|
||||
@@ -1496,9 +1503,10 @@ class Set: public Command {
|
||||
"\n\n"
|
||||
"Sets the value of a variable either to a constant, or to the output"
|
||||
" of a command. A command should be a command that produces an"
|
||||
" output, such as «do», which returns the result of JavaScript or"
|
||||
" «execute», which returns the output of the executed command."
|
||||
" All variables are global with regrad to functions.";
|
||||
" output, such as <do>, which returns the result of JavaScript or"
|
||||
" <execute>, which returns the output of the executed command, or"
|
||||
" <call>, which returns the result of the last command."
|
||||
" All variables are global with regard to functions.";
|
||||
}
|
||||
QString command() const {
|
||||
if (_next)
|
||||
@@ -1840,14 +1848,14 @@ class Function: public Command {
|
||||
Logger log(this, script);
|
||||
return true;
|
||||
}
|
||||
bool call(QStringList args, Script* script, QWebFrame* frame) {
|
||||
bool call(Command* parentCommand, QStringList args,
|
||||
Script* script, QWebFrame* frame) {
|
||||
Logger log(this, script);
|
||||
try {
|
||||
runScript(_script, script, frame, _vars, args);
|
||||
return runScript(parentCommand, _script, script, frame, _vars, args);
|
||||
} catch (const std::exception& x) {
|
||||
throw FunctionCallFailed(_name, _vars, args, x);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
QString _name;
|
||||
@@ -1883,8 +1891,7 @@ class Call: public Command {
|
||||
}
|
||||
bool execute(Script* script, QWebFrame* frame) {
|
||||
Logger log(this, script);
|
||||
script->function(_name)->call(_args, script, frame);
|
||||
return true;
|
||||
return script->function(_name)->call(this, _args, script, frame);
|
||||
}
|
||||
public:
|
||||
QString _name;
|
||||
@@ -1953,8 +1960,8 @@ class If: public Command {
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
if (check) runScript(_script, script, frame);
|
||||
else if (_else) runScript(_else, script, frame);
|
||||
if (check) return runScript(this, _script, script, frame);
|
||||
else if (_else) return runScript(this, _else, script, frame);
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
@@ -2023,6 +2030,71 @@ class TestCase: public Command {
|
||||
QString _name;
|
||||
};
|
||||
|
||||
class Check: public Command {
|
||||
public:
|
||||
QString tag() const {
|
||||
return "check";
|
||||
}
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <value1> <op> <value2>\n"+
|
||||
tag()+" <value1>\n"
|
||||
" <command>"
|
||||
"\n\n"
|
||||
"Compares two values (you can use variables) or compares a value to the"
|
||||
" result of a command. The command should be a command that produces an"
|
||||
" output, such as <do>, which returns the result of JavaScript or"
|
||||
" <execute>, which returns the output of the executed command, or"
|
||||
" <call>, which returns the result of the last command.";
|
||||
}
|
||||
QString command() const {
|
||||
if (_next)
|
||||
return tag()+" "+_value1+" "+QString(_cmp)+"\n "+_next->command();
|
||||
else
|
||||
return tag()+" "+_value1+" "+QString(_cmp)+" "+_value2;
|
||||
}
|
||||
std::shared_ptr<Command> parse(Script* script, QString args,
|
||||
QStringList& in, int line) {
|
||||
std::shared_ptr<Check> cmd(new Check());
|
||||
cmd->_next = 0;
|
||||
int pos(args.indexOf(QRegularExpression("[=^~<>]")));
|
||||
if (pos<0) throw BadArgument(tag()+" needs a comparision, not: "+args);
|
||||
cmd->_value1 = args.left(pos).trimmed();
|
||||
cmd->_cmp = args[pos].toLatin1();
|
||||
cmd->_value2 = args.mid(pos+1).trimmed();
|
||||
if (in.size() && in.first().contains(QRegularExpression("^ "))) {
|
||||
cmd->_next = script->parse(in, line+1);
|
||||
cmd->_next->log(false); // suppress logging of subcommand
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
bool execute(Script* script, QWebFrame* frame) {
|
||||
Logger log(this, script);
|
||||
QString value1(script->replacevars(_value1));
|
||||
QString value2(script->replacevars(_value2));
|
||||
if (_next) {
|
||||
_next->execute(script, frame);
|
||||
value2 = script->replacevars(_next->result());
|
||||
}
|
||||
bool check(false);
|
||||
switch (_cmp) {
|
||||
case '=': check = value1==value2; break;
|
||||
case '^': check = value1!=value2; break;
|
||||
case '~': check = value1.contains(QRegularExpression(value2)); break;
|
||||
case '<': check = value1.toInt()<value2.toInt(); break;
|
||||
case '>': check = value1.toInt()>value2.toInt(); break;
|
||||
default:;
|
||||
}
|
||||
if (!check) throw CheckFailed(value1, _cmp, value2);
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
QString _value1;
|
||||
QString _value2;
|
||||
char _cmp;
|
||||
std::shared_ptr<Command> _next;
|
||||
};
|
||||
|
||||
/* Template:
|
||||
class : public Command {
|
||||
public:
|
||||
@@ -2079,7 +2151,8 @@ inline Logger::~Logger() {
|
||||
_script->log("---------------------");
|
||||
}
|
||||
|
||||
inline void Command::runScript(std::shared_ptr<Script> script,
|
||||
inline bool Command::runScript(Command* parentCommand,
|
||||
std::shared_ptr<Script> script,
|
||||
Script* parent, QWebFrame* frame,
|
||||
QStringList vars,
|
||||
QStringList args) {
|
||||
@@ -2093,10 +2166,12 @@ inline void Command::runScript(std::shared_ptr<Script> script,
|
||||
connect(script.get(), SIGNAL(logging(QString)),
|
||||
parent, SLOT(log(QString)));
|
||||
parent->removeSignals(frame);
|
||||
script->run(frame);
|
||||
bool res(script->run(frame));
|
||||
parent->addSignals(frame);
|
||||
disconnect(script.get(), SIGNAL(logging(QString)),
|
||||
parent, SLOT(log(QString)));
|
||||
parentCommand->_result = script->result();
|
||||
return res;
|
||||
} catch (const std::exception& x) {
|
||||
parent->addSignals(frame);
|
||||
disconnect(script.get(), SIGNAL(logging(QString)),
|
||||
@@ -2133,6 +2208,7 @@ inline void Script::initPrototypes() {
|
||||
add(new If);
|
||||
add(new TestSuite);
|
||||
add(new TestCase);
|
||||
add(new Check);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -253,4 +253,12 @@ class VariableNotFound: public TestFailed {
|
||||
}
|
||||
};
|
||||
|
||||
class CheckFailed: public TestFailed {
|
||||
public:
|
||||
CheckFailed(QString value1, char cmp, QString value2):
|
||||
TestFailed(QString("check failed: %1 %2 %3")
|
||||
.arg(value1).arg(cmp).arg(value1)) {
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user