11import Blocks from 'scratch-vm/src/engine/blocks' ;
22import Variable from 'scratch-vm/src/engine/variable' ;
33
4+ // for debug
5+ const toJson = function ( o ) {
6+ return JSON . stringify ( o , undefined , 2 ) ; // eslint-disable-line no-undefined
7+ } ;
8+
49const expectToEqualFields = function ( context , actualFields , expectedFieldsInfo ) {
510 expect ( Object . keys ( actualFields ) ) . toHaveLength ( expectedFieldsInfo ? expectedFieldsInfo . length : 0 ) ;
611 if ( expectedFieldsInfo ) {
@@ -62,9 +67,8 @@ const expectToEqualBranches = function (context, block, expectedBranchesInfo) {
6267 return ;
6368 }
6469 expect ( branch ) . not . toEqual ( null ) ;
65- /* eslint-disable no-use-before-define */
70+ // eslint-disable-next-line no-use-before-define
6671 expectToEqualBlock ( context , block . id , blocks . getBlock ( branch ) , expectedBranch ) ;
67- /* eslint-enable no-use-before-define */
6872 } ) ;
6973 }
7074} ;
@@ -78,15 +82,89 @@ const expectToEqualInputs = function (context, parent, actualInputs, expectedInp
7882 const input = actualInputs [ expectedInput . name ] ;
7983
8084 expect ( input . name ) . toEqual ( expectedInput . name ) ;
81- expect ( input . shadow ) . toEqual ( expectedInput . block . shadow ? input . block : null ) ;
85+ if ( expectedInput . shadow ) {
86+ // eslint-disable-next-line no-use-before-define
87+ expectToEqualBlock ( context , parent , blocks . getBlock ( input . shadow ) , expectedInput . shadow ) ;
88+ } else {
89+ expect ( input . shadow ) . toEqual ( expectedInput . block . shadow ? input . block : null ) ;
90+ }
8291
83- /* eslint-disable no-use-before-define */
92+ // eslint-disable-next-line no-use-before-define
8493 expectToEqualBlock ( context , parent , blocks . getBlock ( input . block ) , expectedInput . block ) ;
85- /* eslint-enable no-use-before-define */
8694 } ) ;
8795 }
8896} ;
8997
98+ const expectToEqualMutation = function ( context , block , actualMutation , expectedMutationInfo ) {
99+ if ( ! actualMutation && ! expectedMutationInfo ) {
100+ return ;
101+ }
102+
103+ const blocks = context . blocks ;
104+ Object . keys ( expectedMutationInfo ) . forEach ( key => {
105+ switch ( key ) {
106+ case 'arguments' : {
107+ const expectedArguments = expectedMutationInfo [ key ] ;
108+
109+ const argumentNames = expectedArguments . map ( a => a . name ) ;
110+ expect ( actualMutation ) . toHaveProperty ( 'argumentnames' , JSON . stringify ( argumentNames ) ) ;
111+
112+ const actualArgInputIds = JSON . parse ( actualMutation . argumentids ) ;
113+ expect ( actualArgInputIds ) . toHaveLength ( expectedArguments . length ) ;
114+
115+ const expectedArgDefaults = [ ] ;
116+ actualArgInputIds . forEach ( ( actualArgInputId , i ) => {
117+ const actualArgInput = block . inputs [ actualArgInputId ] ;
118+ const expectedArgBlock = {
119+ opcode : `argument_reporter_${ expectedArguments [ i ] . type } ` ,
120+ fields : [
121+ {
122+ name : 'VALUE' ,
123+ value : expectedArguments [ i ] . name
124+ }
125+ ] ,
126+ shadow : true
127+ } ;
128+ if ( expectedArguments [ i ] . type === 'string_number' ) {
129+ expectedArgDefaults . push ( '' ) ;
130+ } else {
131+ expectedArgDefaults . push ( 'false' ) ;
132+ }
133+ // eslint-disable-next-line no-use-before-define
134+ expectToEqualBlock ( context , block . id , blocks . getBlock ( actualArgInput . block ) , expectedArgBlock ) ;
135+ } ) ;
136+
137+ expect ( actualMutation ) . toHaveProperty ( 'argumentdefaults' , JSON . stringify ( expectedArgDefaults ) ) ;
138+ break ;
139+ }
140+ case 'argument_blocks' : {
141+ const actualArgInputIds = JSON . parse ( actualMutation . argumentids ) ;
142+ actualArgInputIds . forEach ( ( actualArgInputId , i ) => {
143+ const actualArgInput = block . inputs [ actualArgInputId ] ;
144+ const expectedArgBlock = expectedMutationInfo [ key ] [ i ] ;
145+
146+ expect ( actualArgInput ) . toHaveProperty ( 'name' , actualArgInputId ) ;
147+ if ( expectedArgBlock === false ) {
148+ expect ( actualArgInput . block ) . toEqual ( null ) ;
149+ expect ( actualArgInput . shadow ) . toEqual ( null ) ;
150+ } else {
151+ const actualArgBlock = blocks . getBlock ( actualArgInput . block ) ;
152+ // eslint-disable-next-line no-use-before-define
153+ expectToEqualBlock ( context , block . id , actualArgBlock , expectedArgBlock ) ;
154+ }
155+ } ) ;
156+ expect ( actualArgInputIds ) . toHaveLength ( expectedMutationInfo [ key ] . length ) ;
157+ break ;
158+ }
159+ default :
160+ expect ( actualMutation ) . toHaveProperty ( key , expectedMutationInfo [ key ] ) ;
161+ }
162+ } ) ;
163+ expect ( actualMutation ) . toHaveProperty ( 'tagName' , 'mutation' ) ;
164+ expect ( actualMutation ) . toHaveProperty ( 'warp' , 'false' ) ;
165+ expect ( actualMutation . children ) . toHaveLength ( 0 ) ;
166+ } ;
167+
90168const expectToEqualBlock = function ( context , parent , actualBlock , expectedBlockInfo ) {
91169 const blocks = context . blocks ;
92170 const block = actualBlock ;
@@ -101,7 +179,11 @@ const expectToEqualBlock = function (context, parent, actualBlock, expectedBlock
101179
102180 expectToEqualFields ( context , blocks . getFields ( block ) , expected . fields ) ;
103181
104- expectToEqualInputs ( context , block . id , blocks . getInputs ( block ) , expected . inputs ) ;
182+ if ( ! expected . hasOwnProperty ( 'mutation' ) ) {
183+ expectToEqualInputs ( context , block . id , blocks . getInputs ( block ) , expected . inputs ) ;
184+ }
185+
186+ expectToEqualMutation ( context , block , blocks . getMutation ( block ) , expected . mutation ) ;
105187
106188 expectToEqualBranches ( context , block , expected . branches ) ;
107189
@@ -212,7 +294,7 @@ const fieldsToExpected = function (context, fields) {
212294 } ) ;
213295} ;
214296
215- const inputsToExpected = function ( context , blocks , inputs ) {
297+ const inputsToExpected = function ( context , inputs ) {
216298 if ( ! inputs ) {
217299 return null ;
218300 }
@@ -221,25 +303,22 @@ const inputsToExpected = function (context, blocks, inputs) {
221303 const input = inputs [ name ] ;
222304 const expected = {
223305 name : input . name ,
224- /* eslint-disable no-use-before-define */
225- block : blockToExpected ( context , blocks , input . block )
226- /* eslint-enable no-use-before-define */
306+ block : blockToExpected ( context , input . block ) // eslint-disable-line no-use-before-define
227307 } ;
228- if ( input . shadow ) {
229- expected . shadow = true ;
308+ if ( input . shadow !== null && input . shadow !== input . block ) {
309+ expected . shadow = blockToExpected ( context , input . shadow ) ; // eslint-disable-line no-use-before-define
230310 }
231311 return expected ;
232312 } ) ;
233313} ;
234314
235- const branchesToExpected = function ( context , blocks , block ) {
315+ const branchesToExpected = function ( context , block ) {
316+ const blocks = context . blocks ;
236317 const branches = [ ] ;
237318 for ( let i = 1 ; i <= 2 ; i ++ ) {
238319 const branch = blocks . getBranch ( block . id , i ) ;
239320 if ( branch !== null ) {
240- /* eslint-disable no-use-before-define */
241- branches [ i - 1 ] = blockToExpected ( context , blocks , branch ) ;
242- /* eslint-enable no-use-before-define */
321+ branches [ i - 1 ] = blockToExpected ( context , branch ) ; // eslint-disable-line no-use-before-define
243322 }
244323 }
245324 if ( branches . length === 0 ) {
@@ -249,11 +328,12 @@ const branchesToExpected = function (context, blocks, block) {
249328 return branches ;
250329} ;
251330
252- const blockToExpected = function ( context , blocks , blockId ) {
331+ const blockToExpected = function ( context , blockId ) {
253332 if ( ! blockId ) {
254333 return null ;
255334 }
256335
336+ const blocks = context . blocks ;
257337 const block = blocks . getBlock ( blockId ) ;
258338 const expected = {
259339 opcode : blocks . getOpcode ( block )
@@ -265,15 +345,15 @@ const blockToExpected = function (context, blocks, blockId) {
265345 if ( fields ) {
266346 expected . fields = fields ;
267347 }
268- const inputs = inputsToExpected ( context , blocks , blocks . getInputs ( block ) ) ;
348+ const inputs = inputsToExpected ( context , blocks . getInputs ( block ) ) ;
269349 if ( inputs ) {
270350 expected . inputs = inputs ;
271351 }
272- const branches = branchesToExpected ( context , blocks , block ) ;
352+ const branches = branchesToExpected ( context , block ) ;
273353 if ( branches ) {
274354 expected . branches = branches ;
275355 }
276- const next = blockToExpected ( context , blocks , blocks . getNextBlock ( block ) ) ;
356+ const next = blockToExpected ( context , blocks . getNextBlock ( block . id ) ) ;
277357 if ( next ) {
278358 expected . next = next ;
279359 }
@@ -298,7 +378,7 @@ const rubyToExpected = function (converter, target, code) {
298378 } ;
299379
300380 const scripts = blocks . getScripts ( ) ;
301- return scripts . map ( scriptId => blockToExpected ( context , blocks , scriptId ) ) ;
381+ return scripts . map ( scriptId => blockToExpected ( context , scriptId ) ) ;
302382} ;
303383
304384const expectedInfo = {
@@ -307,7 +387,7 @@ const expectedInfo = {
307387 fields : [
308388 {
309389 name : 'TEXT' ,
310- value : text
390+ value : text . toString ( )
311391 }
312392 ] ,
313393 shadow : true
@@ -317,14 +397,15 @@ const expectedInfo = {
317397 fields : [
318398 {
319399 name : 'NUM' ,
320- value : num
400+ value : num . toString ( )
321401 }
322402 ] ,
323403 shadow : true
324404 } )
325405} ;
326406
327407export {
408+ toJson ,
328409 expectToEqualBlocks ,
329410 convertAndExpectToEqualBlocks ,
330411 expectToEqualRubyStatement ,
0 commit comments