@@ -117,6 +117,50 @@ describe('clearWorkspaceAndLoadFromXml — isLocal and isCloud preservation', ()
117117 expect ( global_ . isCloud ) . toBe ( false )
118118 } )
119119
120+ it ( 'wraps domToWorkspace errors with top-level element context' , ( ) => {
121+ // A top-level <shadow> will cause Blockly to throw.
122+ const xml = parseXml ( `
123+ <xml>
124+ <shadow type="looks_costume" id="badShadow" x="0" y="0"></shadow>
125+ </xml>
126+ ` )
127+
128+ let caught : unknown
129+ try {
130+ clearWorkspaceAndLoadFromXml ( xml , workspace )
131+ } catch ( e ) {
132+ caught = e
133+ }
134+ expect ( caught ) . toBeDefined ( )
135+ expect ( ( caught as Error ) . message ) . toMatch ( / F a i l e d t o l o a d w o r k s p a c e X M L / )
136+ expect ( ( caught as Error ) . message ) . toMatch ( / b a d S h a d o w / )
137+ } )
138+
139+ it ( 'closes the event group and re-enables resizes after a load failure' , ( ) => {
140+ const xml = parseXml ( `
141+ <xml>
142+ <shadow type="looks_costume" id="badShadow" x="0" y="0"></shadow>
143+ </xml>
144+ ` )
145+
146+ try {
147+ clearWorkspaceAndLoadFromXml ( xml , workspace )
148+ } catch ( _e ) {
149+ // expected
150+ }
151+
152+ // The event group opened by clearWorkspaceAndLoadFromXml should be closed.
153+ // Firing an event outside of a group verifies that setGroup(false) was called.
154+ // If the group were still open, this event would be part of it.
155+ const event = new ( Blockly . Events . get ( Blockly . Events . VAR_CREATE ) ) (
156+ workspace . getVariableMap ( ) . createVariable ( 'testVar' , '' , 'testId' ) ,
157+ )
158+ expect ( event . group ) . toBeFalsy ( )
159+
160+ // Resizes should be re-enabled after a load failure.
161+ expect ( ( workspace as unknown as { resizesEnabled : boolean } ) . resizesEnabled ) . toBe ( true )
162+ } )
163+
120164 it ( 'clears the existing workspace before loading' , ( ) => {
121165 // Pre-load a variable.
122166 workspace . getVariableMap ( ) . createVariable ( 'old' , '' , 'oldId' )
0 commit comments