MCPcopy Create free account
hub / github.com/Serial-Studio/Serial-Studio / dryRun

Method dryRun

app/src/API/Handlers/ControlScriptHandler.cpp:155–216  ·  view source on GitHub ↗

* @brief Compile-checks control-script source in a throwaway engine, mirroring the worker's * compile step: stub bridge + SDK prelude + watchdogged top-level evaluation, then a * setup()/loop() presence check. Nothing is installed or executed. */

Source from the content-addressed store, hash-verified

153 * setup()/loop() presence check. Nothing is installed or executed.
154 */
155API::CommandResponse API::Handlers::ControlScriptHandler::dryRun(const QString& id,
156 const QJsonObject& params)
157{
158 if (!params.contains(QStringLiteral("code")))
159 return CommandResponse::makeError(
160 id, ErrorCode::MissingParam, QStringLiteral("Missing required parameter: code"));
161
162 const QString code = params.value(QStringLiteral("code")).toString();
163
164 QJsonObject result;
165 if (code.trimmed().isEmpty()) {
166 result[QStringLiteral("valid")] = false;
167 result[QStringLiteral("error")] = QStringLiteral("Script is empty");
168 return CommandResponse::makeSuccess(id, result);
169 }
170
171 QJSEngine engine;
172 engine.installExtensions(QJSEngine::ConsoleExtension);
173 DataModel::JsWatchdog watchdog(
174 &engine, kDryRunWatchdogMs, QStringLiteral("controlScript.dryRun"));
175
176 engine.evaluate(
177 QStringLiteral("var __ss_bridge = { call: function() { return { ok: false, error: 'dryRun' "
178 "}; }, listCommands: function() { return []; }, delay: function() {} };\n"
179 "var __ss_control = true;"));
180
181 QFile sdkFile(QStringLiteral(":/api/SerialStudio.js"));
182 if (sdkFile.open(QFile::ReadOnly))
183 engine.evaluate(QString::fromUtf8(sdkFile.readAll()));
184
185 watchdog.arm();
186 const auto evalResult = engine.evaluate(code, QStringLiteral("control-script.js"));
187 watchdog.disarm();
188
189 if (engine.isInterrupted()) {
190 engine.setInterrupted(false);
191 result[QStringLiteral("valid")] = false;
192 result[QStringLiteral("error")] =
193 QStringLiteral("Script did not finish evaluating within %1 ms (infinite loop at the top "
194 "level?)")
195 .arg(kDryRunWatchdogMs);
196 return CommandResponse::makeSuccess(id, result);
197 }
198
199 if (evalResult.isError()) {
200 result[QStringLiteral("valid")] = false;
201 result[QStringLiteral("line")] = evalResult.property(QStringLiteral("lineNumber")).toInt();
202 result[QStringLiteral("error")] = evalResult.toString();
203 return CommandResponse::makeSuccess(id, result);
204 }
205
206 const bool hasSetup = engine.globalObject().property(QStringLiteral("setup")).isCallable();
207 const bool hasLoop = engine.globalObject().property(QStringLiteral("loop")).isCallable();
208
209 result[QStringLiteral("valid")] = hasSetup || hasLoop;
210 result[QStringLiteral("hasSetup")] = hasSetup;
211 result[QStringLiteral("hasLoop")] = hasLoop;
212 if (!hasSetup && !hasLoop)

Callers

nothing calls this directly

Calls 8

isEmptyMethod · 0.80
disarmMethod · 0.80
isErrorMethod · 0.80
containsMethod · 0.45
valueMethod · 0.45
evaluateMethod · 0.45
openMethod · 0.45
armMethod · 0.45

Tested by

no test coverage detected