Skip to content

Commit 703a626

Browse files
committed
test(logo): address review feedback on coverage tests
- Strengthen behaviour assertions: replace toHaveBeenCalled() checks on mocked safePluginExecute/pluginFn with observable side-effect assertions (return value, block.value mutation, effects array) so tests survive refactors that preserve the same outcome via a different call path - evalArgDict test now verifies parseArg returns the value the plugin wrote to blockList[blk].value rather than spying on the call - evalOnStartList and evalFlowDict tests use real plugin functions that push to a side-effect array; no longer mock safePluginExecute - safePluginExecute "function executes" test drops the redundant toHaveBeenCalledWith assertion — the return value already proves execution occurred - Remove weak processSpeak smoke test (function body is empty; the test only proved it does not crash, not that it does anything) - Consolidate console spy teardown with afterEach(jest.restoreAllMocks) in safePluginExecute, parseArg, and doStopTurtles describe blocks; remove the per-test mockRestore() calls that the afterEach now covers Signed-off-by: Vanshika <pahalvanshikaa@gmail.com>
1 parent 349f02d commit 703a626

1 file changed

Lines changed: 27 additions & 42 deletions

File tree

js/__tests__/logo.test.js

Lines changed: 27 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1705,10 +1705,10 @@ describe("Logo safePluginExecute", () => {
17051705
logo = new Logo(mockActivity);
17061706
});
17071707

1708-
test("calls function code with correct arguments and returns result", () => {
1709-
const pluginFn = jest.fn(() => 42);
1710-
const result = logo.safePluginExecute(pluginFn, logo, 0, 0, null);
1711-
expect(pluginFn).toHaveBeenCalledWith(logo, 0, 0, null);
1708+
afterEach(() => jest.restoreAllMocks());
1709+
1710+
test("executes function code and returns its result", () => {
1711+
const result = logo.safePluginExecute(() => 42, logo, 0, 0, null);
17121712
expect(result).toBe(42);
17131713
});
17141714

@@ -1720,7 +1720,6 @@ describe("Logo safePluginExecute", () => {
17201720
const result = logo.safePluginExecute(crashFn, logo, 0, 0, null);
17211721
expect(errorSpy).toHaveBeenCalled();
17221722
expect(result).toBeUndefined();
1723-
errorSpy.mockRestore();
17241723
});
17251724

17261725
test("returns undefined for non-string non-function code", () => {
@@ -1790,7 +1789,6 @@ describe("Logo safePluginExecute", () => {
17901789
const result = logo.safePluginExecute("eval('alert(1)')", logo, 0, 0, null);
17911790
expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining("Blocked"), expect.anything());
17921791
expect(result).toBeUndefined();
1793-
warnSpy.mockRestore();
17941792
});
17951793
});
17961794

@@ -1811,6 +1809,8 @@ describe("Logo parseArg additional edge cases", () => {
18111809
logo.inStatusMatrix = false;
18121810
});
18131811

1812+
afterEach(() => jest.restoreAllMocks());
1813+
18141814
test("dectofrac with null child block shows NOINPUTERRORMSG and sets value to 0", () => {
18151815
logo.blockList = [
18161816
{ name: "print", connections: [null, 1] },
@@ -1897,9 +1897,12 @@ describe("Logo parseArg additional edge cases", () => {
18971897
expect(logo.returns[0].length).toBe(0);
18981898
});
18991899

1900-
test("unknown anyout block in evalArgDict invokes safePluginExecute", () => {
1901-
logo.evalArgDict = { customplugin: jest.fn() };
1902-
logo.safePluginExecute = jest.fn();
1900+
test("evalArgDict plugin result is reflected in parseArg return value", () => {
1901+
logo.evalArgDict = {
1902+
customplugin: (l, _turtle, blk) => {
1903+
l.blockList[blk].value = 555;
1904+
}
1905+
};
19031906
logo.blockList = [
19041907
{
19051908
name: "customplugin",
@@ -1909,16 +1912,8 @@ describe("Logo parseArg additional edge cases", () => {
19091912
isValueBlock: () => false
19101913
}
19111914
];
1912-
logo.parseArg(logo, 0, 0, null, null);
1913-
expect(logo.safePluginExecute).toHaveBeenCalledWith(
1914-
logo.evalArgDict.customplugin,
1915-
logo,
1916-
0,
1917-
0,
1918-
null,
1919-
null,
1920-
tur
1921-
);
1915+
const result = logo.parseArg(logo, 0, 0, null, null);
1916+
expect(result).toBe(555);
19221917
});
19231918

19241919
test("unknown anyout block not in evalArgDict logs console error", () => {
@@ -1935,7 +1930,6 @@ describe("Logo parseArg additional edge cases", () => {
19351930
];
19361931
logo.parseArg(logo, 0, 0, null, null);
19371932
expect(errorSpy).toHaveBeenCalled();
1938-
errorSpy.mockRestore();
19391933
});
19401934
});
19411935

@@ -2087,6 +2081,8 @@ describe("Logo doStopTurtles timer cleanup", () => {
20872081
logo._restoreConnections = jest.fn();
20882082
});
20892083

2084+
afterEach(() => jest.restoreAllMocks());
2085+
20902086
test("clears delayTimeout for turtles that have a pending timer", () => {
20912087
const clearTimeoutSpy = jest.spyOn(global, "clearTimeout").mockImplementation(() => {});
20922088
tur.delayTimeout = 456;
@@ -2095,7 +2091,6 @@ describe("Logo doStopTurtles timer cleanup", () => {
20952091

20962092
expect(clearTimeoutSpy).toHaveBeenCalledWith(456);
20972093
expect(tur.delayTimeout).toBeNull();
2098-
clearTimeoutSpy.mockRestore();
20992094
});
21002095

21012096
test("timerManager.clearAll is invoked during stop", () => {
@@ -2104,7 +2099,6 @@ describe("Logo doStopTurtles timer cleanup", () => {
21042099
logo.doStopTurtles();
21052100

21062101
expect(clearAllSpy).toHaveBeenCalled();
2107-
clearAllSpy.mockRestore();
21082102
});
21092103

21102104
test("logs debug message when timerManager cancels pending timers", () => {
@@ -2114,7 +2108,6 @@ describe("Logo doStopTurtles timer cleanup", () => {
21142108
logo.doStopTurtles();
21152109

21162110
expect(debugSpy).toHaveBeenCalledWith(expect.stringContaining("cancelled"));
2117-
debugSpy.mockRestore();
21182111
});
21192112
});
21202113

@@ -2145,13 +2138,16 @@ describe("Logo runLogoCommands additional coverage", () => {
21452138
});
21462139

21472140
test("executes each evalOnStartList plugin at run startup", () => {
2148-
logo.evalOnStartList = { hook1: jest.fn(), hook2: jest.fn() };
2149-
logo.safePluginExecute = jest.fn();
2141+
const effects = [];
2142+
logo.evalOnStartList = {
2143+
hook1: () => effects.push("hook1"),
2144+
hook2: () => effects.push("hook2")
2145+
};
21502146

21512147
logo.runLogoCommands(null, null);
21522148

2153-
expect(logo.safePluginExecute).toHaveBeenCalledWith(logo.evalOnStartList.hook1, logo);
2154-
expect(logo.safePluginExecute).toHaveBeenCalledWith(logo.evalOnStartList.hook2, logo);
2149+
expect(effects).toContain("hook1");
2150+
expect(effects).toContain("hook2");
21552151
});
21562152

21572153
test("removes existing turtle listeners from stage before running", () => {
@@ -2212,9 +2208,9 @@ describe("Logo runFromBlockNow additional coverage", () => {
22122208
expect(logo.stopTurtle).toBe(true);
22132209
});
22142210

2215-
test("evalFlowDict plugin is called for matching flow block", () => {
2216-
const pluginFn = jest.fn();
2217-
logo.evalFlowDict = { widgetblock: pluginFn };
2211+
test("evalFlowDict plugin executes when block name matches", () => {
2212+
const effects = [];
2213+
logo.evalFlowDict = { widgetblock: () => effects.push("ran") };
22182214
logo.pluginReturnValue = null;
22192215
logo.blockList = [
22202216
{
@@ -2228,7 +2224,7 @@ describe("Logo runFromBlockNow additional coverage", () => {
22282224

22292225
logo.runFromBlockNow(logo, 0, 0, 0, null);
22302226

2231-
expect(pluginFn).toHaveBeenCalled();
2227+
expect(effects).toContain("ran");
22322228
});
22332229

22342230
test("arg block with null value displays 'null block value' message", () => {
@@ -2250,17 +2246,6 @@ describe("Logo runFromBlockNow additional coverage", () => {
22502246
});
22512247
});
22522248

2253-
// ─── processSpeak smoke test ──────────────────────────────────────────────────
2254-
2255-
describe("Logo processSpeak", () => {
2256-
test("does not throw for any text input", () => {
2257-
const logo = new Logo(_buildCovActivity());
2258-
expect(() => logo.processSpeak("hello world")).not.toThrow();
2259-
expect(() => logo.processSpeak("")).not.toThrow();
2260-
expect(() => logo.processSpeak(null)).not.toThrow();
2261-
});
2262-
});
2263-
22642249
// ─── constructor compatibility edge cases ─────────────────────────────────────
22652250

22662251
describe("Logo constructor compatibility", () => {

0 commit comments

Comments
 (0)