@@ -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
22662251describe ( "Logo constructor compatibility" , ( ) => {
0 commit comments