sugarcube-test-config-manager/test-config-manager.js

110 lines
4.4 KiB
JavaScript
Raw Normal View History

!function(){
"use strict";
variables().ADDON_TEST_CONFIG_MGR_STATE = 'ready';
variables().ADDON_TEST_CONFIG_MGR_ERRORS = [];
Macro.add('touch', {
handler: function() {
"use strict";
if (!Config.debug) {
return this.error("Shouldn't reach me outside of debug mode.");
}
let errs = variables().ADDON_TEST_CONFIG_MGR_ERRORS;
if (!variables().ADDON_TEST_CONFIG_MGR_STATE === 'loading') {
errs.push("Tried to {{{touch " + this.args.raw + "}}} while not loading a test config.");
return this.error("Only use me during test configuration.");
}
const realpassage = this.contextSelect((ctx) => ctx.name === 'include')?.name ?? passage();
for(const item of this.args) {
if (Story.has(item)) {
State.create(item);
} else {
errs.push("Can't find passage {{{" + item + "}}} when {{{"
+ realpassage + "}}} tried to touch it.");
}
}
}
});
$(document).on(':passagestart', function(ev) {
"use strict";
if (!Config.debug) {
return;
}
switch(variables().ADDON_TEST_CONFIG_MGR_STATE) {
case 'ready':
// 1. load candidate config passages
// 2. present UI
// a. "no configs" message
// b. "choose a config" selector and activation button
// notes on activation button:
// 1. silently executes chosen passage
// 2. if the tour stack is empty, done
// 3. if the tour stack is not empty:
// a. push current location
// b. reverse it
// c. set state to "touring"
// 4. reload current page without history entry
let config_passages = Story.lookup('tags', 'test-config');
if (config_passages.length) {
let dropdown = document.createElement("select");
dropdown.id = "addon_test_config_mgr_config_picker";
for (const p of config_passages) {
let op = document.createElement("option");
op.value = p.title;
op.text = p.title;
dropdown.appendChild(op);
}
let load_button = document.createElement("button");
load_button.innerText = "Load";
load_button.onclick = function() {
if (!Config.debug) {
// debugging got disabled, ignore it
return;
}
const orig_passage = passage();
variables().ADDON_TEST_CONFIG_MGR_STATE="loading";
const target = document.getElementById("addon_test_config_mgr_config_picker")?.value;
if (!target) {
return;
}
$.wiki("<<include \"" + target + "\">>");
variables().ADDON_TEST_CONFIG_MGR_STATE = 'done';
Engine.play(orig_passage, passage() == orig_passage);
};
$(ev.content).wiki("^^Test Config Manager^^\n"
+ "!!!Would you like to load a test config?\n");
$(ev.content).append(dropdown).append(load_button);
$(ev.content).wiki("\n----\n");
} else {
$(ev.content).wiki("^^Test Config Manager^^\n"
+ "!!!No test configs found.\n"
+ "To create a test configuration, create a passage "
+ "tagged with {{{test-config}}}, containing test setup "
+ "code for a test scenario. You can use the "
+ "{{{touch}}} macro inside a test configuration to "
+ "add passages to the history during setup.\n"
+ "----\n");
}
variables().ADDON_TEST_CONFIG_MGR_STATE = 'done';
return;
case 'loading':
// do nothing, we are in the middle of processing a configuration
return;
}
// state should be "done"; if not, that's an error.
if (variables().ADDON_TEST_CONFIG_MGR_STATE !== 'done') {
variables().ADDON_TEST_CONFIG_MGR_ERRORS.push(
"Invalid state: \"$ADDON_TEST_CONFIG_MGR_STATE\"");
}
let errs = variables().ADDON_TEST_CONFIG_MGR_ERRORS;
if (errs.length) {
$(ev.content).wiki("^^Test Config Manager^^\n\n"
+ "!!Errors during test configuration.\n\n");
for (const err of errs) {
$(ev.content).wiki("* " + err + "\n")
}
$(ev.content).wiki("\n----\n");
variables().ADDON_TEST_CONFIG_MGR_ERRORS = [];
}
});
}();