From 93d080dfdb199f920a4d302c3d9d8ab07968b349 Mon Sep 17 00:00:00 2001 From: Beka Westberg Date: Tue, 20 Jul 2021 14:45:36 +0000 Subject: [PATCH 1/5] Add variable serialization tests --- tests/mocha/jso_serialization_test.js | 34 +++++++++++++++++++++------ 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/tests/mocha/jso_serialization_test.js b/tests/mocha/jso_serialization_test.js index 6aed827bb65..72bfa4cefe0 100644 --- a/tests/mocha/jso_serialization_test.js +++ b/tests/mocha/jso_serialization_test.js @@ -21,15 +21,16 @@ suite('JSO', function() { sharedTestTeardown.call(this); }); - suite('Blocks', function() { - function assertProperty(obj, property, value) { - chai.assert.deepEqual(obj[property], value); - } + function assertProperty(obj, property, value) { + chai.assert.deepEqual(obj[property], value); + } + + function assertNoProperty(obj, property) { + assertProperty(obj, property, undefined); + } - function assertNoProperty(obj, property) { - assertProperty(obj, property, undefined); - } + suite('Blocks', function() { test('Null on insertionMarkers', function() { const block = this.workspace.newBlock('row_block'); block.setInsertionMarker(true); @@ -629,4 +630,23 @@ suite('JSO', function() { }); }); }); + + suite.only('Variables', function() { + test('Without type', function() { + const variable = this.workspace.createVariable('testVar', '', 'testId'); + const jso = Blockly.serialization.variables.save(variable); + assertProperty(jso, 'name', 'testVar'); + assertProperty(jso, 'id', 'testId'); + assertNoProperty(jso, 'type'); + }); + + test('With type', function() { + const variable = this.workspace + .createVariable('testVar', 'testType', 'testId'); + const jso = Blockly.serialization.variables.save(variable); + assertProperty(jso, 'name', 'testVar'); + assertProperty(jso, 'id', 'testId'); + assertProperty(jso, 'type', 'testType'); + }); + }); }); From 1db5a2e1e0d6748454cdba3e739c5ce2847a8d9d Mon Sep 17 00:00:00 2001 From: Beka Westberg Date: Tue, 20 Jul 2021 14:46:01 +0000 Subject: [PATCH 2/5] Fix requires for new file --- core/requires.js | 1 + tests/deps.js | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/core/requires.js b/core/requires.js index 087ad8ac066..1ce08dddcac 100644 --- a/core/requires.js +++ b/core/requires.js @@ -84,3 +84,4 @@ goog.require('Blockly.zelos.Renderer'); goog.require('Blockly.Themes.Classic'); goog.require('Blockly.serialization.blocks'); +goog.require('Blockly.serialization.variables'); diff --git a/tests/deps.js b/tests/deps.js index 83b8365e1ed..9dfa475c3df 100644 --- a/tests/deps.js +++ b/tests/deps.js @@ -151,10 +151,11 @@ goog.addDependency('../../core/renderers/zelos/measurables/row_elements.js', ['B goog.addDependency('../../core/renderers/zelos/measurables/rows.js', ['Blockly.zelos.BottomRow', 'Blockly.zelos.TopRow'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.TopRow', 'Blockly.utils.object']); goog.addDependency('../../core/renderers/zelos/path_object.js', ['Blockly.zelos.PathObject'], ['Blockly.blockRendering.PathObject', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.zelos.ConstantProvider']); goog.addDependency('../../core/renderers/zelos/renderer.js', ['Blockly.zelos.Renderer'], ['Blockly.InsertionMarkerManager', 'Blockly.blockRendering', 'Blockly.blockRendering.Renderer', 'Blockly.connectionTypes', 'Blockly.constants', 'Blockly.utils.object', 'Blockly.zelos.ConstantProvider', 'Blockly.zelos.Drawer', 'Blockly.zelos.MarkerSvg', 'Blockly.zelos.PathObject', 'Blockly.zelos.RenderInfo']); -goog.addDependency('../../core/requires.js', ['Blockly.requires'], ['Blockly', 'Blockly.Comment', 'Blockly.ContextMenuItems', 'Blockly.FieldAngle', 'Blockly.FieldCheckbox', 'Blockly.FieldColour', 'Blockly.FieldDropdown', 'Blockly.FieldImage', 'Blockly.FieldLabelSerializable', 'Blockly.FieldMultilineInput', 'Blockly.FieldNumber', 'Blockly.FieldTextInput', 'Blockly.FieldVariable', 'Blockly.FlyoutButton', 'Blockly.Generator', 'Blockly.HorizontalFlyout', 'Blockly.Mutator', 'Blockly.ShortcutItems', 'Blockly.Themes.Classic', 'Blockly.Toolbox', 'Blockly.Trashcan', 'Blockly.VariablesDynamic', 'Blockly.VerticalFlyout', 'Blockly.Warning', 'Blockly.ZoomControls', 'Blockly.geras.Renderer', 'Blockly.serialization.blocks', 'Blockly.thrasos.Renderer', 'Blockly.zelos.Renderer']); +goog.addDependency('../../core/requires.js', ['Blockly.requires'], ['Blockly', 'Blockly.Comment', 'Blockly.ContextMenuItems', 'Blockly.FieldAngle', 'Blockly.FieldCheckbox', 'Blockly.FieldColour', 'Blockly.FieldDropdown', 'Blockly.FieldImage', 'Blockly.FieldLabelSerializable', 'Blockly.FieldMultilineInput', 'Blockly.FieldNumber', 'Blockly.FieldTextInput', 'Blockly.FieldVariable', 'Blockly.FlyoutButton', 'Blockly.Generator', 'Blockly.HorizontalFlyout', 'Blockly.Mutator', 'Blockly.ShortcutItems', 'Blockly.Themes.Classic', 'Blockly.Toolbox', 'Blockly.Trashcan', 'Blockly.VariablesDynamic', 'Blockly.VerticalFlyout', 'Blockly.Warning', 'Blockly.ZoomControls', 'Blockly.geras.Renderer', 'Blockly.serialization.blocks', 'Blockly.serialization.variables', 'Blockly.thrasos.Renderer', 'Blockly.zelos.Renderer']); goog.addDependency('../../core/scrollbar.js', ['Blockly.Scrollbar', 'Blockly.ScrollbarPair'], ['Blockly.Events', 'Blockly.Touch', 'Blockly.browserEvents', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Metrics', 'Blockly.utils.Svg', 'Blockly.utils.dom']); goog.addDependency('../../core/serialization/blocks.js', ['Blockly.serialization.blocks'], ['Blockly.Xml', 'Blockly.inputTypes'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/serialization/serialization.js', ['Blockly.serialization'], [], {'module': 'goog'}); +goog.addDependency('../../core/serialization/variables.js', ['Blockly.serialization.variables'], [], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/shortcut_items.js', ['Blockly.ShortcutItems'], ['Blockly.Gesture', 'Blockly.ShortcutRegistry', 'Blockly.utils.KeyCodes']); goog.addDependency('../../core/shortcut_registry.js', ['Blockly.ShortcutRegistry'], ['Blockly.utils.KeyCodes', 'Blockly.utils.object']); goog.addDependency('../../core/theme.js', ['Blockly.Theme'], ['Blockly.registry', 'Blockly.utils', 'Blockly.utils.object']); From 5e3fe58d3c24ecb6a51e5f5ef7d354a1e3c379a3 Mon Sep 17 00:00:00 2001 From: Beka Westberg Date: Tue, 20 Jul 2021 14:46:30 +0000 Subject: [PATCH 3/5] Add serialization and deserialization of variables --- core/serialization/variables.js | 56 +++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 core/serialization/variables.js diff --git a/core/serialization/variables.js b/core/serialization/variables.js new file mode 100644 index 00000000000..3697b2fb2c5 --- /dev/null +++ b/core/serialization/variables.js @@ -0,0 +1,56 @@ +/** + * @license + * Copyright 2021 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @fileoverview Handles serializing variables to plain JavaScript objects, only + * containing state. + */ +'use strict'; + +goog.module('Blockly.serialization.variables'); +goog.module.declareLegacyNamespace(); + +// TODO: Is there any way to not export these? I would rather keep this out of +// the public API if possible. + +/** + * Represents the state of a given variable. + * @typedef {{ + * name: string, + * id: string, + * type: ?string, + * }} + */ +// eslint-disable-next-line no-unused-vars +var State; + +/** + * Returns the state of the variable as a plain JavaScript object. + * @param {!Blockly.variableModel} variableModel The variable to serialize. + * @return {!Blockly.serialization.variables.State} The serialized state of the + * variable. + */ +const save = function(variableModel) { + const state = Object.create(null); + state['name'] = variableModel.name; + state['id'] = variableModel.getId(); + if (variableModel.type) { + state['type'] = variableModel.type; + } + return state; +}; + +/** + * Loads the variable represented by the given state into the given workspace. + * @param {!Blockly.serializatio.variables.State} state The state of a variable + * to deserialize into he workspace. + * @param {!Blockly.Workspace} workspace The workspace to add the variable to. + */ +const load = function(state, workspace) { + workspace.createVariable(state['name'], state['type'], state['id']); +}; + +exports = {save, load}; From 2e5b479a0c1071baad1525bcb7329a1477166a66 Mon Sep 17 00:00:00 2001 From: Beka Westberg Date: Tue, 20 Jul 2021 14:53:54 +0000 Subject: [PATCH 4/5] Remove only in tests --- tests/mocha/jso_serialization_test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/mocha/jso_serialization_test.js b/tests/mocha/jso_serialization_test.js index 72bfa4cefe0..2e40010ae22 100644 --- a/tests/mocha/jso_serialization_test.js +++ b/tests/mocha/jso_serialization_test.js @@ -631,7 +631,7 @@ suite('JSO', function() { }); }); - suite.only('Variables', function() { + suite('Variables', function() { test('Without type', function() { const variable = this.workspace.createVariable('testVar', '', 'testId'); const jso = Blockly.serialization.variables.save(variable); From 36964e16c54c2b0f116f77ab100733f9ab3ddb01 Mon Sep 17 00:00:00 2001 From: Beka Westberg Date: Fri, 6 Aug 2021 15:06:50 +0000 Subject: [PATCH 5/5] Cleanup --- core/serialization/variables.js | 36 +++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/core/serialization/variables.js b/core/serialization/variables.js index 3697b2fb2c5..8bcb7b40861 100644 --- a/core/serialization/variables.js +++ b/core/serialization/variables.js @@ -13,44 +13,50 @@ goog.module('Blockly.serialization.variables'); goog.module.declareLegacyNamespace(); -// TODO: Is there any way to not export these? I would rather keep this out of -// the public API if possible. +// eslint-disable-next-line no-unused-vars +const VariableModel = goog.requireType('Blockly.VariableModel'); +// eslint-disable-next-line no-unused-vars +const Workspace = goog.requireType('Blockly.Workspace'); + /** * Represents the state of a given variable. * @typedef {{ * name: string, * id: string, - * type: ?string, + * type: (string|undefined), * }} */ -// eslint-disable-next-line no-unused-vars var State; +exports.State = State; /** * Returns the state of the variable as a plain JavaScript object. - * @param {!Blockly.variableModel} variableModel The variable to serialize. - * @return {!Blockly.serialization.variables.State} The serialized state of the - * variable. + * @param {!VariableModel} variableModel The variable to serialize. + * @return {!State} The serialized state of the variable. */ const save = function(variableModel) { - const state = Object.create(null); - state['name'] = variableModel.name; - state['id'] = variableModel.getId(); + const state = { + 'name': variableModel.name, + 'id': variableModel.getId() + }; if (variableModel.type) { state['type'] = variableModel.type; } return state; }; +/** @package */ +exports.save = save; /** * Loads the variable represented by the given state into the given workspace. - * @param {!Blockly.serializatio.variables.State} state The state of a variable - * to deserialize into he workspace. - * @param {!Blockly.Workspace} workspace The workspace to add the variable to. + * Do not call this directly, use workspace.createVariable instead. + * @param {!State} state The state of a variable to deserialize into the + * workspace. + * @param {!Workspace} workspace The workspace to add the variable to. */ const load = function(state, workspace) { workspace.createVariable(state['name'], state['type'], state['id']); }; - -exports = {save, load}; +/** @package */ +exports.load = load;