From 4d7ffbe088b3102a489e2fbebe7b8ef0b7dc2342 Mon Sep 17 00:00:00 2001 From: mwechsler Date: Thu, 16 Sep 2021 12:54:22 +0200 Subject: [PATCH] STCC-273 Convert Timer/Reset Timer [MW] --- src/scratchtocatrobat/converter/converter.py | 7 +- .../converter/test_converter.py | 10 +- src/scratchtocatrobat/scratch/scratch.py | 83 +----- src/scratchtocatrobat/scratch/test_scratch.py | 281 ------------------ 4 files changed, 9 insertions(+), 372 deletions(-) diff --git a/src/scratchtocatrobat/converter/converter.py b/src/scratchtocatrobat/converter/converter.py index d9ccff37..33a41154 100644 --- a/src/scratchtocatrobat/converter/converter.py +++ b/src/scratchtocatrobat/converter/converter.py @@ -460,6 +460,9 @@ class _ScratchToCatrobat(object): "touching:": None, "dragMode": None, + "timer": catrobat.formula_element_for(catformula.Sensors.TIMER), + "timerReset": catbricks.ResetTimerBrick, + # clone "createCloneOf": catbricks.CloneBrick, "deleteClone": catbricks.DeleteThisCloneBrick, @@ -561,8 +564,8 @@ def _create_catrobat_sprite_stub(name=None): formula_right_child = None if sensor_type == 'timer': - formula_left_child = catformula.FormulaElement(catElementType.USER_VARIABLE, None, None) - formula_left_child.value = scratch.S2CC_TIMER_VARIABLE_NAME + formula_left_child = catformula.FormulaElement(catElementType.SENSOR, None, None) + formula_left_child.value = str(catformula.Sensors.TIMER) elif sensor_type == 'loudness': formula_left_child = catformula.FormulaElement(catElementType.SENSOR, None, None) diff --git a/src/scratchtocatrobat/converter/test_converter.py b/src/scratchtocatrobat/converter/test_converter.py index 56afa664..4621165d 100644 --- a/src/scratchtocatrobat/converter/test_converter.py +++ b/src/scratchtocatrobat/converter/test_converter.py @@ -307,21 +307,13 @@ def test_can_convert_when_timer_greater_than_script_with_formula(self): } raw_project = scratch.RawProject(raw_json) - workaround_info = raw_project.objects[1].preprocess_object([raw_project.objects[0].name, raw_project.objects[1].name]) - assert workaround_info[scratch.ADD_TIMER_SCRIPT_KEY] == True - timer_background_workaround = [['whenGreenFlag'], ['doForever', \ - [['changeVar:by:', scratch.S2CC_TIMER_VARIABLE_NAME, scratch.UPDATE_HELPER_VARIABLE_TIMEOUT], - ['wait:elapsed:from:', scratch.UPDATE_HELPER_VARIABLE_TIMEOUT]]]] - assert raw_project.objects[0].scripts[0].raw_script == timer_background_workaround - catr_script = self.block_converter._catrobat_script_from(raw_project.objects[1].scripts[0], DUMMY_CATR_SPRITE, self.test_project) assert isinstance(catr_script, catbase.WhenConditionScript) formula = catr_script.formulaMap[catbricks.Brick.BrickField.IF_CONDITION] #@UndefinedVariable assert isinstance(formula, catformula.Formula) - assert formula.formulaTree.value == str(catformula.Operators.GREATER_THAN) - assert formula.formulaTree.leftChild.value == scratch.S2CC_TIMER_VARIABLE_NAME + assert formula.formulaTree.leftChild.value == str(catformula.Sensors.TIMER) assert formula.formulaTree.rightChild.value == str(catformula.Operators.PLUS) assert formula.formulaTree.rightChild.leftChild.value == "2" assert formula.formulaTree.rightChild.rightChild.value == "1" diff --git a/src/scratchtocatrobat/scratch/scratch.py b/src/scratchtocatrobat/scratch/scratch.py index 086c79a2..9b79c118 100644 --- a/src/scratchtocatrobat/scratch/scratch.py +++ b/src/scratchtocatrobat/scratch/scratch.py @@ -70,8 +70,6 @@ class JsonKeys(object): STAGE_WIDTH_IN_PIXELS = 480 STAGE_HEIGHT_IN_PIXELS = 360 S2CC_KEY_VARIABLE_NAME = "S2CC:key_" -S2CC_TIMER_VARIABLE_NAME = "S2CC:timer" -S2CC_TIMER_RESET_BROADCAST_MESSAGE = "S2CC:timer:reset" S2CC_POSITION_X_VARIABLE_NAME_PREFIX = "S2CC:pos_x_" S2CC_POSITION_Y_VARIABLE_NAME_PREFIX = "S2CC:pos_y_" S2CC_SENSOR_PREFIX = "S2CC:sensor_" @@ -85,8 +83,6 @@ class JsonKeys(object): S2CC_PEN_SIZE_VARIABLE_NAME = "S2CC:pen_size" S2CC_PEN_SIZE_MULTIPLIER = 3.65 S2CC_PEN_SIZE_DEFAULT_VALUE = (1 * S2CC_PEN_SIZE_MULTIPLIER) -ADD_TIMER_SCRIPT_KEY = "add_timer_script_key" -ADD_TIMER_RESET_SCRIPT_KEY = "add_timer_reset_script_key" ADD_POSITION_SCRIPT_TO_OBJECTS_KEY = "add_position_script_to_objects_key" ADD_UPDATE_ATTRIBUTE_SCRIPT_TO_OBJECTS_KEY = "add_update_attribute_script_to_objects_key" ADD_KEY_PRESSED_SCRIPT_KEY = "add_key_pressed_script_key" @@ -179,8 +175,6 @@ def __init__(self, object_data): def preprocess_object(self, all_sprite_names): workaround_info = { - ADD_TIMER_SCRIPT_KEY: False, - ADD_TIMER_RESET_SCRIPT_KEY: False, ADD_KEY_PRESSED_SCRIPT_KEY: set(), ADD_POSITION_SCRIPT_TO_OBJECTS_KEY: set(), ADD_UPDATE_ATTRIBUTE_SCRIPT_TO_OBJECTS_KEY: {}, @@ -249,44 +243,6 @@ def preprocess_object(self, all_sprite_names): blocks[1] = ['randomFrom:to:', 1.0, float(len(self._dict_object[JsonKeys.COSTUMES]))] script.script_element = script.script_element.from_raw_block(script.blocks) - ############################################################################################ - # timer and timerReset workaround - ############################################################################################ - def has_timer_block(block_list): - for block in block_list: - if isinstance(block, list) and (block[0] == 'timer' or has_timer_block(block)): - return True - return False - - def has_timer_reset_block(block_list): - for block in block_list: - if isinstance(block, list) and (block[0] == 'timerReset' or has_timer_reset_block(block)): - return True - return False - - def replace_timer_blocks(block_list): - new_block_list = [] - for block in block_list: - if isinstance(block, list): - if block[0] == 'timer': - new_block_list += [["readVariable", S2CC_TIMER_VARIABLE_NAME]] - elif block[0] == 'timerReset': - new_block_list += [["doBroadcastAndWait", S2CC_TIMER_RESET_BROADCAST_MESSAGE]] - else: - new_block_list += [replace_timer_blocks(block)] - else: - new_block_list += [block] - return new_block_list - - for script in self.scripts: - if has_timer_reset_block(script.blocks): workaround_info[ADD_TIMER_RESET_SCRIPT_KEY] = True - if has_timer_block(script.blocks) or 'timer' in script.arguments: workaround_info[ADD_TIMER_SCRIPT_KEY] = True - - script.blocks = replace_timer_blocks(script.blocks) - - # rebuild ScriptElement tree - script.script_element = ScriptElement.from_raw_block(script.blocks) - ############################################################################################ # key pressed workaround ############################################################################################ @@ -607,8 +563,6 @@ def __init__(self, dict_, data_origin=""): self.resource_names = [self._resource_name_from(raw_resource) for raw_resource in self._raw_resources()] self.unique_resource_names = list(set(self.resource_names)) - is_add_timer_script = False - is_add_timer_reset_script = False sprite_name_sprite_mapping = dict(map(lambda obj: (obj.get_objName(), obj), self.objects)) all_sprite_names = sprite_name_sprite_mapping.keys() position_script_to_be_added = set() @@ -619,8 +573,6 @@ def __init__(self, dict_, data_origin=""): workaround_applied = set() for scratch_object in self.objects: workaround_info = scratch_object.preprocess_object(all_sprite_names) - if workaround_info[ADD_TIMER_SCRIPT_KEY]: is_add_timer_script = True - if workaround_info[ADD_TIMER_RESET_SCRIPT_KEY]: is_add_timer_reset_script = True if workaround_info[ADD_PEN_DEFAULT_BEHAVIOR]: self._add_pen_default_behavior_to_object(scratch_object) if workaround_info[ADD_PEN_COLOR_VARIABLES]: @@ -640,8 +592,6 @@ def __init__(self, dict_, data_origin=""): for sprite_name, sensor_names_set in workaround_info[ADD_UPDATE_ATTRIBUTE_SCRIPT_TO_OBJECTS_KEY].iteritems(): if sprite_name not in update_attribute_script_to_be_added: update_attribute_script_to_be_added[sprite_name] = set() update_attribute_script_to_be_added[sprite_name] |= sensor_names_set - if is_add_timer_script or is_add_timer_reset_script: self._add_timer_script_to_stage_object() - if is_add_timer_reset_script: self._add_timer_reset_script_to_stage_object() for destination_sprite_name in position_script_to_be_added: if destination_sprite_name == "_mouse_": continue @@ -651,7 +601,7 @@ def __init__(self, dict_, data_origin=""): for sprite_name, sensors_info in sprite_sensors_map.iteritems(): sprite_object = sprite_name_sprite_mapping[sprite_name] assert sprite_object is not None - self._add_sensor_variables_and_update_script_to_object(sprite_object, sensors_info, is_add_timer_script) + self._add_sensor_variables_and_update_script_to_object(sprite_object, sensors_info) for sprite_name, sensor_names in update_attribute_script_to_be_added.iteritems(): sprite_object = sprite_name_sprite_mapping[sprite_name] @@ -701,30 +651,7 @@ def _add_update_attribute_script_to_object(self, sprite_object, sensor_names): forever_loop_body_blocks += [["wait:elapsed:from:", UPDATE_HELPER_VARIABLE_TIMEOUT]] sprite_object.scripts += [Script([0, 0, [[SCRIPT_GREEN_FLAG], ["doForever", forever_loop_body_blocks]]])] - def _add_timer_script_to_stage_object(self): - assert len(self.objects) > 0 - # add timer variable to stage object (in Scratch this acts as a global variable) - self.objects[0]._dict_object["variables"].append({ - "name": S2CC_TIMER_VARIABLE_NAME, - "value": 0, - "isPersistent": False - }) - # timer counter script - script_blocks = [ - ["doForever", [ - ["changeVar:by:", S2CC_TIMER_VARIABLE_NAME, UPDATE_HELPER_VARIABLE_TIMEOUT], - ["wait:elapsed:from:", UPDATE_HELPER_VARIABLE_TIMEOUT] - ]] - ] - self.objects[0].scripts += [Script([0, 0, [[SCRIPT_GREEN_FLAG]] + script_blocks])] - - def _add_timer_reset_script_to_stage_object(self): - assert len(self.objects) > 0 - # timer reset script - script_blocks = [["setVar:to:", S2CC_TIMER_VARIABLE_NAME, 0]] - self.objects[0].scripts += [Script([0, 0, [[SCRIPT_RECEIVE, S2CC_TIMER_RESET_BROADCAST_MESSAGE]] + script_blocks])] - - def _add_sensor_variables_and_update_script_to_object(self, sprite_object, sensors_info, is_add_timer_script): + def _add_sensor_variables_and_update_script_to_object(self, sprite_object, sensors_info): from scratchtocatrobat.converter import converter forever_loop_body_blocks = [] sprite_name = sprite_object.get_objName() @@ -735,11 +662,7 @@ def _add_sensor_variables_and_update_script_to_object(self, sprite_object, senso continue stage_object = self.objects[0] - if command == "timer": - variable_name = S2CC_TIMER_VARIABLE_NAME - if not is_add_timer_script: - self._add_timer_script_to_stage_object() - elif command == "answer": + if command == "answer": variable_name = converter._SHARED_GLOBAL_ANSWER_VARIABLE_NAME stage_object._dict_object["variables"].append({ "name": variable_name, "value": "", "isPersistent": False }) else: diff --git a/src/scratchtocatrobat/scratch/test_scratch.py b/src/scratchtocatrobat/scratch/test_scratch.py index c5a119ae..c3663c5e 100644 --- a/src/scratchtocatrobat/scratch/test_scratch.py +++ b/src/scratchtocatrobat/scratch/test_scratch.py @@ -455,287 +455,6 @@ def test_verify_complex_script_element_tree(self): assert right_child.name == 0.1 assert len(right_child.children) == 0 - -class TestTimerAndResetTimerBlockWorkarounds(unittest.TestCase): - TIMER_HELPER_OBJECTS_DATA_TEMPLATE = { - "objName": "Stage", - "sounds": [], - "costumes": [], - "currentCostumeIndex": 0, - "penLayerMD5": "5c81a336fab8be57adc039a8a2b33ca9.png", - "penLayerID": 0, - "tempoBPM": 60, - "videoAlpha": 0.5, - "children": [{ "objName": "Sprite1", "scripts": None }], - "info": {} - } - - def setUp(self): - unittest.TestCase.setUp(self) - cls = self.__class__ - cls.TIMER_HELPER_OBJECTS_DATA_TEMPLATE["scripts"] = [] - - def test_timer_block(self): - cls = self.__class__ - script_data = [0, 0, [["whenGreenFlag"], ["wait:elapsed:from:", ["timer"]]]] - cls.TIMER_HELPER_OBJECTS_DATA_TEMPLATE["children"][0]["scripts"] = [script_data] - raw_project = scratch.RawProject(cls.TIMER_HELPER_OBJECTS_DATA_TEMPLATE) - expected_background_object_script_data = [0, 0, [['whenGreenFlag'], - ['doForever', [ - ['changeVar:by:', scratch.S2CC_TIMER_VARIABLE_NAME, scratch.UPDATE_HELPER_VARIABLE_TIMEOUT], - ['wait:elapsed:from:', scratch.UPDATE_HELPER_VARIABLE_TIMEOUT] - ]] - ]] - expected_first_object_script_data = [0, 0, [["whenGreenFlag"], - ['wait:elapsed:from:', ['readVariable', scratch.S2CC_TIMER_VARIABLE_NAME]] - ]] - - # validate - assert len(raw_project.objects) == 2 - [background_object, first_object] = raw_project.objects - - # background object - assert len(background_object.scripts) == 1 - script = background_object.scripts[0] - expected_script = scratch.Script(expected_background_object_script_data) - assert script == expected_script - - # first object - assert len(first_object.scripts) == 1 - script = first_object.scripts[0] - expected_script = scratch.Script(expected_first_object_script_data) - assert script == expected_script - - # global variables - global_variables = background_object._dict_object["variables"] - assert len(global_variables) == 1 - assert global_variables[0] == { "name": scratch.S2CC_TIMER_VARIABLE_NAME, "value": 0, "isPersistent": False } - - def test_same_timer_block_twice(self): - cls = self.__class__ - script_data = [0, 0, [["whenGreenFlag"], ["wait:elapsed:from:", ["timer"]], ["wait:elapsed:from:", ["timer"]]]] - cls.TIMER_HELPER_OBJECTS_DATA_TEMPLATE["children"][0]["scripts"] = [script_data] - expected_background_object_script_data = [0, 0, [['whenGreenFlag'], - ['doForever', [ - ['changeVar:by:', scratch.S2CC_TIMER_VARIABLE_NAME, scratch.UPDATE_HELPER_VARIABLE_TIMEOUT], - ['wait:elapsed:from:', scratch.UPDATE_HELPER_VARIABLE_TIMEOUT] - ]] - ]] - expected_first_object_script_data = [0, 0, [["whenGreenFlag"], - ['wait:elapsed:from:', ['readVariable', scratch.S2CC_TIMER_VARIABLE_NAME]], - ['wait:elapsed:from:', ['readVariable', scratch.S2CC_TIMER_VARIABLE_NAME]] - ]] - - # create project - raw_project = scratch.RawProject(cls.TIMER_HELPER_OBJECTS_DATA_TEMPLATE) - - # validate - assert len(raw_project.objects) == 2 - [background_object, first_object] = raw_project.objects - - # background object - assert len(background_object.scripts) == 1 - script = background_object.scripts[0] - expected_script = scratch.Script(expected_background_object_script_data) - assert script == expected_script - - # first object - assert len(first_object.scripts) == 1 - script = first_object.scripts[0] - expected_script = scratch.Script(expected_first_object_script_data) - assert script == expected_script - - # global variables - global_variables = background_object._dict_object["variables"] - assert len(global_variables) == 1 - assert global_variables[0] == { "name": scratch.S2CC_TIMER_VARIABLE_NAME, "value": 0, "isPersistent": False } - - def test_reset_timer_block_with_non_existant_timer_block_should_automatically_add_timer_script(self): - cls = self.__class__ - expected_background_object_scripts_data = [[0, 0, [['whenGreenFlag'], - ['doForever', [ - ['changeVar:by:', scratch.S2CC_TIMER_VARIABLE_NAME, scratch.UPDATE_HELPER_VARIABLE_TIMEOUT], - ['wait:elapsed:from:', scratch.UPDATE_HELPER_VARIABLE_TIMEOUT] - ]]] - ], [0, 0, [['whenIReceive', scratch.S2CC_TIMER_RESET_BROADCAST_MESSAGE], - ['setVar:to:', scratch.S2CC_TIMER_VARIABLE_NAME, 0] - ]]] - script_data = [0, 0, [["whenGreenFlag"], ["timerReset"]]] - cls.TIMER_HELPER_OBJECTS_DATA_TEMPLATE["children"][0]["scripts"] = [script_data] - expected_first_object_script_data = [0, 0, [["whenGreenFlag"], - ['doBroadcastAndWait', scratch.S2CC_TIMER_RESET_BROADCAST_MESSAGE] - ]] - - # create project - raw_project = scratch.RawProject(cls.TIMER_HELPER_OBJECTS_DATA_TEMPLATE) - - # validate - assert len(raw_project.objects) == 2 - [background_object, first_object] = raw_project.objects - - # background object - assert len(background_object.scripts) == 2 - script = background_object.scripts[0] - expected_script = scratch.Script(expected_background_object_scripts_data[0]) - assert script == expected_script - script = background_object.scripts[1] - expected_script = scratch.Script(expected_background_object_scripts_data[1]) - assert script == expected_script - - # first object - assert len(first_object.scripts) == 1 - script = first_object.scripts[0] - expected_script = scratch.Script(expected_first_object_script_data) - assert script == expected_script - - # global variables - global_variables = background_object._dict_object["variables"] - assert len(global_variables) == 1 - assert global_variables[0] == { "name": scratch.S2CC_TIMER_VARIABLE_NAME, "value": 0, "isPersistent": False } - - def test_reset_timer_block_with_existant_timer_block_in_same_object_must_NOT_be_ignored(self): - cls = self.__class__ - expected_background_object_scripts_data = [[0, 0, [['whenGreenFlag'], - ['doForever', [ - ['changeVar:by:', scratch.S2CC_TIMER_VARIABLE_NAME, scratch.UPDATE_HELPER_VARIABLE_TIMEOUT], - ['wait:elapsed:from:', scratch.UPDATE_HELPER_VARIABLE_TIMEOUT] - ]]] - ], [0, 0, [['whenIReceive', scratch.S2CC_TIMER_RESET_BROADCAST_MESSAGE], - ['setVar:to:', scratch.S2CC_TIMER_VARIABLE_NAME, 0] - ]]] - script_data = [0, 0, [["whenGreenFlag"], ["wait:elapsed:from:", ["timer"]], ["timerReset"]]] - cls.TIMER_HELPER_OBJECTS_DATA_TEMPLATE["children"][0]["scripts"] = [script_data] - expected_first_object_script_data = [0, 0, [["whenGreenFlag"], - ['wait:elapsed:from:', ['readVariable', scratch.S2CC_TIMER_VARIABLE_NAME]], - ["doBroadcastAndWait", scratch.S2CC_TIMER_RESET_BROADCAST_MESSAGE] - ]] - - # create project - raw_project = scratch.RawProject(cls.TIMER_HELPER_OBJECTS_DATA_TEMPLATE) - - # validate - assert len(raw_project.objects) == 2 - [background_object, first_object] = raw_project.objects - - # background object - assert len(background_object.scripts) == 2 - script = background_object.scripts[0] - expected_script = scratch.Script(expected_background_object_scripts_data[0]) - assert script == expected_script - script = background_object.scripts[1] - expected_script = scratch.Script(expected_background_object_scripts_data[1]) - assert script == expected_script - - # first object - assert len(first_object.scripts) == 1 - script = first_object.scripts[0] - expected_script = scratch.Script(expected_first_object_script_data) - assert script == expected_script - - # global variables - global_variables = background_object._dict_object["variables"] - assert len(global_variables) == 1 - assert global_variables[0] == { "name": scratch.S2CC_TIMER_VARIABLE_NAME, "value": 0, "isPersistent": False } - - def test_reset_timer_block_and_timer_block_within_loop_must_NOT_be_ignored(self): - cls = self.__class__ - expected_background_object_scripts_data = [[0, 0, [['whenGreenFlag'], - ['doForever', [ - ['changeVar:by:', scratch.S2CC_TIMER_VARIABLE_NAME, scratch.UPDATE_HELPER_VARIABLE_TIMEOUT], - ['wait:elapsed:from:', scratch.UPDATE_HELPER_VARIABLE_TIMEOUT] - ]]] - ], [0, 0, [['whenIReceive', scratch.S2CC_TIMER_RESET_BROADCAST_MESSAGE], - ['setVar:to:', scratch.S2CC_TIMER_VARIABLE_NAME, 0] - ]]] - script_data = [0, 0, [["whenGreenFlag"], - ["doRepeat", 100, [["wait:elapsed:from:", ["timer"]], ["timerReset"]]]] - ] - cls.TIMER_HELPER_OBJECTS_DATA_TEMPLATE["children"][0]["scripts"] = [script_data] - expected_first_object_script_data = [0, 0, [["whenGreenFlag"], - ["doRepeat", 100, [ - ['wait:elapsed:from:', ['readVariable', scratch.S2CC_TIMER_VARIABLE_NAME]], - ["doBroadcastAndWait", scratch.S2CC_TIMER_RESET_BROADCAST_MESSAGE]] - ]]] - - # create project - raw_project = scratch.RawProject(cls.TIMER_HELPER_OBJECTS_DATA_TEMPLATE) - - # validate - assert len(raw_project.objects) == 2 - [background_object, first_object] = raw_project.objects - - # background object - assert len(background_object.scripts) == 2 - script = background_object.scripts[0] - expected_script = scratch.Script(expected_background_object_scripts_data[0]) - assert script == expected_script - script = background_object.scripts[1] - expected_script = scratch.Script(expected_background_object_scripts_data[1]) - assert script == expected_script - - # first object - assert len(first_object.scripts) == 1 - script = first_object.scripts[0] - expected_script = scratch.Script(expected_first_object_script_data) - assert script == expected_script - - # global variables - global_variables = background_object._dict_object["variables"] - assert len(global_variables) == 1 - assert global_variables[0] == { "name": scratch.S2CC_TIMER_VARIABLE_NAME, "value": 0, "isPersistent": False } - - def test_reset_timer_block_with_existant_timer_block_in_other_object_must_NOT_be_ignored(self): - cls = self.__class__ - background_script_data = [0, 0, [["whenGreenFlag"], ["timerReset"]]] - cls.TIMER_HELPER_OBJECTS_DATA_TEMPLATE["scripts"] = [background_script_data] - expected_background_object_scripts_data = [[0, 0, [['whenGreenFlag'], - ["doBroadcastAndWait", scratch.S2CC_TIMER_RESET_BROADCAST_MESSAGE] - ]], [0, 0, [['whenGreenFlag'], - ['doForever', [ - ['changeVar:by:', scratch.S2CC_TIMER_VARIABLE_NAME, scratch.UPDATE_HELPER_VARIABLE_TIMEOUT], - ['wait:elapsed:from:', scratch.UPDATE_HELPER_VARIABLE_TIMEOUT] - ]]] - ], [0, 0, [['whenIReceive', scratch.S2CC_TIMER_RESET_BROADCAST_MESSAGE], - ['setVar:to:', scratch.S2CC_TIMER_VARIABLE_NAME, 0] - ]]] - - # first object scripts - first_object_script_data = [0, 0, [["whenGreenFlag"], ["wait:elapsed:from:", ["timer"]]]] - cls.TIMER_HELPER_OBJECTS_DATA_TEMPLATE["children"][0]["scripts"] = [first_object_script_data] - expected_first_object_script_data = [0, 0, [["whenGreenFlag"], - ['wait:elapsed:from:', ['readVariable', scratch.S2CC_TIMER_VARIABLE_NAME]] - ]] - - # create project - raw_project = scratch.RawProject(cls.TIMER_HELPER_OBJECTS_DATA_TEMPLATE) - - # validate - assert len(raw_project.objects) == 2 - [background_object, first_object] = raw_project.objects - - # background object - assert len(background_object.scripts) == 3 - script = background_object.scripts[0] - expected_script = scratch.Script(expected_background_object_scripts_data[0]) - assert script == expected_script - script = background_object.scripts[1] - expected_script = scratch.Script(expected_background_object_scripts_data[1]) - assert script == expected_script - script = background_object.scripts[2] - expected_script = scratch.Script(expected_background_object_scripts_data[2]) - assert script == expected_script - - # first object - assert len(first_object.scripts) == 1 - script = first_object.scripts[0] - expected_script = scratch.Script(expected_first_object_script_data) - assert script == expected_script - - # global variables - global_variables = background_object._dict_object["variables"] - assert len(global_variables) == 1 - assert global_variables[0] == { "name": scratch.S2CC_TIMER_VARIABLE_NAME, "value": 0, "isPersistent": False } - class TestBackdropWorkaround(unittest.TestCase): BACKDROP_HELPER_OBJECTS_DATA_TEMPLATE = { "objName": "Stage",