@@ -44,6 +44,10 @@ const astring = {
4444global . ASTUtils = ASTUtils ;
4545global . astring = astring ;
4646
47+ global . JSInterface = {
48+ isGetter : jest . fn ( name => name === "myGetter" )
49+ } ;
50+
4751describe ( "JSGenerate Class" , ( ) => {
4852 beforeEach ( ( ) => {
4953 jest . clearAllMocks ( ) ;
@@ -169,4 +173,176 @@ describe("JSGenerate Class", () => {
169173 ) ;
170174 expect ( console . log ) . toHaveBeenCalledWith ( "generated code" ) ;
171175 } ) ;
176+ test ( "should generate stack trees with various block types and arguments" , ( ) => {
177+ globalActivity . blocks . stackList = [ 1 , 20 ] ;
178+ const booleanGrandParent = { constructor : { name : "BooleanBlock" } } ;
179+ const booleanParent = Object . create ( booleanGrandParent ) ;
180+ const booleanProtoblock = Object . create ( booleanParent ) ;
181+ booleanProtoblock . style = "value" ;
182+ const standardGrandParent = { constructor : { name : "StandardBlock" } } ;
183+ const standardParent = Object . create ( standardGrandParent ) ;
184+ const standardProtoblock = Object . create ( standardParent ) ;
185+ standardProtoblock . style = "value" ;
186+
187+ globalActivity . blocks . blockList = {
188+ 1 : {
189+ name : "start" ,
190+ trash : false ,
191+ connections : [ null , 2 , null ] ,
192+ protoblock : { style : "hat" }
193+ } ,
194+ 2 : {
195+ name : "storein2" ,
196+ privateData : "myVar" ,
197+ connections : [ 1 , 4 , 3 ] ,
198+ protoblock : { style : "command" , args : 1 }
199+ } ,
200+ 4 : {
201+ name : "hspace" ,
202+ connections : [ 2 , 5 ] ,
203+ protoblock : { style : "spacer" }
204+ } ,
205+ 5 : {
206+ name : "value" ,
207+ value : 42 ,
208+ connections : [ 4 ] ,
209+ protoblock : standardProtoblock
210+ } ,
211+ 3 : {
212+ name : "if" ,
213+ connections : [ 2 , 6 , 7 , 10 , 13 ] ,
214+ protoblock : { style : "doubleclamp" , args : 3 }
215+ } ,
216+ 6 : {
217+ name : "boolean" ,
218+ value : "true" ,
219+ connections : [ 3 ] ,
220+ protoblock : booleanProtoblock
221+ } ,
222+ 7 : {
223+ name : "nameddo" ,
224+ privateData : "myProc" ,
225+ connections : [ 3 , 8 ] ,
226+ protoblock : { style : "command" }
227+ } ,
228+ 8 : { name : "hidden" , connections : [ 7 , 9 ] , protoblock : { style : "command" } } ,
229+ 9 : { name : "command" , connections : [ 8 , null ] , protoblock : { style : "command" } } ,
230+
231+ 10 : {
232+ name : "repeat" ,
233+ connections : [ 3 , 11 , 12 , null ] ,
234+ protoblock : { style : "clamp" , args : 2 }
235+ } ,
236+ 11 : {
237+ name : "namedbox" ,
238+ privateData : "box1" ,
239+ connections : [ 10 ] ,
240+ protoblock : standardProtoblock
241+ } ,
242+ 12 : { name : "command" , connections : [ 10 , null ] , protoblock : { style : "command" } } ,
243+ 13 : { name : "command" , connections : [ 3 , null ] , protoblock : { style : "command" } } ,
244+ 20 : {
245+ name : "action" ,
246+ trash : false ,
247+ connections : [ null , 21 , 22 , null ] ,
248+ protoblock : { style : "hat" }
249+ } ,
250+ 21 : {
251+ name : "value" ,
252+ value : "myAction" ,
253+ connections : [ 20 ] ,
254+ protoblock : standardProtoblock
255+ } ,
256+ 22 : {
257+ name : "myGetter" ,
258+ connections : [ 20 , null ] ,
259+ protoblock : { style : "value" }
260+ }
261+ } ;
262+
263+ JSGenerate . generateStacksTree ( ) ;
264+
265+ expect ( JSGenerate . startTrees . length ) . toBe ( 1 ) ;
266+ expect ( JSGenerate . actionTrees . length ) . toBe ( 1 ) ;
267+ expect ( JSGenerate . actionNames ) . toContain ( "myAction" ) ;
268+
269+ const tree = JSGenerate . startTrees [ 0 ] ;
270+ expect ( tree [ 0 ] [ 0 ] ) . toBe ( "storein2_myVar" ) ;
271+ expect ( tree [ 0 ] [ 1 ] [ 0 ] ) . toBe ( 42 ) ;
272+ expect ( tree [ 1 ] [ 0 ] ) . toBe ( "if" ) ;
273+ expect ( tree [ 1 ] [ 1 ] [ 0 ] ) . toBe ( "bool_true" ) ;
274+ expect ( tree [ 1 ] [ 2 ] [ 0 ] [ 0 ] ) . toBe ( "nameddo_myProc" ) ;
275+ expect ( tree [ 1 ] [ 3 ] [ 0 ] [ 1 ] [ 0 ] ) . toBe ( "box_box1" ) ;
276+ } ) ;
277+
278+ test ( "should warn when clamp block flows left" , ( ) => {
279+ globalActivity . blocks . stackList = [ 1 ] ;
280+ globalActivity . blocks . blockList = {
281+ 1 : {
282+ name : "start" ,
283+ trash : false ,
284+ connections : [ null , 2 , null ] ,
285+ protoblock : { style : "hat" }
286+ } ,
287+ 2 : {
288+ name : "command" ,
289+ connections : [ 1 , 3 , null ] ,
290+ protoblock : { style : "command" , args : 1 }
291+ } ,
292+ 3 : {
293+ name : "badClamp" ,
294+ connections : [ 2 ] ,
295+ protoblock : {
296+ style : "clamp" ,
297+ _style : { flows : { left : true } }
298+ }
299+ }
300+ } ;
301+
302+ const warnSpy = jest . spyOn ( console , "warn" ) . mockImplementation ( ) ;
303+ JSGenerate . generateStacksTree ( ) ;
304+ expect ( warnSpy ) . toHaveBeenCalledWith ( 'CANNOT PROCESS "badClamp" BLOCK' ) ;
305+ warnSpy . mockRestore ( ) ;
306+ } ) ;
307+ test ( "should print complex stack trees with nested args and flows" , ( ) => {
308+ JSGenerate . startTrees = [
309+ [
310+ [ "block1" , [ "arg1" , "subArg" ] , null ] ,
311+ [ "block2" , null , [ [ "flow1Block" , null , null ] ] , [ [ "flow2Block" , null , null ] ] ]
312+ ]
313+ ] ;
314+ JSGenerate . actionTrees = [ [ [ "actionBlock" , null , null ] ] ] ;
315+
316+ JSGenerate . printStacksTree ( ) ;
317+ expect ( console . log ) . toHaveBeenCalledWith (
318+ expect . stringContaining ( "(arg1, subArg)" ) ,
319+ "background: mediumslateblue" ,
320+ "background; none" ,
321+ "color: dodgerblue"
322+ ) ;
323+ expect ( console . log ) . toHaveBeenCalledWith (
324+ expect . stringContaining ( "** NEXTFLOW **" ) ,
325+ "color: green"
326+ ) ;
327+ expect ( console . log ) . toHaveBeenCalledWith (
328+ expect . stringContaining ( "ACTION" ) ,
329+ "background: green; color: white; font-weight: bold"
330+ ) ;
331+ } ) ;
332+ test ( "should handle astring generation errors" , ( ) => {
333+ JSGenerate . AST = { type : "Program" , body : [ ] } ;
334+ astring . generate
335+ . mockImplementationOnce ( ( ) => {
336+ throw new Error ( "Code Gen Error" ) ;
337+ } )
338+ . mockImplementationOnce ( ( ) => "fallback code" ) ;
339+
340+ JSGenerate . generateCode ( ) ;
341+
342+ expect ( JSGenerate . generateFailed ) . toBe ( true ) ;
343+ expect ( console . error ) . toHaveBeenCalledWith (
344+ "CANNOT GENERATE CODE\nError: INVALID ABSTRACT SYNTAX TREE"
345+ ) ;
346+ expect ( JSGenerate . code ) . toBe ( "fallback code" ) ;
347+ } ) ;
172348} ) ;
0 commit comments