diff --git a/src/serialization/sb2.js b/src/serialization/sb2.js index 04df00939..d45fbffe1 100644 --- a/src/serialization/sb2.js +++ b/src/serialization/sb2.js @@ -1028,8 +1028,13 @@ const parseBlock = function (sb2block, addBroadcastMsg, getVariableId, extension value: providedArg }; - if (expectedArg.fieldName === 'CURRENTMENU' && providedArg === 'day of week') { - activeBlock.fields[expectedArg.fieldName].value = 'DAYOFWEEK'; + if (expectedArg.fieldName === 'CURRENTMENU') { + // In 3.0, the field value of the `sensing_current` block + // is in all caps. + activeBlock.fields[expectedArg.fieldName].value = providedArg.toUpperCase(); + if (providedArg === 'day of week') { + activeBlock.fields[expectedArg.fieldName].value = 'DAYOFWEEK'; + } } if (expectedArg.fieldName === 'VARIABLE') { diff --git a/src/util/get-monitor-id.js b/src/util/get-monitor-id.js index ada1e7c70..8582db231 100644 --- a/src/util/get-monitor-id.js +++ b/src/util/get-monitor-id.js @@ -12,7 +12,20 @@ const getMonitorIdForBlockWithArgs = function (id, fields) { let fieldString = ''; for (const fieldKey in fields) { - fieldString += `_${fields[fieldKey].value}`; + let fieldValue = fields[fieldKey].value; + if (fieldKey === 'CURRENTMENU') { + // The 'sensing_current' block has field values in all caps. + // However, when importing from scratch 2.0, these + // could have gotten imported as lower case field values. + // Normalize the field value here so that we don't ever + // end up with a different monitor ID representing the same + // block configuration + // Note: we are not doing this for every block field that comes into + // this function so as not to make the faulty assumption that block + // field values coming in would be unique after being made lower case + fieldValue = fieldValue.toLowerCase(); + } + fieldString += `_${fieldValue}`; } return `${id}${fieldString}`; }; diff --git a/test/fixtures/monitors.sb2 b/test/fixtures/monitors.sb2 index d4117a83c..2b9ede376 100644 Binary files a/test/fixtures/monitors.sb2 and b/test/fixtures/monitors.sb2 differ diff --git a/test/integration/monitors.js b/test/integration/monitors.js index bf273a489..dc9a9e9e4 100644 --- a/test/integration/monitors.js +++ b/test/integration/monitors.js @@ -17,10 +17,10 @@ test('importing sb2 project with monitors', t => { // All monitors should create threads that finish during the step and // are revoved from runtime.threads. t.equal(threads.length, 0); - t.equal(vm.runtime._lastStepDoneThreads.length, 5); + t.equal(vm.runtime._lastStepDoneThreads.length, 8); // There should be one additional hidden monitor that is in the monitorState but // does not start a thread. - t.equal(vm.runtime._monitorState.size, 6); + t.equal(vm.runtime._monitorState.size, 9); const stage = vm.runtime.targets[0]; const target = vm.runtime.targets[1]; @@ -56,8 +56,8 @@ test('importing sb2 project with monitors', t => { t.equal(monitorRecord.opcode, 'data_listcontents'); t.equal(monitorRecord.mode, 'list'); t.equal(monitorRecord.visible, true); - t.equal(monitorRecord.width, 102); // Make sure these are imported from lists. - t.equal(monitorRecord.height, 202); + t.equal(monitorRecord.width, 104); // Make sure these are imported from lists. + t.equal(monitorRecord.height, 204); // Backdrop name monitor is visible, not sprite specific // should get imported with id that references the name parameter @@ -77,6 +77,45 @@ test('importing sb2 project with monitors', t => { t.equal(monitorRecord.spriteName, 'Sprite1'); t.equal(monitorRecord.targetId, target.id); + + let monitorId; + let monitorBlock; + + // The monitor IDs for the sensing_current block should be unique + // to the parameter that is selected on the block being monitored. + // The paramater portion of the id should be lowercase even + // though the field value on the block is uppercase. + + monitorId = 'current_date'; + monitorRecord = vm.runtime._monitorState.get(monitorId); + t.equal(monitorRecord.opcode, 'sensing_current'); + monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId); + t.equal(monitorBlock.fields.CURRENTMENU.value, 'DATE'); + t.equal(monitorRecord.mode, 'default'); + t.equal(monitorRecord.visible, true); + t.equal(monitorRecord.spriteName, null); + t.equal(monitorRecord.targetId, null); + + monitorId = 'current_minute'; + monitorRecord = vm.runtime._monitorState.get(monitorId); + t.equal(monitorRecord.opcode, 'sensing_current'); + monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId); + t.equal(monitorBlock.fields.CURRENTMENU.value, 'MINUTE'); + t.equal(monitorRecord.mode, 'default'); + t.equal(monitorRecord.visible, true); + t.equal(monitorRecord.spriteName, null); + t.equal(monitorRecord.targetId, null); + + monitorId = 'current_dayofweek'; + monitorRecord = vm.runtime._monitorState.get(monitorId); + t.equal(monitorRecord.opcode, 'sensing_current'); + monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId); + t.equal(monitorBlock.fields.CURRENTMENU.value, 'DAYOFWEEK'); + t.equal(monitorRecord.mode, 'default'); + t.equal(monitorRecord.visible, true); + t.equal(monitorRecord.spriteName, null); + t.equal(monitorRecord.targetId, null); + t.end(); process.nextTick(process.exit); });