Skip to content

Commit 56104fa

Browse files
committed
Disable UI interaction while generating tests
1 parent d12a0a4 commit 56104fa

File tree

4 files changed

+61
-43
lines changed

4 files changed

+61
-43
lines changed

simulator/src/ComponentFactory.ts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -514,19 +514,26 @@ export class ComponentFactory {
514514
return ""
515515
}
516516

517-
// TODO switch mode just like for running test cases
518-
const testCases: TestCaseCombinational[] = []
519-
for (let i = 0; i < numCases; i++) {
520-
for (let j = 0; j < numInputs; j++) {
521-
const value = (i & (1 << j)) !== 0
522-
setBit(j, value)
517+
const result = await editor.disableUIWhile(s.ComputingTestCases, async restoreAfter => {
518+
for (const input of inputs) {
519+
restoreAfter.set(input, input.value)
523520
}
524-
editor.recalcPropagateAndDrawIfNeeded(true)
525-
await editor.waitForPropagation()
526-
testCases.push(this.makeTestCaseWithCurrentValues(editor, inputs, outputs, false))
527-
}
528521

529-
return testCases
522+
const testCases: TestCaseCombinational[] = []
523+
for (let i = 0; i < numCases; i++) {
524+
for (let j = 0; j < numInputs; j++) {
525+
const value = (i & (1 << j)) !== 0
526+
setBit(j, value)
527+
}
528+
editor.recalcPropagateAndDrawIfNeeded(true)
529+
await editor.waitForPropagation()
530+
testCases.push(this.makeTestCaseWithCurrentValues(editor, inputs, outputs, false))
531+
}
532+
533+
return testCases
534+
})
535+
536+
return result ?? ""
530537
}
531538

532539
public tryModifyCustomComponent(def: CustomComponentDef, defRoot: CustomComponent): undefined | string {

simulator/src/LogicEditor.ts

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ export class LogicEditor extends HTMLElement implements DrawableParent {
206206
private _isSingleton = false
207207
private _maxInstanceMode: Mode = MAX_MODE_WHEN_EMBEDDED // can be set later
208208
private _isDirty = false
209-
private _isRunningTests = false
209+
private _isUIDisabled = false // when inputs are being set programmatically over a longer period
210210
private _mode: Mode = DEFAULT_MODE
211211
private _initialData: InitialData | undefined = undefined
212212
private _options: EditorOptions = { ...DEFAULT_EDITOR_OPTIONS }
@@ -1035,8 +1035,7 @@ export class LogicEditor extends HTMLElement implements DrawableParent {
10351035
}
10361036
this.html.rootDiv.setAttribute(ATTRIBUTE_NAMES.nomodes, nomodes.join(" "))
10371037

1038-
1039-
// console.log(`Display/interaction is ${wantedModeStr} - ${mode}`)
1038+
// console.log(`Current mode is ${modeStr} - ${mode}`)
10401039

10411040
this.editTools.redrawMgr.addReason("mode changed", null, true)
10421041

@@ -1741,26 +1740,45 @@ export class LogicEditor extends HTMLElement implements DrawableParent {
17411740
}
17421741
}
17431742

1744-
public async runTestSuite(testSuite: TestSuite, options?: { doLog?: boolean, fast?: boolean }): Promise<TestSuiteResults | undefined> {
1745-
1746-
if (this._isRunningTests) {
1743+
public async disableUIWhile<T>(message: string, action: (restoreAfter: Map<Input, LogicValue[]>) => Promise<T>): Promise<T | undefined> {
1744+
if (this._isUIDisabled) {
17471745
// cannot run tests while already running
17481746
return undefined
17491747
}
17501748

1749+
this._isUIDisabled = true
1750+
const oldMode = this.mode
1751+
const restoreAfter = new Map<Input, LogicValue[]>()
1752+
const hideMsg = this.showMessage(message, 0)
1753+
1754+
try {
1755+
this.setMode(Mode.STATIC, false)
1756+
const result = await action(restoreAfter)
1757+
return result
1758+
} finally {
1759+
hideMsg()
1760+
this.setMode(oldMode, true)
1761+
for (const [input, value] of restoreAfter) {
1762+
input.setValue(value)
1763+
}
1764+
this._isUIDisabled = false
1765+
this.recalcPropagateAndDrawIfNeeded()
1766+
}
1767+
1768+
}
1769+
1770+
public async runTestSuite(testSuite: TestSuite, options?: { doLog?: boolean, fast?: boolean }): Promise<TestSuiteResults | undefined> {
1771+
17511772
const palette = this.editTools.testsPalette
17521773
if (palette === undefined) {
17531774
return undefined
17541775
}
17551776

1756-
this._isRunningTests = true
1757-
const oldMode = this.mode
17581777
const fast = options?.fast ?? false
17591778
const doLog = options?.doLog ?? false
1760-
const allOldInValues = new Map<Input, LogicValue[]>()
17611779

1762-
try {
1763-
this.setMode(Mode.STATIC, false)
1780+
return this.disableUIWhile(S.Messages.RunningTests, async restoreAfter => {
1781+
17641782
this.setTestsPaletteVisible(true) // after setMode, which may hide it
17651783

17661784
const results = new TestSuiteResults(testSuite)
@@ -1785,8 +1803,8 @@ export class LogicEditor extends HTMLElement implements DrawableParent {
17851803
const [oldInValues, result] = await this.runTestCase(testCase, testSuite, doLog)
17861804
testCaseResult = result
17871805
for (const [input, value] of oldInValues) {
1788-
if (!allOldInValues.has(input)) {
1789-
allOldInValues.set(input, value)
1806+
if (!restoreAfter.has(input)) {
1807+
restoreAfter.set(input, value)
17901808
}
17911809
}
17921810
}
@@ -1797,15 +1815,7 @@ export class LogicEditor extends HTMLElement implements DrawableParent {
17971815
}
17981816
}
17991817
return results
1800-
1801-
} finally {
1802-
this.setMode(oldMode, true)
1803-
for (const [input, value] of allOldInValues) {
1804-
input.setValue(value)
1805-
}
1806-
this._isRunningTests = false
1807-
this.recalcPropagateAndDrawIfNeeded()
1808-
}
1818+
})
18091819
}
18101820

18111821
public trySetInputsAndRecalc(inputs: TestCaseValueMap<Input>) {
@@ -1825,12 +1835,10 @@ export class LogicEditor extends HTMLElement implements DrawableParent {
18251835
doLog: boolean
18261836
): Promise<[Map<Input, LogicValue[]>, TestCaseResult]> {
18271837

1828-
const fullTestNameParts = [sourceSuite.name, testCase.name].filter(Boolean)
1829-
const fullTestName = fullTestNameParts.length === 0 ? S.Tests.DefaultTestCaseName : fullTestNameParts.join("/")
1830-
const msg = S.Messages.RunningTestCase.expand({ name: fullTestName })
1831-
const hideMsg = this.showMessage(msg, 0)
18321838
if (doLog) {
1833-
console.group(msg)
1839+
const fullTestNameParts = [sourceSuite.name, testCase.name].filter(Boolean)
1840+
const fullTestName = fullTestNameParts.length === 0 ? S.Tests.DefaultTestCaseName : fullTestNameParts.join("/")
1841+
console.group("Running test case " + fullTestName)
18341842
}
18351843

18361844
testCase.tryFixReferences(this.editorRoot.components)
@@ -1874,7 +1882,6 @@ export class LogicEditor extends HTMLElement implements DrawableParent {
18741882
if (doLog) {
18751883
console.groupEnd()
18761884
}
1877-
hideMsg()
18781885
}
18791886
}
18801887

simulator/src/TestsPalette.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,10 @@ export class TestSuiteUI {
190190
}
191191

192192
private makeComponentRefSpan(elem: Input | Output | string): HTMLElement {
193-
const ref = isString(elem) ? elem : elem.ref ?? "?"
194-
const link = a(ref, href("#")).render()
193+
const compStr = isString(elem) ? elem
194+
: isString(elem.name) ? elem.name
195+
: elem.ref ?? "?"
196+
const link = a(compStr, href("#")).render()
195197
link.addEventListener("click", () => {
196198
this.editor.highlight(elem)
197199
})

simulator/src/strings.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,13 +236,14 @@ const Strings_fr = {
236236
NothingToUndo: "Rien à annuler",
237237
NothingToRedo: "Rien à rétablir ou répéter",
238238

239-
RunningTestCase: template("Exécution du test ${name}..."),
240239
NewTestCaseTitle: "Création d’un nouveau test de circuit",
241240
NewTestCaseSetName: "Entrez le nom du test:",
242241
TestCaseInputToSet: template("Entrée$s{n} à régler:"),
243242
TestCaseOuputToCheck: template("Sorties$s{n} attendue$s{n}:"),
244243
TooManyInputsForAutoTestCases: template("Impossible de créer automatiquement des tests pour plus de ${max} entrées."),
245244
AutoTestCasesWarning: template("Ceci va créer ${numCases} tests, un pour chacune des combinaisons des ${numInputs} entrées. Voulez-vous continuer?"),
245+
ComputingTestCases: "Génération des tests…",
246+
RunningTests: "Excécution des tests…",
246247

247248
},
248249
Components: {
@@ -1022,13 +1023,14 @@ const Strings_en: Strings = {
10221023
NothingToUndo: "Nothing to undo",
10231024
NothingToRedo: "Nothing to redo or repeat",
10241025

1025-
RunningTestCase: template("Running test case ${name}..."),
10261026
NewTestCaseTitle: "Create a new test case",
10271027
NewTestCaseSetName: "Enter the name of the new test case:",
10281028
TestCaseInputToSet: template("Input$s{n} to set:"),
10291029
TestCaseOuputToCheck: template("Output$s{n} to check:"),
10301030
TooManyInputsForAutoTestCases: template("Cannot create test cases automatically for more than ${max} inputs."),
10311031
AutoTestCasesWarning: template("This will create ${numCases} test cases, one for each combination of the ${numInputs} inputs. Do you want to continue?"),
1032+
ComputingTestCases: "Generating test cases…",
1033+
RunningTests: "Running test cases…",
10321034

10331035
},
10341036
Components: {

0 commit comments

Comments
 (0)